1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // On Solaris, we need to define something to make the C99 parts of localeconv
15 #include <__utility/unreachable.h>
24 #include <type_traits>
28 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
33 # include <sys/localedef.h> // for __lc_ctype_ptr
36 #if defined(_LIBCPP_MSVCRT)
37 # define _CTYPE_DISABLE_MACROS
40 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
41 # include "__support/win32/locale_win32.h"
42 #elif !defined(__BIONIC__) && !defined(__NuttX__)
43 # include <langinfo.h>
46 #include "include/atomic_support.h"
47 #include "include/sso_allocator.h"
49 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
50 // lots of noise in the build log, but no bugs that I know of.
51 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion")
54 #include <__undef_macros>
56 _LIBCPP_BEGIN_NAMESPACE_STD
58 struct __libcpp_unique_locale {
59 __libcpp_unique_locale(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {}
61 ~__libcpp_unique_locale() {
66 explicit operator bool() const { return __loc_; }
68 locale_t& get() { return __loc_; }
72 __libcpp_unique_locale(__libcpp_unique_locale const&);
73 __libcpp_unique_locale& operator=(__libcpp_unique_locale const&);
78 // In theory this could create a race condition. In practice
79 // the race condition is non-fatal since it will just create
80 // a little resource leak. Better approach would be appreciated.
81 static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
84 #endif // __cloc_defined
90 void operator()(locale::facet* p) {p->__release_shared();}
93 template <class T, class ...Args>
96 static typename aligned_storage<sizeof(T)>::type buf;
97 auto *obj = ::new (&buf) T(args...);
101 template <typename T, size_t N>
105 countof(const T (&)[N])
110 template <typename T>
114 countof(const T * const begin, const T * const end)
116 return static_cast<size_t>(end - begin);
119 _LIBCPP_NORETURN static void __throw_runtime_error(const string &msg)
121 #ifndef _LIBCPP_NO_EXCEPTIONS
122 throw runtime_error(msg);
131 const locale::category locale::none;
132 const locale::category locale::collate;
133 const locale::category locale::ctype;
134 const locale::category locale::monetary;
135 const locale::category locale::numeric;
136 const locale::category locale::time;
137 const locale::category locale::messages;
138 const locale::category locale::all;
140 class _LIBCPP_HIDDEN locale::__imp
144 #if defined(_LIBCPP_COMPILER_MSVC)
145 // FIXME: MSVC doesn't support aligned parameters by value.
146 // I can't get the __sso_allocator to work here
147 // for MSVC I think for this reason.
148 vector<facet*> facets_;
150 vector<facet*, __sso_allocator<facet*, N> > facets_;
154 explicit __imp(size_t refs = 0);
155 explicit __imp(const string& name, size_t refs = 0);
157 __imp(const __imp&, const string&, locale::category c);
158 __imp(const __imp& other, const __imp& one, locale::category c);
159 __imp(const __imp&, facet* f, long id);
162 const string& name() const {return name_;}
163 bool has_facet(long id) const
164 {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
165 const locale::facet* use_facet(long id) const;
167 static const locale& make_classic();
168 static locale& make_global();
170 void install(facet* f, long id);
171 template <class F> void install(F* f) {install(f, f->id.__get());}
172 template <class F> void install_from(const __imp& other);
175 locale::__imp::__imp(size_t refs)
181 install(&make<_VSTD::collate<char> >(1u));
182 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
183 install(&make<_VSTD::collate<wchar_t> >(1u));
185 install(&make<_VSTD::ctype<char> >(nullptr, false, 1u));
186 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
187 install(&make<_VSTD::ctype<wchar_t> >(1u));
189 install(&make<codecvt<char, char, mbstate_t> >(1u));
190 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
191 install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
193 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
194 install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
195 install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
196 _LIBCPP_SUPPRESS_DEPRECATED_POP
197 #ifndef _LIBCPP_HAS_NO_CHAR8_T
198 install(&make<codecvt<char16_t, char8_t, mbstate_t> >(1u));
199 install(&make<codecvt<char32_t, char8_t, mbstate_t> >(1u));
201 install(&make<numpunct<char> >(1u));
202 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
203 install(&make<numpunct<wchar_t> >(1u));
205 install(&make<num_get<char> >(1u));
206 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
207 install(&make<num_get<wchar_t> >(1u));
209 install(&make<num_put<char> >(1u));
210 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
211 install(&make<num_put<wchar_t> >(1u));
213 install(&make<moneypunct<char, false> >(1u));
214 install(&make<moneypunct<char, true> >(1u));
215 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
216 install(&make<moneypunct<wchar_t, false> >(1u));
217 install(&make<moneypunct<wchar_t, true> >(1u));
219 install(&make<money_get<char> >(1u));
220 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
221 install(&make<money_get<wchar_t> >(1u));
223 install(&make<money_put<char> >(1u));
224 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
225 install(&make<money_put<wchar_t> >(1u));
227 install(&make<time_get<char> >(1u));
228 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
229 install(&make<time_get<wchar_t> >(1u));
231 install(&make<time_put<char> >(1u));
232 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
233 install(&make<time_put<wchar_t> >(1u));
235 install(&make<_VSTD::messages<char> >(1u));
236 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
237 install(&make<_VSTD::messages<wchar_t> >(1u));
241 locale::__imp::__imp(const string& name, size_t refs)
246 #ifndef _LIBCPP_NO_EXCEPTIONS
249 #endif // _LIBCPP_NO_EXCEPTIONS
250 facets_ = locale::classic().__locale_->facets_;
251 for (unsigned i = 0; i < facets_.size(); ++i)
253 facets_[i]->__add_shared();
254 install(new collate_byname<char>(name_));
255 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
256 install(new collate_byname<wchar_t>(name_));
258 install(new ctype_byname<char>(name_));
259 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
260 install(new ctype_byname<wchar_t>(name_));
262 install(new codecvt_byname<char, char, mbstate_t>(name_));
263 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
264 install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
266 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
267 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
268 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
269 _LIBCPP_SUPPRESS_DEPRECATED_POP
270 #ifndef _LIBCPP_HAS_NO_CHAR8_T
271 install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name_));
272 install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name_));
274 install(new numpunct_byname<char>(name_));
275 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
276 install(new numpunct_byname<wchar_t>(name_));
278 install(new moneypunct_byname<char, false>(name_));
279 install(new moneypunct_byname<char, true>(name_));
280 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
281 install(new moneypunct_byname<wchar_t, false>(name_));
282 install(new moneypunct_byname<wchar_t, true>(name_));
284 install(new time_get_byname<char>(name_));
285 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
286 install(new time_get_byname<wchar_t>(name_));
288 install(new time_put_byname<char>(name_));
289 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
290 install(new time_put_byname<wchar_t>(name_));
292 install(new messages_byname<char>(name_));
293 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
294 install(new messages_byname<wchar_t>(name_));
296 #ifndef _LIBCPP_NO_EXCEPTIONS
300 for (unsigned i = 0; i < facets_.size(); ++i)
302 facets_[i]->__release_shared();
305 #endif // _LIBCPP_NO_EXCEPTIONS
308 locale::__imp::__imp(const __imp& other)
309 : facets_(max<size_t>(N, other.facets_.size())),
312 facets_ = other.facets_;
313 for (unsigned i = 0; i < facets_.size(); ++i)
315 facets_[i]->__add_shared();
318 locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
322 facets_ = other.facets_;
323 for (unsigned i = 0; i < facets_.size(); ++i)
325 facets_[i]->__add_shared();
326 #ifndef _LIBCPP_NO_EXCEPTIONS
329 #endif // _LIBCPP_NO_EXCEPTIONS
330 if (c & locale::collate)
332 install(new collate_byname<char>(name));
333 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
334 install(new collate_byname<wchar_t>(name));
337 if (c & locale::ctype)
339 install(new ctype_byname<char>(name));
340 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
341 install(new ctype_byname<wchar_t>(name));
343 install(new codecvt_byname<char, char, mbstate_t>(name));
344 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
345 install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
347 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
348 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
349 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
350 _LIBCPP_SUPPRESS_DEPRECATED_POP
351 #ifndef _LIBCPP_HAS_NO_CHAR8_T
352 install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name));
353 install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name));
356 if (c & locale::monetary)
358 install(new moneypunct_byname<char, false>(name));
359 install(new moneypunct_byname<char, true>(name));
360 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
361 install(new moneypunct_byname<wchar_t, false>(name));
362 install(new moneypunct_byname<wchar_t, true>(name));
365 if (c & locale::numeric)
367 install(new numpunct_byname<char>(name));
368 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
369 install(new numpunct_byname<wchar_t>(name));
372 if (c & locale::time)
374 install(new time_get_byname<char>(name));
375 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
376 install(new time_get_byname<wchar_t>(name));
378 install(new time_put_byname<char>(name));
379 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
380 install(new time_put_byname<wchar_t>(name));
383 if (c & locale::messages)
385 install(new messages_byname<char>(name));
386 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
387 install(new messages_byname<wchar_t>(name));
390 #ifndef _LIBCPP_NO_EXCEPTIONS
394 for (unsigned i = 0; i < facets_.size(); ++i)
396 facets_[i]->__release_shared();
399 #endif // _LIBCPP_NO_EXCEPTIONS
405 locale::__imp::install_from(const locale::__imp& one)
407 long id = F::id.__get();
408 install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
411 locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
415 facets_ = other.facets_;
416 for (unsigned i = 0; i < facets_.size(); ++i)
418 facets_[i]->__add_shared();
419 #ifndef _LIBCPP_NO_EXCEPTIONS
422 #endif // _LIBCPP_NO_EXCEPTIONS
423 if (c & locale::collate)
425 install_from<_VSTD::collate<char> >(one);
426 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
427 install_from<_VSTD::collate<wchar_t> >(one);
430 if (c & locale::ctype)
432 install_from<_VSTD::ctype<char> >(one);
433 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
434 install_from<_VSTD::ctype<wchar_t> >(one);
436 install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
437 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
438 install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
439 install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
440 _LIBCPP_SUPPRESS_DEPRECATED_POP
441 #ifndef _LIBCPP_HAS_NO_CHAR8_T
442 install_from<_VSTD::codecvt<char16_t, char8_t, mbstate_t> >(one);
443 install_from<_VSTD::codecvt<char32_t, char8_t, mbstate_t> >(one);
445 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
446 install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
449 if (c & locale::monetary)
451 install_from<moneypunct<char, false> >(one);
452 install_from<moneypunct<char, true> >(one);
453 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
454 install_from<moneypunct<wchar_t, false> >(one);
455 install_from<moneypunct<wchar_t, true> >(one);
457 install_from<money_get<char> >(one);
458 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
459 install_from<money_get<wchar_t> >(one);
461 install_from<money_put<char> >(one);
462 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
463 install_from<money_put<wchar_t> >(one);
466 if (c & locale::numeric)
468 install_from<numpunct<char> >(one);
469 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
470 install_from<numpunct<wchar_t> >(one);
472 install_from<num_get<char> >(one);
473 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
474 install_from<num_get<wchar_t> >(one);
476 install_from<num_put<char> >(one);
477 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
478 install_from<num_put<wchar_t> >(one);
481 if (c & locale::time)
483 install_from<time_get<char> >(one);
484 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
485 install_from<time_get<wchar_t> >(one);
487 install_from<time_put<char> >(one);
488 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
489 install_from<time_put<wchar_t> >(one);
492 if (c & locale::messages)
494 install_from<_VSTD::messages<char> >(one);
495 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
496 install_from<_VSTD::messages<wchar_t> >(one);
499 #ifndef _LIBCPP_NO_EXCEPTIONS
503 for (unsigned i = 0; i < facets_.size(); ++i)
505 facets_[i]->__release_shared();
508 #endif // _LIBCPP_NO_EXCEPTIONS
511 locale::__imp::__imp(const __imp& other, facet* f, long id)
512 : facets_(max<size_t>(N, other.facets_.size()+1)),
516 unique_ptr<facet, release> hold(f);
517 facets_ = other.facets_;
518 for (unsigned i = 0; i < other.facets_.size(); ++i)
520 facets_[i]->__add_shared();
521 install(hold.get(), id);
524 locale::__imp::~__imp()
526 for (unsigned i = 0; i < facets_.size(); ++i)
528 facets_[i]->__release_shared();
532 locale::__imp::install(facet* f, long id)
535 unique_ptr<facet, release> hold(f);
536 if (static_cast<size_t>(id) >= facets_.size())
537 facets_.resize(static_cast<size_t>(id+1));
538 if (facets_[static_cast<size_t>(id)])
539 facets_[static_cast<size_t>(id)]->__release_shared();
540 facets_[static_cast<size_t>(id)] = hold.release();
544 locale::__imp::use_facet(long id) const
548 return facets_[static_cast<size_t>(id)];
554 locale::__imp::make_classic()
556 // only one thread can get in here and it only gets in once
557 static aligned_storage<sizeof(locale)>::type buf;
558 locale* c = reinterpret_cast<locale*>(&buf);
559 c->__locale_ = &make<__imp>(1u);
566 static const locale& c = __imp::make_classic();
571 locale::__imp::make_global()
573 // only one thread can get in here and it only gets in once
574 static aligned_storage<sizeof(locale)>::type buf;
575 auto *obj = ::new (&buf) locale(locale::classic());
582 static locale& g = __imp::make_global();
586 locale::locale() noexcept
587 : __locale_(__global().__locale_)
589 __locale_->__add_shared();
592 locale::locale(const locale& l) noexcept
593 : __locale_(l.__locale_)
595 __locale_->__add_shared();
600 __locale_->__release_shared();
604 locale::operator=(const locale& other) noexcept
606 other.__locale_->__add_shared();
607 __locale_->__release_shared();
608 __locale_ = other.__locale_;
612 locale::locale(const char* name)
613 : __locale_(name ? new __imp(name)
614 : (__throw_runtime_error("locale constructed with null"), nullptr))
616 __locale_->__add_shared();
619 locale::locale(const string& name)
620 : __locale_(new __imp(name))
622 __locale_->__add_shared();
625 locale::locale(const locale& other, const char* name, category c)
626 : __locale_(name ? new __imp(*other.__locale_, name, c)
627 : (__throw_runtime_error("locale constructed with null"), nullptr))
629 __locale_->__add_shared();
632 locale::locale(const locale& other, const string& name, category c)
633 : __locale_(new __imp(*other.__locale_, name, c))
635 __locale_->__add_shared();
638 locale::locale(const locale& other, const locale& one, category c)
639 : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
641 __locale_->__add_shared();
647 return __locale_->name();
651 locale::__install_ctor(const locale& other, facet* f, long id)
654 __locale_ = new __imp(*other.__locale_, f, id);
656 __locale_ = other.__locale_;
657 __locale_->__add_shared();
661 locale::global(const locale& loc)
663 locale& g = __global();
667 setlocale(LC_ALL, g.name().c_str());
672 locale::has_facet(id& x) const
674 return __locale_->has_facet(x.__get());
678 locale::use_facet(id& x) const
680 return __locale_->use_facet(x.__get());
684 locale::operator==(const locale& y) const
686 return (__locale_ == y.__locale_)
687 || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
692 locale::facet::~facet()
697 locale::facet::__on_zero_shared() noexcept
704 int32_t locale::id::__next_id = 0;
712 void (locale::id::* pmf_)();
714 __fake_bind(void (locale::id::* pmf)(), locale::id* id)
715 : id_(id), pmf_(pmf) {}
717 void operator()() const
728 call_once(__flag_, __fake_bind(&locale::id::__init, this));
735 __id_ = __libcpp_atomic_add(&__next_id, 1);
738 // template <> class collate_byname<char>
740 collate_byname<char>::collate_byname(const char* n, size_t refs)
741 : collate<char>(refs),
742 __l(newlocale(LC_ALL_MASK, n, 0))
745 __throw_runtime_error("collate_byname<char>::collate_byname"
746 " failed to construct for " + string(n));
749 collate_byname<char>::collate_byname(const string& name, size_t refs)
750 : collate<char>(refs),
751 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
754 __throw_runtime_error("collate_byname<char>::collate_byname"
755 " failed to construct for " + name);
758 collate_byname<char>::~collate_byname()
764 collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
765 const char_type* __lo2, const char_type* __hi2) const
767 string_type lhs(__lo1, __hi1);
768 string_type rhs(__lo2, __hi2);
769 int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l);
777 collate_byname<char>::string_type
778 collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
780 const string_type in(lo, hi);
781 string_type out(strxfrm_l(0, in.c_str(), 0, __l), char());
782 strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l);
786 // template <> class collate_byname<wchar_t>
788 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
789 collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
790 : collate<wchar_t>(refs),
791 __l(newlocale(LC_ALL_MASK, n, 0))
794 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
795 " failed to construct for " + string(n));
798 collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
799 : collate<wchar_t>(refs),
800 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
803 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
804 " failed to construct for " + name);
807 collate_byname<wchar_t>::~collate_byname()
813 collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
814 const char_type* __lo2, const char_type* __hi2) const
816 string_type lhs(__lo1, __hi1);
817 string_type rhs(__lo2, __hi2);
818 int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l);
826 collate_byname<wchar_t>::string_type
827 collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
829 const string_type in(lo, hi);
830 string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t());
831 wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l);
834 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
836 const ctype_base::mask ctype_base::space;
837 const ctype_base::mask ctype_base::print;
838 const ctype_base::mask ctype_base::cntrl;
839 const ctype_base::mask ctype_base::upper;
840 const ctype_base::mask ctype_base::lower;
841 const ctype_base::mask ctype_base::alpha;
842 const ctype_base::mask ctype_base::digit;
843 const ctype_base::mask ctype_base::punct;
844 const ctype_base::mask ctype_base::xdigit;
845 const ctype_base::mask ctype_base::blank;
846 const ctype_base::mask ctype_base::alnum;
847 const ctype_base::mask ctype_base::graph;
849 // template <> class ctype<wchar_t>;
851 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
852 locale::id ctype<wchar_t>::id;
854 ctype<wchar_t>::~ctype()
859 ctype<wchar_t>::do_is(mask m, char_type c) const
861 return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
865 ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
867 for (; low != high; ++low, ++vec)
868 *vec = static_cast<mask>(isascii(*low) ?
869 ctype<char>::classic_table()[*low] : 0);
874 ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
876 for (; low != high; ++low)
877 if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
883 ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
885 for (; low != high; ++low)
886 if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
892 ctype<wchar_t>::do_toupper(char_type c) const
894 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
895 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
896 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
897 defined(__NetBSD__) || defined(__MVS__)
898 return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
900 return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;
905 ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
907 for (; low != high; ++low)
908 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
909 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
910 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
911 defined(__NetBSD__) || defined(__MVS__)
912 *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
915 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low;
921 ctype<wchar_t>::do_tolower(char_type c) const
923 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
924 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
925 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
926 defined(__NetBSD__) || defined(__MVS__)
927 return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
929 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;
934 ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
936 for (; low != high; ++low)
937 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
938 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
939 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
940 defined(__NetBSD__) || defined(__MVS__)
941 *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
944 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low;
950 ctype<wchar_t>::do_widen(char c) const
956 ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
958 for (; low != high; ++low, ++dest)
964 ctype<wchar_t>::do_narrow(char_type c, char dfault) const
967 return static_cast<char>(c);
972 ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
974 for (; low != high; ++low, ++dest)
976 *dest = static_cast<char>(*low);
981 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
983 // template <> class ctype<char>;
985 locale::id ctype<char>::id;
987 const size_t ctype<char>::table_size;
989 ctype<char>::ctype(const mask* tab, bool del, size_t refs)
990 : locale::facet(refs),
995 __tab_ = classic_table();
998 ctype<char>::~ctype()
1000 if (__tab_ && __del_)
1005 ctype<char>::do_toupper(char_type c) const
1007 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1009 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
1010 #elif defined(__NetBSD__)
1011 return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
1012 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1014 static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
1016 return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;
1021 ctype<char>::do_toupper(char_type* low, const char_type* high) const
1023 for (; low != high; ++low)
1024 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1025 *low = isascii(*low) ?
1026 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
1027 #elif defined(__NetBSD__)
1028 *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
1029 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1030 *low = isascii(*low) ?
1031 static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
1033 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low;
1039 ctype<char>::do_tolower(char_type c) const
1041 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1043 static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
1044 #elif defined(__NetBSD__)
1045 return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
1046 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1048 static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
1050 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c;
1055 ctype<char>::do_tolower(char_type* low, const char_type* high) const
1057 for (; low != high; ++low)
1058 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1059 *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
1060 #elif defined(__NetBSD__)
1061 *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
1062 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1063 *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
1065 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low;
1071 ctype<char>::do_widen(char c) const
1077 ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
1079 for (; low != high; ++low, ++dest)
1085 ctype<char>::do_narrow(char_type c, char dfault) const
1088 return static_cast<char>(c);
1093 ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1095 for (; low != high; ++low, ++dest)
1103 #if defined(__EMSCRIPTEN__)
1104 extern "C" const unsigned short ** __ctype_b_loc();
1105 extern "C" const int ** __ctype_tolower_loc();
1106 extern "C" const int ** __ctype_toupper_loc();
1109 #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
1110 const ctype<char>::mask*
1111 ctype<char>::classic_table() noexcept
1113 static _LIBCPP_CONSTEXPR const ctype<char>::mask builtin_table[table_size] = {
1118 cntrl, cntrl | space | blank,
1119 cntrl | space, cntrl | space,
1120 cntrl | space, cntrl | space,
1130 space | blank | print, punct | print,
1131 punct | print, punct | print,
1132 punct | print, punct | print,
1133 punct | print, punct | print,
1134 punct | print, punct | print,
1135 punct | print, punct | print,
1136 punct | print, punct | print,
1137 punct | print, punct | print,
1138 digit | print | xdigit, digit | print | xdigit,
1139 digit | print | xdigit, digit | print | xdigit,
1140 digit | print | xdigit, digit | print | xdigit,
1141 digit | print | xdigit, digit | print | xdigit,
1142 digit | print | xdigit, digit | print | xdigit,
1143 punct | print, punct | print,
1144 punct | print, punct | print,
1145 punct | print, punct | print,
1146 punct | print, upper | xdigit | print | alpha,
1147 upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1148 upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1149 upper | xdigit | print | alpha, upper | print | alpha,
1150 upper | print | alpha, upper | print | alpha,
1151 upper | print | alpha, upper | print | alpha,
1152 upper | print | alpha, upper | print | alpha,
1153 upper | print | alpha, upper | print | alpha,
1154 upper | print | alpha, upper | print | alpha,
1155 upper | print | alpha, upper | print | alpha,
1156 upper | print | alpha, upper | print | alpha,
1157 upper | print | alpha, upper | print | alpha,
1158 upper | print | alpha, upper | print | alpha,
1159 upper | print | alpha, punct | print,
1160 punct | print, punct | print,
1161 punct | print, punct | print,
1162 punct | print, lower | xdigit | print | alpha,
1163 lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1164 lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1165 lower | xdigit | print | alpha, lower | print | alpha,
1166 lower | print | alpha, lower | print | alpha,
1167 lower | print | alpha, lower | print | alpha,
1168 lower | print | alpha, lower | print | alpha,
1169 lower | print | alpha, lower | print | alpha,
1170 lower | print | alpha, lower | print | alpha,
1171 lower | print | alpha, lower | print | alpha,
1172 lower | print | alpha, lower | print | alpha,
1173 lower | print | alpha, lower | print | alpha,
1174 lower | print | alpha, lower | print | alpha,
1175 lower | print | alpha, punct | print,
1176 punct | print, punct | print,
1177 punct | print, cntrl,
1178 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1179 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1180 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1181 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1182 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1183 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1184 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1185 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1187 return builtin_table;
1190 const ctype<char>::mask*
1191 ctype<char>::classic_table() noexcept
1193 #if defined(__APPLE__) || defined(__FreeBSD__)
1194 return _DefaultRuneLocale.__runetype;
1195 #elif defined(__NetBSD__)
1196 return _C_ctype_tab_ + 1;
1197 #elif defined(__GLIBC__)
1198 return _LIBCPP_GET_C_LOCALE->__ctype_b;
1199 #elif defined(__sun__)
1200 return __ctype_mask;
1201 #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
1202 return __pctype_func();
1203 #elif defined(__EMSCRIPTEN__)
1204 return *__ctype_b_loc();
1205 #elif defined(_NEWLIB_VERSION)
1206 // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
1209 return (const unsigned int *)__lc_ctype_ptr->obj->mask;
1210 #elif defined(__MVS__)
1211 # if defined(__NATIVE_ASCII_F)
1212 return const_cast<const ctype<char>::mask*> (__OBJ_DATA(__lc_ctype_a)->mask);
1214 return const_cast<const ctype<char>::mask*> (__ctypec);
1217 // Platform not supported: abort so the person doing the port knows what to
1219 # warning ctype<char>::classic_table() is not implemented
1220 printf("ctype<char>::classic_table() is not implemented\n");
1227 #if defined(__GLIBC__)
1229 ctype<char>::__classic_lower_table() noexcept
1231 return _LIBCPP_GET_C_LOCALE->__ctype_tolower;
1235 ctype<char>::__classic_upper_table() noexcept
1237 return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
1239 #elif defined(__NetBSD__)
1241 ctype<char>::__classic_lower_table() noexcept
1243 return _C_tolower_tab_ + 1;
1247 ctype<char>::__classic_upper_table() noexcept
1249 return _C_toupper_tab_ + 1;
1252 #elif defined(__EMSCRIPTEN__)
1254 ctype<char>::__classic_lower_table() noexcept
1256 return *__ctype_tolower_loc();
1260 ctype<char>::__classic_upper_table() noexcept
1262 return *__ctype_toupper_loc();
1264 #elif defined(__MVS__)
1265 const unsigned short*
1266 ctype<char>::__classic_lower_table() _NOEXCEPT
1268 # if defined(__NATIVE_ASCII_F)
1269 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a)->lower);
1271 return const_cast<const unsigned short*>(__ctype + __TOLOWER_INDEX);
1274 const unsigned short *
1275 ctype<char>::__classic_upper_table() _NOEXCEPT
1277 # if defined(__NATIVE_ASCII_F)
1278 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a)->upper);
1280 return const_cast<const unsigned short*>(__ctype + __TOUPPER_INDEX);
1283 #endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ || __MVS__
1285 // template <> class ctype_byname<char>
1287 ctype_byname<char>::ctype_byname(const char* name, size_t refs)
1288 : ctype<char>(0, false, refs),
1289 __l(newlocale(LC_ALL_MASK, name, 0))
1292 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1293 " failed to construct for " + string(name));
1296 ctype_byname<char>::ctype_byname(const string& name, size_t refs)
1297 : ctype<char>(0, false, refs),
1298 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1301 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1302 " failed to construct for " + name);
1305 ctype_byname<char>::~ctype_byname()
1311 ctype_byname<char>::do_toupper(char_type c) const
1313 return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l));
1317 ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
1319 for (; low != high; ++low)
1320 *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l));
1325 ctype_byname<char>::do_tolower(char_type c) const
1327 return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l));
1331 ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
1333 for (; low != high; ++low)
1334 *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l));
1338 // template <> class ctype_byname<wchar_t>
1340 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1341 ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
1342 : ctype<wchar_t>(refs),
1343 __l(newlocale(LC_ALL_MASK, name, 0))
1346 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1347 " failed to construct for " + string(name));
1350 ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
1351 : ctype<wchar_t>(refs),
1352 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1355 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1356 " failed to construct for " + name);
1359 ctype_byname<wchar_t>::~ctype_byname()
1365 ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1367 #ifdef _LIBCPP_WCTYPE_IS_MASK
1368 return static_cast<bool>(iswctype_l(c, m, __l));
1370 bool result = false;
1371 wint_t ch = static_cast<wint_t>(c);
1372 if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0);
1373 if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0);
1374 if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0);
1375 if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0);
1376 if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0);
1377 if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0);
1378 if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0);
1379 if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0);
1380 if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0);
1381 if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0);
1387 ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1389 for (; low != high; ++low, ++vec)
1392 *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
1396 wint_t ch = static_cast<wint_t>(*low);
1397 if (iswspace_l(ch, __l))
1399 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
1400 if (iswprint_l(ch, __l))
1403 if (iswcntrl_l(ch, __l))
1405 if (iswupper_l(ch, __l))
1407 if (iswlower_l(ch, __l))
1409 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
1410 if (iswalpha_l(ch, __l))
1413 if (iswdigit_l(ch, __l))
1415 if (iswpunct_l(ch, __l))
1417 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
1418 if (iswxdigit_l(ch, __l))
1421 #if !defined(__sun__)
1422 if (iswblank_l(ch, __l))
1431 ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1433 for (; low != high; ++low)
1435 #ifdef _LIBCPP_WCTYPE_IS_MASK
1436 if (iswctype_l(*low, m, __l))
1439 wint_t ch = static_cast<wint_t>(*low);
1440 if ((m & space) == space && iswspace_l(ch, __l)) break;
1441 if ((m & print) == print && iswprint_l(ch, __l)) break;
1442 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break;
1443 if ((m & upper) == upper && iswupper_l(ch, __l)) break;
1444 if ((m & lower) == lower && iswlower_l(ch, __l)) break;
1445 if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break;
1446 if ((m & digit) == digit && iswdigit_l(ch, __l)) break;
1447 if ((m & punct) == punct && iswpunct_l(ch, __l)) break;
1448 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break;
1449 if ((m & blank) == blank && iswblank_l(ch, __l)) break;
1456 ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1458 for (; low != high; ++low)
1460 #ifdef _LIBCPP_WCTYPE_IS_MASK
1461 if (!iswctype_l(*low, m, __l))
1464 wint_t ch = static_cast<wint_t>(*low);
1465 if ((m & space) == space && iswspace_l(ch, __l)) continue;
1466 if ((m & print) == print && iswprint_l(ch, __l)) continue;
1467 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue;
1468 if ((m & upper) == upper && iswupper_l(ch, __l)) continue;
1469 if ((m & lower) == lower && iswlower_l(ch, __l)) continue;
1470 if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue;
1471 if ((m & digit) == digit && iswdigit_l(ch, __l)) continue;
1472 if ((m & punct) == punct && iswpunct_l(ch, __l)) continue;
1473 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue;
1474 if ((m & blank) == blank && iswblank_l(ch, __l)) continue;
1482 ctype_byname<wchar_t>::do_toupper(char_type c) const
1484 return towupper_l(c, __l);
1488 ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1490 for (; low != high; ++low)
1491 *low = towupper_l(*low, __l);
1496 ctype_byname<wchar_t>::do_tolower(char_type c) const
1498 return towlower_l(c, __l);
1502 ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1504 for (; low != high; ++low)
1505 *low = towlower_l(*low, __l);
1510 ctype_byname<wchar_t>::do_widen(char c) const
1512 return __libcpp_btowc_l(c, __l);
1516 ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1518 for (; low != high; ++low, ++dest)
1519 *dest = __libcpp_btowc_l(*low, __l);
1524 ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1526 int r = __libcpp_wctob_l(c, __l);
1527 return (r != EOF) ? static_cast<char>(r) : dfault;
1531 ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1533 for (; low != high; ++low, ++dest)
1535 int r = __libcpp_wctob_l(*low, __l);
1536 *dest = (r != EOF) ? static_cast<char>(r) : dfault;
1540 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1542 // template <> class codecvt<char, char, mbstate_t>
1544 locale::id codecvt<char, char, mbstate_t>::id;
1546 codecvt<char, char, mbstate_t>::~codecvt()
1550 codecvt<char, char, mbstate_t>::result
1551 codecvt<char, char, mbstate_t>::do_out(state_type&,
1552 const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
1553 extern_type* to, extern_type*, extern_type*& to_nxt) const
1560 codecvt<char, char, mbstate_t>::result
1561 codecvt<char, char, mbstate_t>::do_in(state_type&,
1562 const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
1563 intern_type* to, intern_type*, intern_type*& to_nxt) const
1570 codecvt<char, char, mbstate_t>::result
1571 codecvt<char, char, mbstate_t>::do_unshift(state_type&,
1572 extern_type* to, extern_type*, extern_type*& to_nxt) const
1579 codecvt<char, char, mbstate_t>::do_encoding() const noexcept
1585 codecvt<char, char, mbstate_t>::do_always_noconv() const noexcept
1591 codecvt<char, char, mbstate_t>::do_length(state_type&,
1592 const extern_type* frm, const extern_type* end, size_t mx) const
1594 return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
1598 codecvt<char, char, mbstate_t>::do_max_length() const noexcept
1603 // template <> class codecvt<wchar_t, char, mbstate_t>
1605 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1606 locale::id codecvt<wchar_t, char, mbstate_t>::id;
1608 codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1609 : locale::facet(refs),
1610 __l(_LIBCPP_GET_C_LOCALE)
1614 codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1615 : locale::facet(refs),
1616 __l(newlocale(LC_ALL_MASK, nm, 0))
1619 __throw_runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1620 " failed to construct for " + string(nm));
1623 codecvt<wchar_t, char, mbstate_t>::~codecvt()
1625 if (__l != _LIBCPP_GET_C_LOCALE)
1629 codecvt<wchar_t, char, mbstate_t>::result
1630 codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
1631 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
1632 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1634 // look for first internal null in frm
1635 const intern_type* fend = frm;
1636 for (; fend != frm_end; ++fend)
1639 // loop over all null-terminated sequences in frm
1641 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1643 // save state in case it is needed to recover to_nxt on error
1644 mbstate_t save_state = st;
1645 size_t n = __libcpp_wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1646 static_cast<size_t>(to_end-to), &st, __l);
1647 if (n == size_t(-1))
1649 // need to recover to_nxt
1650 for (to_nxt = to; frm != frm_nxt; ++frm)
1652 n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l);
1653 if (n == size_t(-1))
1663 if (to_nxt == to_end)
1665 if (fend != frm_end) // set up next null terminated sequence
1667 // Try to write the terminating null
1668 extern_type tmp[MB_LEN_MAX];
1669 n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l);
1670 if (n == size_t(-1)) // on error
1672 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1674 for (extern_type* p = tmp; n; --n) // write it
1677 // look for next null in frm
1678 for (fend = frm_nxt; fend != frm_end; ++fend)
1683 return frm_nxt == frm_end ? ok : partial;
1686 codecvt<wchar_t, char, mbstate_t>::result
1687 codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
1688 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
1689 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1691 // look for first internal null in frm
1692 const extern_type* fend = frm;
1693 for (; fend != frm_end; ++fend)
1696 // loop over all null-terminated sequences in frm
1698 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1700 // save state in case it is needed to recover to_nxt on error
1701 mbstate_t save_state = st;
1702 size_t n = __libcpp_mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1703 static_cast<size_t>(to_end-to), &st, __l);
1704 if (n == size_t(-1))
1706 // need to recover to_nxt
1707 for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1709 n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
1728 return frm_nxt == frm_end ? ok : partial;
1730 if (n == size_t(-1))
1733 if (to_nxt == to_end)
1735 if (fend != frm_end) // set up next null terminated sequence
1737 // Try to write the terminating null
1738 n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1739 if (n != 0) // on error
1743 // look for next null in frm
1744 for (fend = frm_nxt; fend != frm_end; ++fend)
1749 return frm_nxt == frm_end ? ok : partial;
1752 codecvt<wchar_t, char, mbstate_t>::result
1753 codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1754 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1757 extern_type tmp[MB_LEN_MAX];
1758 size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l);
1759 if (n == size_t(-1) || n == 0) // on error
1762 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1764 for (extern_type* p = tmp; n; --n) // write it
1770 codecvt<wchar_t, char, mbstate_t>::do_encoding() const noexcept
1772 if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)
1775 // stateless encoding
1776 if (__l == 0 || __libcpp_mb_cur_max_l(__l) == 1) // there are no known constant length encodings
1777 return 1; // which take more than 1 char to form a wchar_t
1782 codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const noexcept
1788 codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1789 const extern_type* frm, const extern_type* frm_end, size_t mx) const
1792 for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1794 size_t n = __libcpp_mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l);
1814 codecvt<wchar_t, char, mbstate_t>::do_max_length() const noexcept
1816 return __l == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l));
1818 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1821 // UTF-32 UTF-16 UTF-8 # of code points
1822 // first second first second third fourth
1823 // 000000 - 00007F 0000 - 007F 00 - 7F 127
1824 // 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1825 // 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1826 // 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1827 // 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1828 // 00D800 - 00DFFF invalid
1829 // 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1830 // 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1831 // 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1832 // 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1834 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1836 codecvt_base::result
1837 utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1838 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1839 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1843 if (mode & generate_header)
1845 if (to_end-to_nxt < 3)
1846 return codecvt_base::partial;
1847 *to_nxt++ = static_cast<uint8_t>(0xEF);
1848 *to_nxt++ = static_cast<uint8_t>(0xBB);
1849 *to_nxt++ = static_cast<uint8_t>(0xBF);
1851 for (; frm_nxt < frm_end; ++frm_nxt)
1853 uint16_t wc1 = *frm_nxt;
1855 return codecvt_base::error;
1858 if (to_end-to_nxt < 1)
1859 return codecvt_base::partial;
1860 *to_nxt++ = static_cast<uint8_t>(wc1);
1862 else if (wc1 < 0x0800)
1864 if (to_end-to_nxt < 2)
1865 return codecvt_base::partial;
1866 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1867 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1869 else if (wc1 < 0xD800)
1871 if (to_end-to_nxt < 3)
1872 return codecvt_base::partial;
1873 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1874 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1875 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1877 else if (wc1 < 0xDC00)
1879 if (frm_end-frm_nxt < 2)
1880 return codecvt_base::partial;
1881 uint16_t wc2 = frm_nxt[1];
1882 if ((wc2 & 0xFC00) != 0xDC00)
1883 return codecvt_base::error;
1884 if (to_end-to_nxt < 4)
1885 return codecvt_base::partial;
1886 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1887 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1888 return codecvt_base::error;
1890 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1891 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1892 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1893 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1894 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1896 else if (wc1 < 0xE000)
1898 return codecvt_base::error;
1902 if (to_end-to_nxt < 3)
1903 return codecvt_base::partial;
1904 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1905 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1906 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1909 return codecvt_base::ok;
1913 codecvt_base::result
1914 utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1915 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1916 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1920 if (mode & generate_header)
1922 if (to_end-to_nxt < 3)
1923 return codecvt_base::partial;
1924 *to_nxt++ = static_cast<uint8_t>(0xEF);
1925 *to_nxt++ = static_cast<uint8_t>(0xBB);
1926 *to_nxt++ = static_cast<uint8_t>(0xBF);
1928 for (; frm_nxt < frm_end; ++frm_nxt)
1930 uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1932 return codecvt_base::error;
1935 if (to_end-to_nxt < 1)
1936 return codecvt_base::partial;
1937 *to_nxt++ = static_cast<uint8_t>(wc1);
1939 else if (wc1 < 0x0800)
1941 if (to_end-to_nxt < 2)
1942 return codecvt_base::partial;
1943 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1944 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1946 else if (wc1 < 0xD800)
1948 if (to_end-to_nxt < 3)
1949 return codecvt_base::partial;
1950 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1951 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1952 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1954 else if (wc1 < 0xDC00)
1956 if (frm_end-frm_nxt < 2)
1957 return codecvt_base::partial;
1958 uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1959 if ((wc2 & 0xFC00) != 0xDC00)
1960 return codecvt_base::error;
1961 if (to_end-to_nxt < 4)
1962 return codecvt_base::partial;
1963 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1964 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1965 return codecvt_base::error;
1967 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1968 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1969 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1970 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1971 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1973 else if (wc1 < 0xE000)
1975 return codecvt_base::error;
1979 if (to_end-to_nxt < 3)
1980 return codecvt_base::partial;
1981 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1982 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1983 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1986 return codecvt_base::ok;
1990 codecvt_base::result
1991 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1992 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1993 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1997 if (mode & consume_header)
1999 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2003 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2005 uint8_t c1 = *frm_nxt;
2007 return codecvt_base::error;
2010 *to_nxt = static_cast<uint16_t>(c1);
2015 return codecvt_base::error;
2019 if (frm_end-frm_nxt < 2)
2020 return codecvt_base::partial;
2021 uint8_t c2 = frm_nxt[1];
2022 if ((c2 & 0xC0) != 0x80)
2023 return codecvt_base::error;
2024 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2026 return codecvt_base::error;
2032 if (frm_end-frm_nxt < 3)
2033 return codecvt_base::partial;
2034 uint8_t c2 = frm_nxt[1];
2035 uint8_t c3 = frm_nxt[2];
2039 if ((c2 & 0xE0) != 0xA0)
2040 return codecvt_base::error;
2043 if ((c2 & 0xE0) != 0x80)
2044 return codecvt_base::error;
2047 if ((c2 & 0xC0) != 0x80)
2048 return codecvt_base::error;
2051 if ((c3 & 0xC0) != 0x80)
2052 return codecvt_base::error;
2053 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2054 | ((c2 & 0x3F) << 6)
2057 return codecvt_base::error;
2063 if (frm_end-frm_nxt < 4)
2064 return codecvt_base::partial;
2065 uint8_t c2 = frm_nxt[1];
2066 uint8_t c3 = frm_nxt[2];
2067 uint8_t c4 = frm_nxt[3];
2071 if (!(0x90 <= c2 && c2 <= 0xBF))
2072 return codecvt_base::error;
2075 if ((c2 & 0xF0) != 0x80)
2076 return codecvt_base::error;
2079 if ((c2 & 0xC0) != 0x80)
2080 return codecvt_base::error;
2083 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2084 return codecvt_base::error;
2085 if (to_end-to_nxt < 2)
2086 return codecvt_base::partial;
2087 if ((((c1 & 7UL) << 18) +
2088 ((c2 & 0x3FUL) << 12) +
2089 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2090 return codecvt_base::error;
2091 *to_nxt = static_cast<uint16_t>(
2093 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2094 | ((c2 & 0x0F) << 2)
2095 | ((c3 & 0x30) >> 4));
2096 *++to_nxt = static_cast<uint16_t>(
2098 | ((c3 & 0x0F) << 6)
2104 return codecvt_base::error;
2107 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2111 codecvt_base::result
2112 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2113 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2114 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2118 if (mode & consume_header)
2120 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2124 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2126 uint8_t c1 = *frm_nxt;
2128 return codecvt_base::error;
2131 *to_nxt = static_cast<uint32_t>(c1);
2136 return codecvt_base::error;
2140 if (frm_end-frm_nxt < 2)
2141 return codecvt_base::partial;
2142 uint8_t c2 = frm_nxt[1];
2143 if ((c2 & 0xC0) != 0x80)
2144 return codecvt_base::error;
2145 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2147 return codecvt_base::error;
2148 *to_nxt = static_cast<uint32_t>(t);
2153 if (frm_end-frm_nxt < 3)
2154 return codecvt_base::partial;
2155 uint8_t c2 = frm_nxt[1];
2156 uint8_t c3 = frm_nxt[2];
2160 if ((c2 & 0xE0) != 0xA0)
2161 return codecvt_base::error;
2164 if ((c2 & 0xE0) != 0x80)
2165 return codecvt_base::error;
2168 if ((c2 & 0xC0) != 0x80)
2169 return codecvt_base::error;
2172 if ((c3 & 0xC0) != 0x80)
2173 return codecvt_base::error;
2174 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2175 | ((c2 & 0x3F) << 6)
2178 return codecvt_base::error;
2179 *to_nxt = static_cast<uint32_t>(t);
2184 if (frm_end-frm_nxt < 4)
2185 return codecvt_base::partial;
2186 uint8_t c2 = frm_nxt[1];
2187 uint8_t c3 = frm_nxt[2];
2188 uint8_t c4 = frm_nxt[3];
2192 if (!(0x90 <= c2 && c2 <= 0xBF))
2193 return codecvt_base::error;
2196 if ((c2 & 0xF0) != 0x80)
2197 return codecvt_base::error;
2200 if ((c2 & 0xC0) != 0x80)
2201 return codecvt_base::error;
2204 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2205 return codecvt_base::error;
2206 if (to_end-to_nxt < 2)
2207 return codecvt_base::partial;
2208 if ((((c1 & 7UL) << 18) +
2209 ((c2 & 0x3FUL) << 12) +
2210 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2211 return codecvt_base::error;
2212 *to_nxt = static_cast<uint32_t>(
2214 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2215 | ((c2 & 0x0F) << 2)
2216 | ((c3 & 0x30) >> 4));
2217 *++to_nxt = static_cast<uint32_t>(
2219 | ((c3 & 0x0F) << 6)
2225 return codecvt_base::error;
2228 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2233 utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
2234 size_t mx, unsigned long Maxcode = 0x10FFFF,
2235 codecvt_mode mode = codecvt_mode(0))
2237 const uint8_t* frm_nxt = frm;
2238 if (mode & consume_header)
2240 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2244 for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
2246 uint8_t c1 = *frm_nxt;
2259 if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
2261 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
2268 if (frm_end-frm_nxt < 3)
2270 uint8_t c2 = frm_nxt[1];
2271 uint8_t c3 = frm_nxt[2];
2275 if ((c2 & 0xE0) != 0xA0)
2276 return static_cast<int>(frm_nxt - frm);
2279 if ((c2 & 0xE0) != 0x80)
2280 return static_cast<int>(frm_nxt - frm);
2283 if ((c2 & 0xC0) != 0x80)
2284 return static_cast<int>(frm_nxt - frm);
2287 if ((c3 & 0xC0) != 0x80)
2289 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2295 if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
2297 uint8_t c2 = frm_nxt[1];
2298 uint8_t c3 = frm_nxt[2];
2299 uint8_t c4 = frm_nxt[3];
2303 if (!(0x90 <= c2 && c2 <= 0xBF))
2304 return static_cast<int>(frm_nxt - frm);
2307 if ((c2 & 0xF0) != 0x80)
2308 return static_cast<int>(frm_nxt - frm);
2311 if ((c2 & 0xC0) != 0x80)
2312 return static_cast<int>(frm_nxt - frm);
2315 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2317 if ((((c1 & 7UL) << 18) +
2318 ((c2 & 0x3FUL) << 12) +
2319 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2329 return static_cast<int>(frm_nxt - frm);
2333 codecvt_base::result
2334 ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2335 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2336 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2340 if (mode & generate_header)
2342 if (to_end-to_nxt < 3)
2343 return codecvt_base::partial;
2344 *to_nxt++ = static_cast<uint8_t>(0xEF);
2345 *to_nxt++ = static_cast<uint8_t>(0xBB);
2346 *to_nxt++ = static_cast<uint8_t>(0xBF);
2348 for (; frm_nxt < frm_end; ++frm_nxt)
2350 uint32_t wc = *frm_nxt;
2351 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2352 return codecvt_base::error;
2355 if (to_end-to_nxt < 1)
2356 return codecvt_base::partial;
2357 *to_nxt++ = static_cast<uint8_t>(wc);
2359 else if (wc < 0x000800)
2361 if (to_end-to_nxt < 2)
2362 return codecvt_base::partial;
2363 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2364 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2366 else if (wc < 0x010000)
2368 if (to_end-to_nxt < 3)
2369 return codecvt_base::partial;
2370 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2371 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2372 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2374 else // if (wc < 0x110000)
2376 if (to_end-to_nxt < 4)
2377 return codecvt_base::partial;
2378 *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
2379 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2380 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2381 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
2384 return codecvt_base::ok;
2388 codecvt_base::result
2389 utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2390 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2391 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2395 if (mode & consume_header)
2397 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2401 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2403 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2407 return codecvt_base::error;
2408 *to_nxt = static_cast<uint32_t>(c1);
2413 return codecvt_base::error;
2417 if (frm_end-frm_nxt < 2)
2418 return codecvt_base::partial;
2419 uint8_t c2 = frm_nxt[1];
2420 if ((c2 & 0xC0) != 0x80)
2421 return codecvt_base::error;
2422 uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2425 return codecvt_base::error;
2431 if (frm_end-frm_nxt < 3)
2432 return codecvt_base::partial;
2433 uint8_t c2 = frm_nxt[1];
2434 uint8_t c3 = frm_nxt[2];
2438 if ((c2 & 0xE0) != 0xA0)
2439 return codecvt_base::error;
2442 if ((c2 & 0xE0) != 0x80)
2443 return codecvt_base::error;
2446 if ((c2 & 0xC0) != 0x80)
2447 return codecvt_base::error;
2450 if ((c3 & 0xC0) != 0x80)
2451 return codecvt_base::error;
2452 uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2453 | ((c2 & 0x3F) << 6)
2456 return codecvt_base::error;
2462 if (frm_end-frm_nxt < 4)
2463 return codecvt_base::partial;
2464 uint8_t c2 = frm_nxt[1];
2465 uint8_t c3 = frm_nxt[2];
2466 uint8_t c4 = frm_nxt[3];
2470 if (!(0x90 <= c2 && c2 <= 0xBF))
2471 return codecvt_base::error;
2474 if ((c2 & 0xF0) != 0x80)
2475 return codecvt_base::error;
2478 if ((c2 & 0xC0) != 0x80)
2479 return codecvt_base::error;
2482 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2483 return codecvt_base::error;
2484 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2485 | ((c2 & 0x3F) << 12)
2486 | ((c3 & 0x3F) << 6)
2489 return codecvt_base::error;
2495 return codecvt_base::error;
2498 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2503 utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2504 size_t mx, unsigned long Maxcode = 0x10FFFF,
2505 codecvt_mode mode = codecvt_mode(0))
2507 const uint8_t* frm_nxt = frm;
2508 if (mode & consume_header)
2510 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2514 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2516 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2529 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2531 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2537 if (frm_end-frm_nxt < 3)
2539 uint8_t c2 = frm_nxt[1];
2540 uint8_t c3 = frm_nxt[2];
2544 if ((c2 & 0xE0) != 0xA0)
2545 return static_cast<int>(frm_nxt - frm);
2548 if ((c2 & 0xE0) != 0x80)
2549 return static_cast<int>(frm_nxt - frm);
2552 if ((c2 & 0xC0) != 0x80)
2553 return static_cast<int>(frm_nxt - frm);
2556 if ((c3 & 0xC0) != 0x80)
2558 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2564 if (frm_end-frm_nxt < 4)
2566 uint8_t c2 = frm_nxt[1];
2567 uint8_t c3 = frm_nxt[2];
2568 uint8_t c4 = frm_nxt[3];
2572 if (!(0x90 <= c2 && c2 <= 0xBF))
2573 return static_cast<int>(frm_nxt - frm);
2576 if ((c2 & 0xF0) != 0x80)
2577 return static_cast<int>(frm_nxt - frm);
2580 if ((c2 & 0xC0) != 0x80)
2581 return static_cast<int>(frm_nxt - frm);
2584 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2586 if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
2587 ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode)
2596 return static_cast<int>(frm_nxt - frm);
2600 codecvt_base::result
2601 ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2602 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2603 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2607 if (mode & generate_header)
2609 if (to_end-to_nxt < 3)
2610 return codecvt_base::partial;
2611 *to_nxt++ = static_cast<uint8_t>(0xEF);
2612 *to_nxt++ = static_cast<uint8_t>(0xBB);
2613 *to_nxt++ = static_cast<uint8_t>(0xBF);
2615 for (; frm_nxt < frm_end; ++frm_nxt)
2617 uint16_t wc = *frm_nxt;
2618 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2619 return codecvt_base::error;
2622 if (to_end-to_nxt < 1)
2623 return codecvt_base::partial;
2624 *to_nxt++ = static_cast<uint8_t>(wc);
2626 else if (wc < 0x0800)
2628 if (to_end-to_nxt < 2)
2629 return codecvt_base::partial;
2630 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2631 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2633 else // if (wc <= 0xFFFF)
2635 if (to_end-to_nxt < 3)
2636 return codecvt_base::partial;
2637 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2638 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2639 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2642 return codecvt_base::ok;
2646 codecvt_base::result
2647 utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2648 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2649 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2653 if (mode & consume_header)
2655 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2659 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2661 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2665 return codecvt_base::error;
2666 *to_nxt = static_cast<uint16_t>(c1);
2671 return codecvt_base::error;
2675 if (frm_end-frm_nxt < 2)
2676 return codecvt_base::partial;
2677 uint8_t c2 = frm_nxt[1];
2678 if ((c2 & 0xC0) != 0x80)
2679 return codecvt_base::error;
2680 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2683 return codecvt_base::error;
2689 if (frm_end-frm_nxt < 3)
2690 return codecvt_base::partial;
2691 uint8_t c2 = frm_nxt[1];
2692 uint8_t c3 = frm_nxt[2];
2696 if ((c2 & 0xE0) != 0xA0)
2697 return codecvt_base::error;
2700 if ((c2 & 0xE0) != 0x80)
2701 return codecvt_base::error;
2704 if ((c2 & 0xC0) != 0x80)
2705 return codecvt_base::error;
2708 if ((c3 & 0xC0) != 0x80)
2709 return codecvt_base::error;
2710 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2711 | ((c2 & 0x3F) << 6)
2714 return codecvt_base::error;
2720 return codecvt_base::error;
2723 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2728 utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2729 size_t mx, unsigned long Maxcode = 0x10FFFF,
2730 codecvt_mode mode = codecvt_mode(0))
2732 const uint8_t* frm_nxt = frm;
2733 if (mode & consume_header)
2735 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2739 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2741 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2754 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2756 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2762 if (frm_end-frm_nxt < 3)
2764 uint8_t c2 = frm_nxt[1];
2765 uint8_t c3 = frm_nxt[2];
2769 if ((c2 & 0xE0) != 0xA0)
2770 return static_cast<int>(frm_nxt - frm);
2773 if ((c2 & 0xE0) != 0x80)
2774 return static_cast<int>(frm_nxt - frm);
2777 if ((c2 & 0xC0) != 0x80)
2778 return static_cast<int>(frm_nxt - frm);
2781 if ((c3 & 0xC0) != 0x80)
2783 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2792 return static_cast<int>(frm_nxt - frm);
2796 codecvt_base::result
2797 ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2798 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2799 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2803 if (mode & generate_header)
2805 if (to_end-to_nxt < 2)
2806 return codecvt_base::partial;
2807 *to_nxt++ = static_cast<uint8_t>(0xFE);
2808 *to_nxt++ = static_cast<uint8_t>(0xFF);
2810 for (; frm_nxt < frm_end; ++frm_nxt)
2812 uint32_t wc = *frm_nxt;
2813 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2814 return codecvt_base::error;
2817 if (to_end-to_nxt < 2)
2818 return codecvt_base::partial;
2819 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2820 *to_nxt++ = static_cast<uint8_t>(wc);
2824 if (to_end-to_nxt < 4)
2825 return codecvt_base::partial;
2826 uint16_t t = static_cast<uint16_t>(
2828 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2829 | ((wc & 0x00FC00) >> 10));
2830 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2831 *to_nxt++ = static_cast<uint8_t>(t);
2832 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2833 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2834 *to_nxt++ = static_cast<uint8_t>(t);
2837 return codecvt_base::ok;
2841 codecvt_base::result
2842 utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2843 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2844 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2848 if (mode & consume_header)
2850 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2853 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2855 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2856 if ((c1 & 0xFC00) == 0xDC00)
2857 return codecvt_base::error;
2858 if ((c1 & 0xFC00) != 0xD800)
2861 return codecvt_base::error;
2862 *to_nxt = static_cast<uint32_t>(c1);
2867 if (frm_end-frm_nxt < 4)
2868 return codecvt_base::partial;
2869 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2870 if ((c2 & 0xFC00) != 0xDC00)
2871 return codecvt_base::error;
2872 uint32_t t = static_cast<uint32_t>(
2873 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2874 | ((c1 & 0x003F) << 10)
2877 return codecvt_base::error;
2882 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2887 utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2888 size_t mx, unsigned long Maxcode = 0x10FFFF,
2889 codecvt_mode mode = codecvt_mode(0))
2891 const uint8_t* frm_nxt = frm;
2892 if (mode & consume_header)
2894 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2897 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2899 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2900 if ((c1 & 0xFC00) == 0xDC00)
2902 if ((c1 & 0xFC00) != 0xD800)
2910 if (frm_end-frm_nxt < 4)
2912 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2913 if ((c2 & 0xFC00) != 0xDC00)
2915 uint32_t t = static_cast<uint32_t>(
2916 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2917 | ((c1 & 0x003F) << 10)
2924 return static_cast<int>(frm_nxt - frm);
2928 codecvt_base::result
2929 ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2930 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2931 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2935 if (mode & generate_header)
2937 if (to_end - to_nxt < 2)
2938 return codecvt_base::partial;
2939 *to_nxt++ = static_cast<uint8_t>(0xFF);
2940 *to_nxt++ = static_cast<uint8_t>(0xFE);
2942 for (; frm_nxt < frm_end; ++frm_nxt)
2944 uint32_t wc = *frm_nxt;
2945 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2946 return codecvt_base::error;
2949 if (to_end-to_nxt < 2)
2950 return codecvt_base::partial;
2951 *to_nxt++ = static_cast<uint8_t>(wc);
2952 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2956 if (to_end-to_nxt < 4)
2957 return codecvt_base::partial;
2958 uint16_t t = static_cast<uint16_t>(
2960 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2961 | ((wc & 0x00FC00) >> 10));
2962 *to_nxt++ = static_cast<uint8_t>(t);
2963 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2964 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2965 *to_nxt++ = static_cast<uint8_t>(t);
2966 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2969 return codecvt_base::ok;
2973 codecvt_base::result
2974 utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2975 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2976 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2980 if (mode & consume_header)
2982 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2985 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2987 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2988 if ((c1 & 0xFC00) == 0xDC00)
2989 return codecvt_base::error;
2990 if ((c1 & 0xFC00) != 0xD800)
2993 return codecvt_base::error;
2994 *to_nxt = static_cast<uint32_t>(c1);
2999 if (frm_end-frm_nxt < 4)
3000 return codecvt_base::partial;
3001 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
3002 if ((c2 & 0xFC00) != 0xDC00)
3003 return codecvt_base::error;
3004 uint32_t t = static_cast<uint32_t>(
3005 ((((c1 & 0x03C0) >> 6) + 1) << 16)
3006 | ((c1 & 0x003F) << 10)
3009 return codecvt_base::error;
3014 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3019 utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
3020 size_t mx, unsigned long Maxcode = 0x10FFFF,
3021 codecvt_mode mode = codecvt_mode(0))
3023 const uint8_t* frm_nxt = frm;
3024 if (mode & consume_header)
3026 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3029 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
3031 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3032 if ((c1 & 0xFC00) == 0xDC00)
3034 if ((c1 & 0xFC00) != 0xD800)
3042 if (frm_end-frm_nxt < 4)
3044 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
3045 if ((c2 & 0xFC00) != 0xDC00)
3047 uint32_t t = static_cast<uint32_t>(
3048 ((((c1 & 0x03C0) >> 6) + 1) << 16)
3049 | ((c1 & 0x003F) << 10)
3056 return static_cast<int>(frm_nxt - frm);
3060 codecvt_base::result
3061 ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3062 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3063 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3067 if (mode & generate_header)
3069 if (to_end-to_nxt < 2)
3070 return codecvt_base::partial;
3071 *to_nxt++ = static_cast<uint8_t>(0xFE);
3072 *to_nxt++ = static_cast<uint8_t>(0xFF);
3074 for (; frm_nxt < frm_end; ++frm_nxt)
3076 uint16_t wc = *frm_nxt;
3077 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3078 return codecvt_base::error;
3079 if (to_end-to_nxt < 2)
3080 return codecvt_base::partial;
3081 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3082 *to_nxt++ = static_cast<uint8_t>(wc);
3084 return codecvt_base::ok;
3088 codecvt_base::result
3089 utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3090 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3091 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3095 if (mode & consume_header)
3097 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3100 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3102 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
3103 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3104 return codecvt_base::error;
3108 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3113 utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3114 size_t mx, unsigned long Maxcode = 0x10FFFF,
3115 codecvt_mode mode = codecvt_mode(0))
3117 const uint8_t* frm_nxt = frm;
3118 if (mode & consume_header)
3120 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3123 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3125 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
3126 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3130 return static_cast<int>(frm_nxt - frm);
3134 codecvt_base::result
3135 ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3136 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3137 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3141 if (mode & generate_header)
3143 if (to_end-to_nxt < 2)
3144 return codecvt_base::partial;
3145 *to_nxt++ = static_cast<uint8_t>(0xFF);
3146 *to_nxt++ = static_cast<uint8_t>(0xFE);
3148 for (; frm_nxt < frm_end; ++frm_nxt)
3150 uint16_t wc = *frm_nxt;
3151 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3152 return codecvt_base::error;
3153 if (to_end-to_nxt < 2)
3154 return codecvt_base::partial;
3155 *to_nxt++ = static_cast<uint8_t>(wc);
3156 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3158 return codecvt_base::ok;
3162 codecvt_base::result
3163 utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3164 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3165 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3169 if (mode & consume_header)
3171 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3174 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3176 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3177 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3178 return codecvt_base::error;
3182 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3187 utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3188 size_t mx, unsigned long Maxcode = 0x10FFFF,
3189 codecvt_mode mode = codecvt_mode(0))
3191 const uint8_t* frm_nxt = frm;
3193 if (mode & consume_header)
3195 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3198 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3200 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3201 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3205 return static_cast<int>(frm_nxt - frm);
3208 _LIBCPP_SUPPRESS_DEPRECATED_POP
3210 // template <> class codecvt<char16_t, char, mbstate_t>
3212 locale::id codecvt<char16_t, char, mbstate_t>::id;
3214 codecvt<char16_t, char, mbstate_t>::~codecvt()
3218 codecvt<char16_t, char, mbstate_t>::result
3219 codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
3220 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3221 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3223 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3224 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3225 const uint16_t* _frm_nxt = _frm;
3226 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3227 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3228 uint8_t* _to_nxt = _to;
3229 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3230 frm_nxt = frm + (_frm_nxt - _frm);
3231 to_nxt = to + (_to_nxt - _to);
3235 codecvt<char16_t, char, mbstate_t>::result
3236 codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
3237 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3238 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3240 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3241 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3242 const uint8_t* _frm_nxt = _frm;
3243 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3244 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3245 uint16_t* _to_nxt = _to;
3246 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3247 frm_nxt = frm + (_frm_nxt - _frm);
3248 to_nxt = to + (_to_nxt - _to);
3252 codecvt<char16_t, char, mbstate_t>::result
3253 codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
3254 extern_type* to, extern_type*, extern_type*& to_nxt) const
3261 codecvt<char16_t, char, mbstate_t>::do_encoding() const noexcept
3267 codecvt<char16_t, char, mbstate_t>::do_always_noconv() const noexcept
3273 codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
3274 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3276 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3277 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3278 return utf8_to_utf16_length(_frm, _frm_end, mx);
3282 codecvt<char16_t, char, mbstate_t>::do_max_length() const noexcept
3287 #ifndef _LIBCPP_HAS_NO_CHAR8_T
3289 // template <> class codecvt<char16_t, char8_t, mbstate_t>
3291 locale::id codecvt<char16_t, char8_t, mbstate_t>::id;
3293 codecvt<char16_t, char8_t, mbstate_t>::~codecvt()
3297 codecvt<char16_t, char8_t, mbstate_t>::result
3298 codecvt<char16_t, char8_t, mbstate_t>::do_out(state_type&,
3299 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3300 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3302 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3303 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3304 const uint16_t* _frm_nxt = _frm;
3305 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3306 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3307 uint8_t* _to_nxt = _to;
3308 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3309 frm_nxt = frm + (_frm_nxt - _frm);
3310 to_nxt = to + (_to_nxt - _to);
3314 codecvt<char16_t, char8_t, mbstate_t>::result
3315 codecvt<char16_t, char8_t, mbstate_t>::do_in(state_type&,
3316 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3317 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3319 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3320 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3321 const uint8_t* _frm_nxt = _frm;
3322 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3323 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3324 uint16_t* _to_nxt = _to;
3325 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3326 frm_nxt = frm + (_frm_nxt - _frm);
3327 to_nxt = to + (_to_nxt - _to);
3331 codecvt<char16_t, char8_t, mbstate_t>::result
3332 codecvt<char16_t, char8_t, mbstate_t>::do_unshift(state_type&,
3333 extern_type* to, extern_type*, extern_type*& to_nxt) const
3340 codecvt<char16_t, char8_t, mbstate_t>::do_encoding() const noexcept
3346 codecvt<char16_t, char8_t, mbstate_t>::do_always_noconv() const noexcept
3352 codecvt<char16_t, char8_t, mbstate_t>::do_length(state_type&,
3353 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3355 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3356 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3357 return utf8_to_utf16_length(_frm, _frm_end, mx);
3361 codecvt<char16_t, char8_t, mbstate_t>::do_max_length() const noexcept
3368 // template <> class codecvt<char32_t, char, mbstate_t>
3370 locale::id codecvt<char32_t, char, mbstate_t>::id;
3372 codecvt<char32_t, char, mbstate_t>::~codecvt()
3376 codecvt<char32_t, char, mbstate_t>::result
3377 codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
3378 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3379 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3381 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3382 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3383 const uint32_t* _frm_nxt = _frm;
3384 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3385 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3386 uint8_t* _to_nxt = _to;
3387 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3388 frm_nxt = frm + (_frm_nxt - _frm);
3389 to_nxt = to + (_to_nxt - _to);
3393 codecvt<char32_t, char, mbstate_t>::result
3394 codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
3395 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3396 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3398 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3399 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3400 const uint8_t* _frm_nxt = _frm;
3401 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3402 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3403 uint32_t* _to_nxt = _to;
3404 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3405 frm_nxt = frm + (_frm_nxt - _frm);
3406 to_nxt = to + (_to_nxt - _to);
3410 codecvt<char32_t, char, mbstate_t>::result
3411 codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3412 extern_type* to, extern_type*, extern_type*& to_nxt) const
3419 codecvt<char32_t, char, mbstate_t>::do_encoding() const noexcept
3425 codecvt<char32_t, char, mbstate_t>::do_always_noconv() const noexcept
3431 codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3432 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3434 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3435 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3436 return utf8_to_ucs4_length(_frm, _frm_end, mx);
3440 codecvt<char32_t, char, mbstate_t>::do_max_length() const noexcept
3445 #ifndef _LIBCPP_HAS_NO_CHAR8_T
3447 // template <> class codecvt<char32_t, char8_t, mbstate_t>
3449 locale::id codecvt<char32_t, char8_t, mbstate_t>::id;
3451 codecvt<char32_t, char8_t, mbstate_t>::~codecvt()
3455 codecvt<char32_t, char8_t, mbstate_t>::result
3456 codecvt<char32_t, char8_t, mbstate_t>::do_out(state_type&,
3457 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3458 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3460 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3461 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3462 const uint32_t* _frm_nxt = _frm;
3463 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3464 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3465 uint8_t* _to_nxt = _to;
3466 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3467 frm_nxt = frm + (_frm_nxt - _frm);
3468 to_nxt = to + (_to_nxt - _to);
3472 codecvt<char32_t, char8_t, mbstate_t>::result
3473 codecvt<char32_t, char8_t, mbstate_t>::do_in(state_type&,
3474 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3475 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3477 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3478 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3479 const uint8_t* _frm_nxt = _frm;
3480 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3481 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3482 uint32_t* _to_nxt = _to;
3483 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3484 frm_nxt = frm + (_frm_nxt - _frm);
3485 to_nxt = to + (_to_nxt - _to);
3489 codecvt<char32_t, char8_t, mbstate_t>::result
3490 codecvt<char32_t, char8_t, mbstate_t>::do_unshift(state_type&,
3491 extern_type* to, extern_type*, extern_type*& to_nxt) const
3498 codecvt<char32_t, char8_t, mbstate_t>::do_encoding() const noexcept
3504 codecvt<char32_t, char8_t, mbstate_t>::do_always_noconv() const noexcept
3510 codecvt<char32_t, char8_t, mbstate_t>::do_length(state_type&,
3511 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3513 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3514 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3515 return utf8_to_ucs4_length(_frm, _frm_end, mx);
3519 codecvt<char32_t, char8_t, mbstate_t>::do_max_length() const noexcept
3526 // __codecvt_utf8<wchar_t>
3528 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3529 __codecvt_utf8<wchar_t>::result
3530 __codecvt_utf8<wchar_t>::do_out(state_type&,
3531 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3532 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3534 #if defined(_LIBCPP_SHORT_WCHAR)
3535 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3536 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3537 const uint16_t* _frm_nxt = _frm;
3539 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3540 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3541 const uint32_t* _frm_nxt = _frm;
3543 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3544 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3545 uint8_t* _to_nxt = _to;
3546 #if defined(_LIBCPP_SHORT_WCHAR)
3547 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3550 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3553 frm_nxt = frm + (_frm_nxt - _frm);
3554 to_nxt = to + (_to_nxt - _to);
3558 __codecvt_utf8<wchar_t>::result
3559 __codecvt_utf8<wchar_t>::do_in(state_type&,
3560 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3561 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3563 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3564 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3565 const uint8_t* _frm_nxt = _frm;
3566 #if defined(_LIBCPP_SHORT_WCHAR)
3567 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3568 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3569 uint16_t* _to_nxt = _to;
3570 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3573 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3574 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3575 uint32_t* _to_nxt = _to;
3576 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3579 frm_nxt = frm + (_frm_nxt - _frm);
3580 to_nxt = to + (_to_nxt - _to);
3584 __codecvt_utf8<wchar_t>::result
3585 __codecvt_utf8<wchar_t>::do_unshift(state_type&,
3586 extern_type* to, extern_type*, extern_type*& to_nxt) const
3593 __codecvt_utf8<wchar_t>::do_encoding() const noexcept
3599 __codecvt_utf8<wchar_t>::do_always_noconv() const noexcept
3605 __codecvt_utf8<wchar_t>::do_length(state_type&,
3606 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3608 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3609 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3610 #if defined(_LIBCPP_SHORT_WCHAR)
3611 return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3613 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3617 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3619 __codecvt_utf8<wchar_t>::do_max_length() const noexcept
3621 #if defined(_LIBCPP_SHORT_WCHAR)
3622 if (_Mode_ & consume_header)
3626 if (_Mode_ & consume_header)
3631 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3633 // __codecvt_utf8<char16_t>
3635 __codecvt_utf8<char16_t>::result
3636 __codecvt_utf8<char16_t>::do_out(state_type&,
3637 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3638 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3640 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3641 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3642 const uint16_t* _frm_nxt = _frm;
3643 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3644 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3645 uint8_t* _to_nxt = _to;
3646 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3648 frm_nxt = frm + (_frm_nxt - _frm);
3649 to_nxt = to + (_to_nxt - _to);
3653 __codecvt_utf8<char16_t>::result
3654 __codecvt_utf8<char16_t>::do_in(state_type&,
3655 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3656 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3658 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3659 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3660 const uint8_t* _frm_nxt = _frm;
3661 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3662 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3663 uint16_t* _to_nxt = _to;
3664 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3666 frm_nxt = frm + (_frm_nxt - _frm);
3667 to_nxt = to + (_to_nxt - _to);
3671 __codecvt_utf8<char16_t>::result
3672 __codecvt_utf8<char16_t>::do_unshift(state_type&,
3673 extern_type* to, extern_type*, extern_type*& to_nxt) const
3680 __codecvt_utf8<char16_t>::do_encoding() const noexcept
3686 __codecvt_utf8<char16_t>::do_always_noconv() const noexcept
3692 __codecvt_utf8<char16_t>::do_length(state_type&,
3693 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3695 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3696 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3697 return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3700 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3702 __codecvt_utf8<char16_t>::do_max_length() const noexcept
3704 if (_Mode_ & consume_header)
3708 _LIBCPP_SUPPRESS_DEPRECATED_POP
3710 // __codecvt_utf8<char32_t>
3712 __codecvt_utf8<char32_t>::result
3713 __codecvt_utf8<char32_t>::do_out(state_type&,
3714 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3715 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3717 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3718 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3719 const uint32_t* _frm_nxt = _frm;
3720 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3721 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3722 uint8_t* _to_nxt = _to;
3723 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3725 frm_nxt = frm + (_frm_nxt - _frm);
3726 to_nxt = to + (_to_nxt - _to);
3730 __codecvt_utf8<char32_t>::result
3731 __codecvt_utf8<char32_t>::do_in(state_type&,
3732 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3733 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3735 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3736 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3737 const uint8_t* _frm_nxt = _frm;
3738 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3739 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3740 uint32_t* _to_nxt = _to;
3741 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3743 frm_nxt = frm + (_frm_nxt - _frm);
3744 to_nxt = to + (_to_nxt - _to);
3748 __codecvt_utf8<char32_t>::result
3749 __codecvt_utf8<char32_t>::do_unshift(state_type&,
3750 extern_type* to, extern_type*, extern_type*& to_nxt) const
3757 __codecvt_utf8<char32_t>::do_encoding() const noexcept
3763 __codecvt_utf8<char32_t>::do_always_noconv() const noexcept
3769 __codecvt_utf8<char32_t>::do_length(state_type&,
3770 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3772 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3773 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3774 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3777 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3779 __codecvt_utf8<char32_t>::do_max_length() const noexcept
3781 if (_Mode_ & consume_header)
3785 _LIBCPP_SUPPRESS_DEPRECATED_POP
3787 // __codecvt_utf16<wchar_t, false>
3789 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3790 __codecvt_utf16<wchar_t, false>::result
3791 __codecvt_utf16<wchar_t, false>::do_out(state_type&,
3792 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3793 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3795 #if defined(_LIBCPP_SHORT_WCHAR)
3796 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3797 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3798 const uint16_t* _frm_nxt = _frm;
3800 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3801 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3802 const uint32_t* _frm_nxt = _frm;
3804 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3805 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3806 uint8_t* _to_nxt = _to;
3807 #if defined(_LIBCPP_SHORT_WCHAR)
3808 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3811 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3814 frm_nxt = frm + (_frm_nxt - _frm);
3815 to_nxt = to + (_to_nxt - _to);
3819 __codecvt_utf16<wchar_t, false>::result
3820 __codecvt_utf16<wchar_t, false>::do_in(state_type&,
3821 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3822 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3824 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3825 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3826 const uint8_t* _frm_nxt = _frm;
3827 #if defined(_LIBCPP_SHORT_WCHAR)
3828 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3829 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3830 uint16_t* _to_nxt = _to;
3831 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3834 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3835 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3836 uint32_t* _to_nxt = _to;
3837 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3840 frm_nxt = frm + (_frm_nxt - _frm);
3841 to_nxt = to + (_to_nxt - _to);
3845 __codecvt_utf16<wchar_t, false>::result
3846 __codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3847 extern_type* to, extern_type*, extern_type*& to_nxt) const
3854 __codecvt_utf16<wchar_t, false>::do_encoding() const noexcept
3860 __codecvt_utf16<wchar_t, false>::do_always_noconv() const noexcept
3866 __codecvt_utf16<wchar_t, false>::do_length(state_type&,
3867 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3869 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3870 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3871 #if defined(_LIBCPP_SHORT_WCHAR)
3872 return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3874 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3879 __codecvt_utf16<wchar_t, false>::do_max_length() const noexcept
3881 #if defined(_LIBCPP_SHORT_WCHAR)
3882 if (_Mode_ & consume_header)
3886 if (_Mode_ & consume_header)
3892 // __codecvt_utf16<wchar_t, true>
3894 __codecvt_utf16<wchar_t, true>::result
3895 __codecvt_utf16<wchar_t, true>::do_out(state_type&,
3896 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3897 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3899 #if defined(_LIBCPP_SHORT_WCHAR)
3900 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3901 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3902 const uint16_t* _frm_nxt = _frm;
3904 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3905 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3906 const uint32_t* _frm_nxt = _frm;
3908 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3909 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3910 uint8_t* _to_nxt = _to;
3911 #if defined(_LIBCPP_SHORT_WCHAR)
3912 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3915 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3918 frm_nxt = frm + (_frm_nxt - _frm);
3919 to_nxt = to + (_to_nxt - _to);
3923 __codecvt_utf16<wchar_t, true>::result
3924 __codecvt_utf16<wchar_t, true>::do_in(state_type&,
3925 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3926 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3928 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3929 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3930 const uint8_t* _frm_nxt = _frm;
3931 #if defined(_LIBCPP_SHORT_WCHAR)
3932 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3933 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3934 uint16_t* _to_nxt = _to;
3935 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3938 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3939 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3940 uint32_t* _to_nxt = _to;
3941 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3944 frm_nxt = frm + (_frm_nxt - _frm);
3945 to_nxt = to + (_to_nxt - _to);
3949 __codecvt_utf16<wchar_t, true>::result
3950 __codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3951 extern_type* to, extern_type*, extern_type*& to_nxt) const
3958 __codecvt_utf16<wchar_t, true>::do_encoding() const noexcept
3964 __codecvt_utf16<wchar_t, true>::do_always_noconv() const noexcept
3970 __codecvt_utf16<wchar_t, true>::do_length(state_type&,
3971 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3973 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3974 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3975 #if defined(_LIBCPP_SHORT_WCHAR)
3976 return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3978 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3983 __codecvt_utf16<wchar_t, true>::do_max_length() const noexcept
3985 #if defined(_LIBCPP_SHORT_WCHAR)
3986 if (_Mode_ & consume_header)
3990 if (_Mode_ & consume_header)
3995 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3997 // __codecvt_utf16<char16_t, false>
3999 __codecvt_utf16<char16_t, false>::result
4000 __codecvt_utf16<char16_t, false>::do_out(state_type&,
4001 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4002 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4004 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4005 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4006 const uint16_t* _frm_nxt = _frm;
4007 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4008 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4009 uint8_t* _to_nxt = _to;
4010 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4012 frm_nxt = frm + (_frm_nxt - _frm);
4013 to_nxt = to + (_to_nxt - _to);
4017 __codecvt_utf16<char16_t, false>::result
4018 __codecvt_utf16<char16_t, false>::do_in(state_type&,
4019 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4020 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4022 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4023 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4024 const uint8_t* _frm_nxt = _frm;
4025 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4026 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4027 uint16_t* _to_nxt = _to;
4028 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4030 frm_nxt = frm + (_frm_nxt - _frm);
4031 to_nxt = to + (_to_nxt - _to);
4035 __codecvt_utf16<char16_t, false>::result
4036 __codecvt_utf16<char16_t, false>::do_unshift(state_type&,
4037 extern_type* to, extern_type*, extern_type*& to_nxt) const
4044 __codecvt_utf16<char16_t, false>::do_encoding() const noexcept
4050 __codecvt_utf16<char16_t, false>::do_always_noconv() const noexcept
4056 __codecvt_utf16<char16_t, false>::do_length(state_type&,
4057 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4059 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4060 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4061 return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4064 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4066 __codecvt_utf16<char16_t, false>::do_max_length() const noexcept
4068 if (_Mode_ & consume_header)
4072 _LIBCPP_SUPPRESS_DEPRECATED_POP
4074 // __codecvt_utf16<char16_t, true>
4076 __codecvt_utf16<char16_t, true>::result
4077 __codecvt_utf16<char16_t, true>::do_out(state_type&,
4078 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4079 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4081 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4082 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4083 const uint16_t* _frm_nxt = _frm;
4084 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4085 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4086 uint8_t* _to_nxt = _to;
4087 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4089 frm_nxt = frm + (_frm_nxt - _frm);
4090 to_nxt = to + (_to_nxt - _to);
4094 __codecvt_utf16<char16_t, true>::result
4095 __codecvt_utf16<char16_t, true>::do_in(state_type&,
4096 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4097 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4099 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4100 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4101 const uint8_t* _frm_nxt = _frm;
4102 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4103 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4104 uint16_t* _to_nxt = _to;
4105 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4107 frm_nxt = frm + (_frm_nxt - _frm);
4108 to_nxt = to + (_to_nxt - _to);
4112 __codecvt_utf16<char16_t, true>::result
4113 __codecvt_utf16<char16_t, true>::do_unshift(state_type&,
4114 extern_type* to, extern_type*, extern_type*& to_nxt) const
4121 __codecvt_utf16<char16_t, true>::do_encoding() const noexcept
4127 __codecvt_utf16<char16_t, true>::do_always_noconv() const noexcept
4133 __codecvt_utf16<char16_t, true>::do_length(state_type&,
4134 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4136 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4137 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4138 return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4141 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4143 __codecvt_utf16<char16_t, true>::do_max_length() const noexcept
4145 if (_Mode_ & consume_header)
4149 _LIBCPP_SUPPRESS_DEPRECATED_POP
4151 // __codecvt_utf16<char32_t, false>
4153 __codecvt_utf16<char32_t, false>::result
4154 __codecvt_utf16<char32_t, false>::do_out(state_type&,
4155 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4156 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4158 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4159 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4160 const uint32_t* _frm_nxt = _frm;
4161 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4162 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4163 uint8_t* _to_nxt = _to;
4164 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4166 frm_nxt = frm + (_frm_nxt - _frm);
4167 to_nxt = to + (_to_nxt - _to);
4171 __codecvt_utf16<char32_t, false>::result
4172 __codecvt_utf16<char32_t, false>::do_in(state_type&,
4173 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4174 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4176 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4177 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4178 const uint8_t* _frm_nxt = _frm;
4179 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4180 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4181 uint32_t* _to_nxt = _to;
4182 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4184 frm_nxt = frm + (_frm_nxt - _frm);
4185 to_nxt = to + (_to_nxt - _to);
4189 __codecvt_utf16<char32_t, false>::result
4190 __codecvt_utf16<char32_t, false>::do_unshift(state_type&,
4191 extern_type* to, extern_type*, extern_type*& to_nxt) const
4198 __codecvt_utf16<char32_t, false>::do_encoding() const noexcept
4204 __codecvt_utf16<char32_t, false>::do_always_noconv() const noexcept
4210 __codecvt_utf16<char32_t, false>::do_length(state_type&,
4211 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4213 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4214 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4215 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4218 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4220 __codecvt_utf16<char32_t, false>::do_max_length() const noexcept
4222 if (_Mode_ & consume_header)
4226 _LIBCPP_SUPPRESS_DEPRECATED_POP
4228 // __codecvt_utf16<char32_t, true>
4230 __codecvt_utf16<char32_t, true>::result
4231 __codecvt_utf16<char32_t, true>::do_out(state_type&,
4232 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4233 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4235 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4236 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4237 const uint32_t* _frm_nxt = _frm;
4238 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4239 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4240 uint8_t* _to_nxt = _to;
4241 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4243 frm_nxt = frm + (_frm_nxt - _frm);
4244 to_nxt = to + (_to_nxt - _to);
4248 __codecvt_utf16<char32_t, true>::result
4249 __codecvt_utf16<char32_t, true>::do_in(state_type&,
4250 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4251 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4253 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4254 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4255 const uint8_t* _frm_nxt = _frm;
4256 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4257 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4258 uint32_t* _to_nxt = _to;
4259 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4261 frm_nxt = frm + (_frm_nxt - _frm);
4262 to_nxt = to + (_to_nxt - _to);
4266 __codecvt_utf16<char32_t, true>::result
4267 __codecvt_utf16<char32_t, true>::do_unshift(state_type&,
4268 extern_type* to, extern_type*, extern_type*& to_nxt) const
4275 __codecvt_utf16<char32_t, true>::do_encoding() const noexcept
4281 __codecvt_utf16<char32_t, true>::do_always_noconv() const noexcept
4287 __codecvt_utf16<char32_t, true>::do_length(state_type&,
4288 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4290 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4291 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4292 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4295 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4297 __codecvt_utf16<char32_t, true>::do_max_length() const noexcept
4299 if (_Mode_ & consume_header)
4303 _LIBCPP_SUPPRESS_DEPRECATED_POP
4305 // __codecvt_utf8_utf16<wchar_t>
4307 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4308 __codecvt_utf8_utf16<wchar_t>::result
4309 __codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
4310 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4311 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4313 #if defined(_LIBCPP_SHORT_WCHAR)
4314 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4315 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4316 const uint16_t* _frm_nxt = _frm;
4318 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4319 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4320 const uint32_t* _frm_nxt = _frm;
4322 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4323 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4324 uint8_t* _to_nxt = _to;
4325 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4327 frm_nxt = frm + (_frm_nxt - _frm);
4328 to_nxt = to + (_to_nxt - _to);
4332 __codecvt_utf8_utf16<wchar_t>::result
4333 __codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
4334 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4335 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4337 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4338 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4339 const uint8_t* _frm_nxt = _frm;
4340 #if defined(_LIBCPP_SHORT_WCHAR)
4341 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4342 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4343 uint16_t* _to_nxt = _to;
4345 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4346 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4347 uint32_t* _to_nxt = _to;
4349 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4351 frm_nxt = frm + (_frm_nxt - _frm);
4352 to_nxt = to + (_to_nxt - _to);
4356 __codecvt_utf8_utf16<wchar_t>::result
4357 __codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
4358 extern_type* to, extern_type*, extern_type*& to_nxt) const
4365 __codecvt_utf8_utf16<wchar_t>::do_encoding() const noexcept
4371 __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const noexcept
4377 __codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
4378 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4380 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4381 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4382 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4386 __codecvt_utf8_utf16<wchar_t>::do_max_length() const noexcept
4388 if (_Mode_ & consume_header)
4392 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4394 // __codecvt_utf8_utf16<char16_t>
4396 __codecvt_utf8_utf16<char16_t>::result
4397 __codecvt_utf8_utf16<char16_t>::do_out(state_type&,
4398 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4399 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4401 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4402 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4403 const uint16_t* _frm_nxt = _frm;
4404 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4405 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4406 uint8_t* _to_nxt = _to;
4407 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4409 frm_nxt = frm + (_frm_nxt - _frm);
4410 to_nxt = to + (_to_nxt - _to);
4414 __codecvt_utf8_utf16<char16_t>::result
4415 __codecvt_utf8_utf16<char16_t>::do_in(state_type&,
4416 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4417 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4419 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4420 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4421 const uint8_t* _frm_nxt = _frm;
4422 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4423 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4424 uint16_t* _to_nxt = _to;
4425 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4427 frm_nxt = frm + (_frm_nxt - _frm);
4428 to_nxt = to + (_to_nxt - _to);
4432 __codecvt_utf8_utf16<char16_t>::result
4433 __codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
4434 extern_type* to, extern_type*, extern_type*& to_nxt) const
4441 __codecvt_utf8_utf16<char16_t>::do_encoding() const noexcept
4447 __codecvt_utf8_utf16<char16_t>::do_always_noconv() const noexcept
4453 __codecvt_utf8_utf16<char16_t>::do_length(state_type&,
4454 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4456 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4457 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4458 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4461 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4463 __codecvt_utf8_utf16<char16_t>::do_max_length() const noexcept
4465 if (_Mode_ & consume_header)
4469 _LIBCPP_SUPPRESS_DEPRECATED_POP
4471 // __codecvt_utf8_utf16<char32_t>
4473 __codecvt_utf8_utf16<char32_t>::result
4474 __codecvt_utf8_utf16<char32_t>::do_out(state_type&,
4475 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4476 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4478 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4479 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4480 const uint32_t* _frm_nxt = _frm;
4481 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4482 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4483 uint8_t* _to_nxt = _to;
4484 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4486 frm_nxt = frm + (_frm_nxt - _frm);
4487 to_nxt = to + (_to_nxt - _to);
4491 __codecvt_utf8_utf16<char32_t>::result
4492 __codecvt_utf8_utf16<char32_t>::do_in(state_type&,
4493 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4494 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4496 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4497 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4498 const uint8_t* _frm_nxt = _frm;
4499 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4500 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4501 uint32_t* _to_nxt = _to;
4502 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4504 frm_nxt = frm + (_frm_nxt - _frm);
4505 to_nxt = to + (_to_nxt - _to);
4509 __codecvt_utf8_utf16<char32_t>::result
4510 __codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
4511 extern_type* to, extern_type*, extern_type*& to_nxt) const
4518 __codecvt_utf8_utf16<char32_t>::do_encoding() const noexcept
4524 __codecvt_utf8_utf16<char32_t>::do_always_noconv() const noexcept
4530 __codecvt_utf8_utf16<char32_t>::do_length(state_type&,
4531 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4533 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4534 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4535 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4538 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4540 __codecvt_utf8_utf16<char32_t>::do_max_length() const noexcept
4542 if (_Mode_ & consume_header)
4546 _LIBCPP_SUPPRESS_DEPRECATED_POP
4548 // __narrow_to_utf8<16>
4550 __narrow_to_utf8<16>::~__narrow_to_utf8()
4554 // __narrow_to_utf8<32>
4556 __narrow_to_utf8<32>::~__narrow_to_utf8()
4560 // __widen_from_utf8<16>
4562 __widen_from_utf8<16>::~__widen_from_utf8()
4566 // __widen_from_utf8<32>
4568 __widen_from_utf8<32>::~__widen_from_utf8()
4572 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4573 static bool checked_string_to_wchar_convert(wchar_t& dest,
4580 size_t ret = __libcpp_mbrtowc_l(&out, ptr, strlen(ptr), &mb, loc);
4581 if (ret == static_cast<size_t>(-1) || ret == static_cast<size_t>(-2)) {
4587 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4589 #ifdef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4590 static bool is_narrow_non_breaking_space(const char* ptr) {
4591 // https://www.fileformat.info/info/unicode/char/202f/index.htm
4592 return ptr[0] == '\xe2' && ptr[1] == '\x80' && ptr[2] == '\xaf';
4595 static bool is_non_breaking_space(const char* ptr) {
4596 // https://www.fileformat.info/info/unicode/char/0a/index.htm
4597 return ptr[0] == '\xc2' && ptr[1] == '\xa0';
4599 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4601 static bool checked_string_to_char_convert(char& dest,
4611 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4612 // First convert the MBS into a wide char then attempt to narrow it using
4615 if (!checked_string_to_wchar_convert(wout, ptr, __loc))
4618 if ((res = __libcpp_wctob_l(wout, __loc)) != char_traits<char>::eof()) {
4622 // FIXME: Work around specific multibyte sequences that we can reasonably
4623 // translate into a different single byte.
4625 case L'\u202F': // narrow non-breaking space
4626 case L'\u00A0': // non-breaking space
4632 #else // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4633 // FIXME: Work around specific multibyte sequences that we can reasonably
4634 // translate into a different single byte.
4635 if (is_narrow_non_breaking_space(ptr) || is_non_breaking_space(ptr)) {
4641 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4642 __libcpp_unreachable();
4646 // numpunct<char> && numpunct<wchar_t>
4648 locale::id numpunct< char >::id;
4649 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4650 locale::id numpunct<wchar_t>::id;
4653 numpunct<char>::numpunct(size_t refs)
4654 : locale::facet(refs),
4655 __decimal_point_('.'),
4656 __thousands_sep_(',')
4660 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4661 numpunct<wchar_t>::numpunct(size_t refs)
4662 : locale::facet(refs),
4663 __decimal_point_(L'.'),
4664 __thousands_sep_(L',')
4669 numpunct<char>::~numpunct()
4673 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4674 numpunct<wchar_t>::~numpunct()
4679 char numpunct< char >::do_decimal_point() const {return __decimal_point_;}
4680 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4681 wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
4684 char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;}
4685 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4686 wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
4689 string numpunct< char >::do_grouping() const {return __grouping_;}
4690 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4691 string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
4694 string numpunct< char >::do_truename() const {return "true";}
4695 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4696 wstring numpunct<wchar_t>::do_truename() const {return L"true";}
4699 string numpunct< char >::do_falsename() const {return "false";}
4700 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4701 wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
4704 // numpunct_byname<char>
4706 numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4707 : numpunct<char>(refs)
4712 numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4713 : numpunct<char>(refs)
4718 numpunct_byname<char>::~numpunct_byname()
4723 numpunct_byname<char>::__init(const char* nm)
4725 typedef numpunct<char> base;
4726 if (strcmp(nm, "C") != 0)
4728 __libcpp_unique_locale loc(nm);
4730 __throw_runtime_error("numpunct_byname<char>::numpunct_byname"
4731 " failed to construct for " + string(nm));
4733 lconv* lc = __libcpp_localeconv_l(loc.get());
4734 if (!checked_string_to_char_convert(__decimal_point_, lc->decimal_point,
4736 __decimal_point_ = base::do_decimal_point();
4737 if (!checked_string_to_char_convert(__thousands_sep_, lc->thousands_sep,
4739 __thousands_sep_ = base::do_thousands_sep();
4740 __grouping_ = lc->grouping;
4741 // localization for truename and falsename is not available
4745 // numpunct_byname<wchar_t>
4747 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4748 numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4749 : numpunct<wchar_t>(refs)
4754 numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4755 : numpunct<wchar_t>(refs)
4760 numpunct_byname<wchar_t>::~numpunct_byname()
4765 numpunct_byname<wchar_t>::__init(const char* nm)
4767 if (strcmp(nm, "C") != 0)
4769 __libcpp_unique_locale loc(nm);
4771 __throw_runtime_error("numpunct_byname<wchar_t>::numpunct_byname"
4772 " failed to construct for " + string(nm));
4774 lconv* lc = __libcpp_localeconv_l(loc.get());
4775 checked_string_to_wchar_convert(__decimal_point_, lc->decimal_point,
4777 checked_string_to_wchar_convert(__thousands_sep_, lc->thousands_sep,
4779 __grouping_ = lc->grouping;
4780 // localization for truename and falsename is not available
4783 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4788 __num_get_base::__get_base(ios_base& iob)
4790 ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4791 if (__basefield == ios_base::oct)
4793 else if (__basefield == ios_base::hex)
4795 else if (__basefield == 0)
4800 const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4803 __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4804 ios_base::iostate& __err)
4806 // if the grouping pattern is empty _or_ there are no grouping bits, then do nothing
4807 // we always have at least a single entry in [__g, __g_end); the end of the input sequence
4808 if (__grouping.size() != 0 && __g_end - __g > 1)
4810 reverse(__g, __g_end);
4811 const char* __ig = __grouping.data();
4812 const char* __eg = __ig + __grouping.size();
4813 for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4815 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4817 if (static_cast<unsigned>(*__ig) != *__r)
4819 __err = ios_base::failbit;
4823 if (__eg - __ig > 1)
4826 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4828 if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
4829 __err = ios_base::failbit;
4835 __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4836 ios_base::fmtflags __flags)
4838 if ((__flags & ios_base::showpos) &&
4839 (__flags & ios_base::basefield) != ios_base::oct &&
4840 (__flags & ios_base::basefield) != ios_base::hex &&
4843 if (__flags & ios_base::showbase)
4846 *__fmtp++ = *__len++;
4847 if ((__flags & ios_base::basefield) == ios_base::oct)
4849 else if ((__flags & ios_base::basefield) == ios_base::hex)
4851 if (__flags & ios_base::uppercase)
4863 __num_put_base::__format_float(char* __fmtp, const char* __len,
4864 ios_base::fmtflags __flags)
4866 bool specify_precision = true;
4867 if (__flags & ios_base::showpos)
4869 if (__flags & ios_base::showpoint)
4871 ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4872 bool uppercase = (__flags & ios_base::uppercase) != 0;
4873 if (floatfield == (ios_base::fixed | ios_base::scientific))
4874 specify_precision = false;
4881 *__fmtp++ = *__len++;
4882 if (floatfield == ios_base::fixed)
4889 else if (floatfield == ios_base::scientific)
4896 else if (floatfield == (ios_base::fixed | ios_base::scientific))
4910 return specify_precision;
4914 __num_put_base::__identify_padding(char* __nb, char* __ne,
4915 const ios_base& __iob)
4917 switch (__iob.flags() & ios_base::adjustfield)
4919 case ios_base::internal:
4920 if (__nb[0] == '-' || __nb[0] == '+')
4922 if (__ne - __nb >= 2 && __nb[0] == '0'
4923 && (__nb[1] == 'x' || __nb[1] == 'X'))
4926 case ios_base::left:
4928 case ios_base::right:
4941 static string weeks[14];
4942 weeks[0] = "Sunday";
4943 weeks[1] = "Monday";
4944 weeks[2] = "Tuesday";
4945 weeks[3] = "Wednesday";
4946 weeks[4] = "Thursday";
4947 weeks[5] = "Friday";
4948 weeks[6] = "Saturday";
4959 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4964 static wstring weeks[14];
4965 weeks[0] = L"Sunday";
4966 weeks[1] = L"Monday";
4967 weeks[2] = L"Tuesday";
4968 weeks[3] = L"Wednesday";
4969 weeks[4] = L"Thursday";
4970 weeks[5] = L"Friday";
4971 weeks[6] = L"Saturday";
4985 __time_get_c_storage<char>::__weeks() const
4987 static const string* weeks = init_weeks();
4991 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4994 __time_get_c_storage<wchar_t>::__weeks() const
4996 static const wstring* weeks = init_wweeks();
5005 static string months[24];
5006 months[0] = "January";
5007 months[1] = "February";
5008 months[2] = "March";
5009 months[3] = "April";
5013 months[7] = "August";
5014 months[8] = "September";
5015 months[9] = "October";
5016 months[10] = "November";
5017 months[11] = "December";
5033 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5038 static wstring months[24];
5039 months[0] = L"January";
5040 months[1] = L"February";
5041 months[2] = L"March";
5042 months[3] = L"April";
5044 months[5] = L"June";
5045 months[6] = L"July";
5046 months[7] = L"August";
5047 months[8] = L"September";
5048 months[9] = L"October";
5049 months[10] = L"November";
5050 months[11] = L"December";
5051 months[12] = L"Jan";
5052 months[13] = L"Feb";
5053 months[14] = L"Mar";
5054 months[15] = L"Apr";
5055 months[16] = L"May";
5056 months[17] = L"Jun";
5057 months[18] = L"Jul";
5058 months[19] = L"Aug";
5059 months[20] = L"Sep";
5060 months[21] = L"Oct";
5061 months[22] = L"Nov";
5062 months[23] = L"Dec";
5069 __time_get_c_storage<char>::__months() const
5071 static const string* months = init_months();
5075 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5078 __time_get_c_storage<wchar_t>::__months() const
5080 static const wstring* months = init_wmonths();
5089 static string am_pm[2];
5095 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5100 static wstring am_pm[2];
5109 __time_get_c_storage<char>::__am_pm() const
5111 static const string* am_pm = init_am_pm();
5115 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5118 __time_get_c_storage<wchar_t>::__am_pm() const
5120 static const wstring* am_pm = init_wam_pm();
5127 __time_get_c_storage<char>::__x() const
5129 static string s("%m/%d/%y");
5133 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5136 __time_get_c_storage<wchar_t>::__x() const
5138 static wstring s(L"%m/%d/%y");
5145 __time_get_c_storage<char>::__X() const
5147 static string s("%H:%M:%S");
5151 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5154 __time_get_c_storage<wchar_t>::__X() const
5156 static wstring s(L"%H:%M:%S");
5163 __time_get_c_storage<char>::__c() const
5165 static string s("%a %b %d %H:%M:%S %Y");
5169 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5172 __time_get_c_storage<wchar_t>::__c() const
5174 static wstring s(L"%a %b %d %H:%M:%S %Y");
5181 __time_get_c_storage<char>::__r() const
5183 static string s("%I:%M:%S %p");
5187 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5190 __time_get_c_storage<wchar_t>::__r() const
5192 static wstring s(L"%I:%M:%S %p");
5199 __time_get::__time_get(const char* nm)
5200 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5203 __throw_runtime_error("time_get_byname"
5204 " failed to construct for " + string(nm));
5207 __time_get::__time_get(const string& nm)
5208 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5211 __throw_runtime_error("time_get_byname"
5212 " failed to construct for " + nm);
5215 __time_get::~__time_get()
5220 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-field-initializers")
5224 __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
5240 size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);
5246 if (ct.is(ctype_base::space, *bb))
5248 result.push_back(' ');
5249 for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
5254 ios_base::iostate err = ios_base::goodbit;
5255 ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
5260 result.push_back('%');
5262 result.push_back('A');
5264 result.push_back('a');
5269 i = __scan_keyword(w, be, this->__months_, this->__months_+24,
5274 result.push_back('%');
5276 result.push_back('B');
5278 result.push_back('b');
5279 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
5280 result.back() = 'm';
5284 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
5287 i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
5288 ct, err, false) - this->__am_pm_;
5291 result.push_back('%');
5292 result.push_back('p');
5298 if (ct.is(ctype_base::digit, *bb))
5300 switch(__get_up_to_n_digits(bb, be, err, ct, 4))
5303 result.push_back('%');
5304 result.push_back('w');
5307 result.push_back('%');
5308 result.push_back('u');
5311 result.push_back('%');
5312 result.push_back('I');
5315 result.push_back('%');
5316 result.push_back('m');
5319 result.push_back('%');
5320 result.push_back('H');
5323 result.push_back('%');
5324 result.push_back('d');
5327 result.push_back('%');
5328 result.push_back('M');
5331 result.push_back('%');
5332 result.push_back('S');
5335 result.push_back('%');
5336 result.push_back('y');
5339 result.push_back('%');
5340 result.push_back('j');
5343 result.push_back('%');
5344 result.push_back('Y');
5347 for (; w != bb; ++w)
5348 result.push_back(*w);
5355 result.push_back('%');
5356 result.push_back('%');
5360 result.push_back(*bb);
5366 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-braces")
5368 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5371 __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
5387 strftime_l(buf, countof(buf), f, &t, __loc_);
5389 wchar_t* wbb = wbuf;
5391 const char* bb = buf;
5392 size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
5393 if (j == size_t(-1))
5394 __throw_runtime_error("locale not supported");
5395 wchar_t* wbe = wbb + j;
5399 if (ct.is(ctype_base::space, *wbb))
5401 result.push_back(L' ');
5402 for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
5407 ios_base::iostate err = ios_base::goodbit;
5408 ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
5413 result.push_back(L'%');
5415 result.push_back(L'A');
5417 result.push_back(L'a');
5422 i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
5427 result.push_back(L'%');
5429 result.push_back(L'B');
5431 result.push_back(L'b');
5432 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
5433 result.back() = L'm';
5437 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
5440 i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
5441 ct, err, false) - this->__am_pm_;
5444 result.push_back(L'%');
5445 result.push_back(L'p');
5451 if (ct.is(ctype_base::digit, *wbb))
5453 switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
5456 result.push_back(L'%');
5457 result.push_back(L'w');
5460 result.push_back(L'%');
5461 result.push_back(L'u');
5464 result.push_back(L'%');
5465 result.push_back(L'I');
5468 result.push_back(L'%');
5469 result.push_back(L'm');
5472 result.push_back(L'%');
5473 result.push_back(L'H');
5476 result.push_back(L'%');
5477 result.push_back(L'd');
5480 result.push_back(L'%');
5481 result.push_back(L'M');
5484 result.push_back(L'%');
5485 result.push_back(L'S');
5488 result.push_back(L'%');
5489 result.push_back(L'y');
5492 result.push_back(L'%');
5493 result.push_back(L'j');
5496 result.push_back(L'%');
5497 result.push_back(L'Y');
5500 for (; w != wbb; ++w)
5501 result.push_back(*w);
5506 if (ct.narrow(*wbb, 0) == '%')
5508 result.push_back(L'%');
5509 result.push_back(L'%');
5513 result.push_back(*wbb);
5518 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5522 __time_get_storage<char>::init(const ctype<char>& ct)
5527 for (int i = 0; i < 7; ++i)
5530 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5532 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5533 __weeks_[i+7] = buf;
5536 for (int i = 0; i < 12; ++i)
5539 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5541 strftime_l(buf, countof(buf), "%b", &t, __loc_);
5542 __months_[i+12] = buf;
5546 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5549 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5551 __c_ = __analyze('c', ct);
5552 __r_ = __analyze('r', ct);
5553 __x_ = __analyze('x', ct);
5554 __X_ = __analyze('X', ct);
5557 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5560 __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
5568 for (int i = 0; i < 7; ++i)
5571 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5573 const char* bb = buf;
5574 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5575 if (j == size_t(-1) || j == 0)
5576 __throw_runtime_error("locale not supported");
5578 __weeks_[i].assign(wbuf, wbe);
5579 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5582 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5583 if (j == size_t(-1) || j == 0)
5584 __throw_runtime_error("locale not supported");
5586 __weeks_[i+7].assign(wbuf, wbe);
5589 for (int i = 0; i < 12; ++i)
5592 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5594 const char* bb = buf;
5595 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5596 if (j == size_t(-1) || j == 0)
5597 __throw_runtime_error("locale not supported");
5599 __months_[i].assign(wbuf, wbe);
5600 strftime_l(buf, countof(buf), "%b", &t, __loc_);
5603 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5604 if (j == size_t(-1) || j == 0)
5605 __throw_runtime_error("locale not supported");
5607 __months_[i+12].assign(wbuf, wbe);
5611 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5613 const char* bb = buf;
5614 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5615 if (j == size_t(-1))
5616 __throw_runtime_error("locale not supported");
5618 __am_pm_[0].assign(wbuf, wbe);
5620 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5623 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5624 if (j == size_t(-1))
5625 __throw_runtime_error("locale not supported");
5627 __am_pm_[1].assign(wbuf, wbe);
5628 __c_ = __analyze('c', ct);
5629 __r_ = __analyze('r', ct);
5630 __x_ = __analyze('x', ct);
5631 __X_ = __analyze('X', ct);
5633 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5635 template <class CharT>
5636 struct _LIBCPP_HIDDEN __time_get_temp
5637 : public ctype_byname<CharT>
5639 explicit __time_get_temp(const char* nm)
5640 : ctype_byname<CharT>(nm, 1) {}
5641 explicit __time_get_temp(const string& nm)
5642 : ctype_byname<CharT>(nm, 1) {}
5646 __time_get_storage<char>::__time_get_storage(const char* __nm)
5649 const __time_get_temp<char> ct(__nm);
5654 __time_get_storage<char>::__time_get_storage(const string& __nm)
5657 const __time_get_temp<char> ct(__nm);
5661 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5663 __time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5666 const __time_get_temp<wchar_t> ct(__nm);
5671 __time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5674 const __time_get_temp<wchar_t> ct(__nm);
5677 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5680 time_base::dateorder
5681 __time_get_storage<char>::__do_date_order() const
5684 for (i = 0; i < __x_.size(); ++i)
5692 for (++i; i < __x_.size(); ++i)
5695 if (i == __x_.size())
5701 for (++i; i < __x_.size(); ++i)
5704 if (i == __x_.size())
5708 return time_base::ymd;
5711 for (++i; i < __x_.size(); ++i)
5714 if (i == __x_.size())
5718 return time_base::ydm;
5723 for (++i; i < __x_.size(); ++i)
5726 if (i == __x_.size())
5731 for (++i; i < __x_.size(); ++i)
5734 if (i == __x_.size())
5737 if (__x_[i] == 'y' || __x_[i] == 'Y')
5738 return time_base::mdy;
5743 for (++i; i < __x_.size(); ++i)
5746 if (i == __x_.size())
5751 for (++i; i < __x_.size(); ++i)
5754 if (i == __x_.size())
5757 if (__x_[i] == 'y' || __x_[i] == 'Y')
5758 return time_base::dmy;
5763 return time_base::no_order;
5766 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5768 time_base::dateorder
5769 __time_get_storage<wchar_t>::__do_date_order() const
5772 for (i = 0; i < __x_.size(); ++i)
5773 if (__x_[i] == L'%')
5780 for (++i; i < __x_.size(); ++i)
5781 if (__x_[i] == L'%')
5783 if (i == __x_.size())
5789 for (++i; i < __x_.size(); ++i)
5790 if (__x_[i] == L'%')
5792 if (i == __x_.size())
5795 if (__x_[i] == L'd')
5796 return time_base::ymd;
5799 for (++i; i < __x_.size(); ++i)
5800 if (__x_[i] == L'%')
5802 if (i == __x_.size())
5805 if (__x_[i] == L'm')
5806 return time_base::ydm;
5811 for (++i; i < __x_.size(); ++i)
5812 if (__x_[i] == L'%')
5814 if (i == __x_.size())
5817 if (__x_[i] == L'd')
5819 for (++i; i < __x_.size(); ++i)
5820 if (__x_[i] == L'%')
5822 if (i == __x_.size())
5825 if (__x_[i] == L'y' || __x_[i] == L'Y')
5826 return time_base::mdy;
5831 for (++i; i < __x_.size(); ++i)
5832 if (__x_[i] == L'%')
5834 if (i == __x_.size())
5837 if (__x_[i] == L'm')
5839 for (++i; i < __x_.size(); ++i)
5840 if (__x_[i] == L'%')
5842 if (i == __x_.size())
5845 if (__x_[i] == L'y' || __x_[i] == L'Y')
5846 return time_base::dmy;
5851 return time_base::no_order;
5853 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5857 __time_put::__time_put(const char* nm)
5858 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5861 __throw_runtime_error("time_put_byname"
5862 " failed to construct for " + string(nm));
5865 __time_put::__time_put(const string& nm)
5866 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5869 __throw_runtime_error("time_put_byname"
5870 " failed to construct for " + nm);
5873 __time_put::~__time_put()
5875 if (__loc_ != _LIBCPP_GET_C_LOCALE)
5880 __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5881 char __fmt, char __mod) const
5883 char fmt[] = {'%', __fmt, __mod, 0};
5885 swap(fmt[1], fmt[2]);
5886 size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
5890 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5892 __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5893 char __fmt, char __mod) const
5896 char* __ne = __nar + 100;
5897 __do_put(__nar, __ne, __tm, __fmt, __mod);
5899 const char* __nb = __nar;
5900 size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
5901 if (j == size_t(-1))
5902 __throw_runtime_error("locale not supported");
5905 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5907 // moneypunct_byname
5909 template <class charT>
5912 __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
5913 bool intl, char cs_precedes, char sep_by_space, char sign_posn,
5916 const char sign = static_cast<char>(money_base::sign);
5917 const char space = static_cast<char>(money_base::space);
5918 const char none = static_cast<char>(money_base::none);
5919 const char symbol = static_cast<char>(money_base::symbol);
5920 const char value = static_cast<char>(money_base::value);
5921 const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
5923 // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5924 // function'. "Space between sign and symbol or value" means that
5925 // if the sign is adjacent to the symbol, there's a space between
5926 // them, and otherwise there's a space between the sign and value.
5928 // C11's localeconv specifies that the fourth character of an
5929 // international curr_symbol is used to separate the sign and
5930 // value when sep_by_space says to do so. C++ can't represent
5931 // that, so we just use a space. When sep_by_space says to
5932 // separate the symbol and value-or-sign with a space, we rearrange the
5933 // curr_symbol to put its spacing character on the correct side of
5936 // We also need to avoid adding an extra space between the sign
5937 // and value when the currency symbol is suppressed (by not
5938 // setting showbase). We match glibc's strfmon by interpreting
5939 // sep_by_space==1 as "omit the space when the currency symbol is
5942 // Users who want to get this right should use ICU instead.
5944 switch (cs_precedes)
5946 case 0: // value before curr_symbol
5947 if (symbol_contains_sep) {
5948 // Move the separator to before the symbol, to place it
5949 // between the value and symbol.
5950 rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,
5951 __curr_symbol_.end());
5955 case 0: // Parentheses surround the quantity and currency symbol.
5956 pat.field[0] = sign;
5957 pat.field[1] = value;
5958 pat.field[2] = none; // Any space appears in the symbol.
5959 pat.field[3] = symbol;
5960 switch (sep_by_space)
5962 case 0: // No space separates the currency symbol and value.
5963 // This case may have changed between C99 and C11;
5964 // assume the currency symbol matches the intention.
5965 case 2: // Space between sign and currency or value.
5966 // The "sign" is two parentheses, so no space here either.
5968 case 1: // Space between currency-and-sign or currency and value.
5969 if (!symbol_contains_sep) {
5970 // We insert the space into the symbol instead of
5971 // setting pat.field[2]=space so that when
5972 // showbase is not set, the space goes away too.
5973 __curr_symbol_.insert(0, 1, space_char);
5980 case 1: // The sign string precedes the quantity and currency symbol.
5981 pat.field[0] = sign;
5982 pat.field[3] = symbol;
5983 switch (sep_by_space)
5985 case 0: // No space separates the currency symbol and value.
5986 pat.field[1] = value;
5987 pat.field[2] = none;
5989 case 1: // Space between currency-and-sign or currency and value.
5990 pat.field[1] = value;
5991 pat.field[2] = none;
5992 if (!symbol_contains_sep) {
5993 // We insert the space into the symbol instead of
5994 // setting pat.field[2]=space so that when
5995 // showbase is not set, the space goes away too.
5996 __curr_symbol_.insert(0, 1, space_char);
5999 case 2: // Space between sign and currency or value.
6000 pat.field[1] = space;
6001 pat.field[2] = value;
6002 if (symbol_contains_sep) {
6003 // Remove the separator from the symbol, since it
6004 // has already appeared after the sign.
6005 __curr_symbol_.erase(__curr_symbol_.begin());
6012 case 2: // The sign string succeeds the quantity and currency symbol.
6013 pat.field[0] = value;
6014 pat.field[3] = sign;
6015 switch (sep_by_space)
6017 case 0: // No space separates the currency symbol and value.
6018 pat.field[1] = none;
6019 pat.field[2] = symbol;
6021 case 1: // Space between currency-and-sign or currency and value.
6022 if (!symbol_contains_sep) {
6023 // We insert the space into the symbol instead of
6024 // setting pat.field[1]=space so that when
6025 // showbase is not set, the space goes away too.
6026 __curr_symbol_.insert(0, 1, space_char);
6028 pat.field[1] = none;
6029 pat.field[2] = symbol;
6031 case 2: // Space between sign and currency or value.
6032 pat.field[1] = symbol;
6033 pat.field[2] = space;
6034 if (symbol_contains_sep) {
6035 // Remove the separator from the symbol, since it
6036 // should not be removed if showbase is absent.
6037 __curr_symbol_.erase(__curr_symbol_.begin());
6044 case 3: // The sign string immediately precedes the currency symbol.
6045 pat.field[0] = value;
6046 pat.field[3] = symbol;
6047 switch (sep_by_space)
6049 case 0: // No space separates the currency symbol and value.
6050 pat.field[1] = none;
6051 pat.field[2] = sign;
6053 case 1: // Space between currency-and-sign or currency and value.
6054 pat.field[1] = space;
6055 pat.field[2] = sign;
6056 if (symbol_contains_sep) {
6057 // Remove the separator from the symbol, since it
6058 // has already appeared before the sign.
6059 __curr_symbol_.erase(__curr_symbol_.begin());
6062 case 2: // Space between sign and currency or value.
6063 pat.field[1] = sign;
6064 pat.field[2] = none;
6065 if (!symbol_contains_sep) {
6066 // We insert the space into the symbol instead of
6067 // setting pat.field[2]=space so that when
6068 // showbase is not set, the space goes away too.
6069 __curr_symbol_.insert(0, 1, space_char);
6076 case 4: // The sign string immediately succeeds the currency symbol.
6077 pat.field[0] = value;
6078 pat.field[3] = sign;
6079 switch (sep_by_space)
6081 case 0: // No space separates the currency symbol and value.
6082 pat.field[1] = none;
6083 pat.field[2] = symbol;
6085 case 1: // Space between currency-and-sign or currency and value.
6086 pat.field[1] = none;
6087 pat.field[2] = symbol;
6088 if (!symbol_contains_sep) {
6089 // We insert the space into the symbol instead of
6090 // setting pat.field[1]=space so that when
6091 // showbase is not set, the space goes away too.
6092 __curr_symbol_.insert(0, 1, space_char);
6095 case 2: // Space between sign and currency or value.
6096 pat.field[1] = symbol;
6097 pat.field[2] = space;
6098 if (symbol_contains_sep) {
6099 // Remove the separator from the symbol, since it
6100 // should not disappear when showbase is absent.
6101 __curr_symbol_.erase(__curr_symbol_.begin());
6112 case 1: // curr_symbol before value
6115 case 0: // Parentheses surround the quantity and currency symbol.
6116 pat.field[0] = sign;
6117 pat.field[1] = symbol;
6118 pat.field[2] = none; // Any space appears in the symbol.
6119 pat.field[3] = value;
6120 switch (sep_by_space)
6122 case 0: // No space separates the currency symbol and value.
6123 // This case may have changed between C99 and C11;
6124 // assume the currency symbol matches the intention.
6125 case 2: // Space between sign and currency or value.
6126 // The "sign" is two parentheses, so no space here either.
6128 case 1: // Space between currency-and-sign or currency and value.
6129 if (!symbol_contains_sep) {
6130 // We insert the space into the symbol instead of
6131 // setting pat.field[2]=space so that when
6132 // showbase is not set, the space goes away too.
6133 __curr_symbol_.insert(0, 1, space_char);
6140 case 1: // The sign string precedes the quantity and currency symbol.
6141 pat.field[0] = sign;
6142 pat.field[3] = value;
6143 switch (sep_by_space)
6145 case 0: // No space separates the currency symbol and value.
6146 pat.field[1] = symbol;
6147 pat.field[2] = none;
6149 case 1: // Space between currency-and-sign or currency and value.
6150 pat.field[1] = symbol;
6151 pat.field[2] = none;
6152 if (!symbol_contains_sep) {
6153 // We insert the space into the symbol instead of
6154 // setting pat.field[2]=space so that when
6155 // showbase is not set, the space goes away too.
6156 __curr_symbol_.push_back(space_char);
6159 case 2: // Space between sign and currency or value.
6160 pat.field[1] = space;
6161 pat.field[2] = symbol;
6162 if (symbol_contains_sep) {
6163 // Remove the separator from the symbol, since it
6164 // has already appeared after the sign.
6165 __curr_symbol_.pop_back();
6172 case 2: // The sign string succeeds the quantity and currency symbol.
6173 pat.field[0] = symbol;
6174 pat.field[3] = sign;
6175 switch (sep_by_space)
6177 case 0: // No space separates the currency symbol and value.
6178 pat.field[1] = none;
6179 pat.field[2] = value;
6181 case 1: // Space between currency-and-sign or currency and value.
6182 pat.field[1] = none;
6183 pat.field[2] = value;
6184 if (!symbol_contains_sep) {
6185 // We insert the space into the symbol instead of
6186 // setting pat.field[1]=space so that when
6187 // showbase is not set, the space goes away too.
6188 __curr_symbol_.push_back(space_char);
6191 case 2: // Space between sign and currency or value.
6192 pat.field[1] = value;
6193 pat.field[2] = space;
6194 if (symbol_contains_sep) {
6195 // Remove the separator from the symbol, since it
6196 // will appear before the sign.
6197 __curr_symbol_.pop_back();
6204 case 3: // The sign string immediately precedes the currency symbol.
6205 pat.field[0] = sign;
6206 pat.field[3] = value;
6207 switch (sep_by_space)
6209 case 0: // No space separates the currency symbol and value.
6210 pat.field[1] = symbol;
6211 pat.field[2] = none;
6213 case 1: // Space between currency-and-sign or currency and value.
6214 pat.field[1] = symbol;
6215 pat.field[2] = none;
6216 if (!symbol_contains_sep) {
6217 // We insert the space into the symbol instead of
6218 // setting pat.field[2]=space so that when
6219 // showbase is not set, the space goes away too.
6220 __curr_symbol_.push_back(space_char);
6223 case 2: // Space between sign and currency or value.
6224 pat.field[1] = space;
6225 pat.field[2] = symbol;
6226 if (symbol_contains_sep) {
6227 // Remove the separator from the symbol, since it
6228 // has already appeared after the sign.
6229 __curr_symbol_.pop_back();
6236 case 4: // The sign string immediately succeeds the currency symbol.
6237 pat.field[0] = symbol;
6238 pat.field[3] = value;
6239 switch (sep_by_space)
6241 case 0: // No space separates the currency symbol and value.
6242 pat.field[1] = sign;
6243 pat.field[2] = none;
6245 case 1: // Space between currency-and-sign or currency and value.
6246 pat.field[1] = sign;
6247 pat.field[2] = space;
6248 if (symbol_contains_sep) {
6249 // Remove the separator from the symbol, since it
6250 // should not disappear when showbase is absent.
6251 __curr_symbol_.pop_back();
6254 case 2: // Space between sign and currency or value.
6255 pat.field[1] = none;
6256 pat.field[2] = sign;
6257 if (!symbol_contains_sep) {
6258 // We insert the space into the symbol instead of
6259 // setting pat.field[1]=space so that when
6260 // showbase is not set, the space goes away too.
6261 __curr_symbol_.push_back(space_char);
6275 pat.field[0] = symbol;
6276 pat.field[1] = sign;
6277 pat.field[2] = none;
6278 pat.field[3] = value;
6283 moneypunct_byname<char, false>::init(const char* nm)
6285 typedef moneypunct<char, false> base;
6286 __libcpp_unique_locale loc(nm);
6288 __throw_runtime_error("moneypunct_byname"
6289 " failed to construct for " + string(nm));
6291 lconv* lc = __libcpp_localeconv_l(loc.get());
6292 if (!checked_string_to_char_convert(__decimal_point_,
6293 lc->mon_decimal_point,
6295 __decimal_point_ = base::do_decimal_point();
6296 if (!checked_string_to_char_convert(__thousands_sep_,
6297 lc->mon_thousands_sep,
6299 __thousands_sep_ = base::do_thousands_sep();
6301 __grouping_ = lc->mon_grouping;
6302 __curr_symbol_ = lc->currency_symbol;
6303 if (lc->frac_digits != CHAR_MAX)
6304 __frac_digits_ = lc->frac_digits;
6306 __frac_digits_ = base::do_frac_digits();
6307 if (lc->p_sign_posn == 0)
6308 __positive_sign_ = "()";
6310 __positive_sign_ = lc->positive_sign;
6311 if (lc->n_sign_posn == 0)
6312 __negative_sign_ = "()";
6314 __negative_sign_ = lc->negative_sign;
6315 // Assume the positive and negative formats will want spaces in
6316 // the same places in curr_symbol since there's no way to
6317 // represent anything else.
6318 string_type __dummy_curr_symbol = __curr_symbol_;
6319 __init_pat(__pos_format_, __dummy_curr_symbol, false,
6320 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
6321 __init_pat(__neg_format_, __curr_symbol_, false,
6322 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
6327 moneypunct_byname<char, true>::init(const char* nm)
6329 typedef moneypunct<char, true> base;
6330 __libcpp_unique_locale loc(nm);
6332 __throw_runtime_error("moneypunct_byname"
6333 " failed to construct for " + string(nm));
6335 lconv* lc = __libcpp_localeconv_l(loc.get());
6336 if (!checked_string_to_char_convert(__decimal_point_,
6337 lc->mon_decimal_point,
6339 __decimal_point_ = base::do_decimal_point();
6340 if (!checked_string_to_char_convert(__thousands_sep_,
6341 lc->mon_thousands_sep,
6343 __thousands_sep_ = base::do_thousands_sep();
6344 __grouping_ = lc->mon_grouping;
6345 __curr_symbol_ = lc->int_curr_symbol;
6346 if (lc->int_frac_digits != CHAR_MAX)
6347 __frac_digits_ = lc->int_frac_digits;
6349 __frac_digits_ = base::do_frac_digits();
6350 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6351 if (lc->p_sign_posn == 0)
6352 #else // _LIBCPP_MSVCRT
6353 if (lc->int_p_sign_posn == 0)
6354 #endif // !_LIBCPP_MSVCRT
6355 __positive_sign_ = "()";
6357 __positive_sign_ = lc->positive_sign;
6358 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6359 if(lc->n_sign_posn == 0)
6360 #else // _LIBCPP_MSVCRT
6361 if (lc->int_n_sign_posn == 0)
6362 #endif // !_LIBCPP_MSVCRT
6363 __negative_sign_ = "()";
6365 __negative_sign_ = lc->negative_sign;
6366 // Assume the positive and negative formats will want spaces in
6367 // the same places in curr_symbol since there's no way to
6368 // represent anything else.
6369 string_type __dummy_curr_symbol = __curr_symbol_;
6370 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6371 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6372 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
6373 __init_pat(__neg_format_, __curr_symbol_, true,
6374 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
6375 #else // _LIBCPP_MSVCRT
6376 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6377 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6378 lc->int_p_sign_posn, ' ');
6379 __init_pat(__neg_format_, __curr_symbol_, true,
6380 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6381 lc->int_n_sign_posn, ' ');
6382 #endif // !_LIBCPP_MSVCRT
6385 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
6388 moneypunct_byname<wchar_t, false>::init(const char* nm)
6390 typedef moneypunct<wchar_t, false> base;
6391 __libcpp_unique_locale loc(nm);
6393 __throw_runtime_error("moneypunct_byname"
6394 " failed to construct for " + string(nm));
6395 lconv* lc = __libcpp_localeconv_l(loc.get());
6396 if (!checked_string_to_wchar_convert(__decimal_point_,
6397 lc->mon_decimal_point,
6399 __decimal_point_ = base::do_decimal_point();
6400 if (!checked_string_to_wchar_convert(__thousands_sep_,
6401 lc->mon_thousands_sep,
6403 __thousands_sep_ = base::do_thousands_sep();
6404 __grouping_ = lc->mon_grouping;
6407 const char* bb = lc->currency_symbol;
6408 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6409 if (j == size_t(-1))
6410 __throw_runtime_error("locale not supported");
6411 wchar_t* wbe = wbuf + j;
6412 __curr_symbol_.assign(wbuf, wbe);
6413 if (lc->frac_digits != CHAR_MAX)
6414 __frac_digits_ = lc->frac_digits;
6416 __frac_digits_ = base::do_frac_digits();
6417 if (lc->p_sign_posn == 0)
6418 __positive_sign_ = L"()";
6422 bb = lc->positive_sign;
6423 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6424 if (j == size_t(-1))
6425 __throw_runtime_error("locale not supported");
6427 __positive_sign_.assign(wbuf, wbe);
6429 if (lc->n_sign_posn == 0)
6430 __negative_sign_ = L"()";
6434 bb = lc->negative_sign;
6435 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6436 if (j == size_t(-1))
6437 __throw_runtime_error("locale not supported");
6439 __negative_sign_.assign(wbuf, wbe);
6441 // Assume the positive and negative formats will want spaces in
6442 // the same places in curr_symbol since there's no way to
6443 // represent anything else.
6444 string_type __dummy_curr_symbol = __curr_symbol_;
6445 __init_pat(__pos_format_, __dummy_curr_symbol, false,
6446 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6447 __init_pat(__neg_format_, __curr_symbol_, false,
6448 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6453 moneypunct_byname<wchar_t, true>::init(const char* nm)
6455 typedef moneypunct<wchar_t, true> base;
6456 __libcpp_unique_locale loc(nm);
6458 __throw_runtime_error("moneypunct_byname"
6459 " failed to construct for " + string(nm));
6461 lconv* lc = __libcpp_localeconv_l(loc.get());
6462 if (!checked_string_to_wchar_convert(__decimal_point_,
6463 lc->mon_decimal_point,
6465 __decimal_point_ = base::do_decimal_point();
6466 if (!checked_string_to_wchar_convert(__thousands_sep_,
6467 lc->mon_thousands_sep,
6469 __thousands_sep_ = base::do_thousands_sep();
6470 __grouping_ = lc->mon_grouping;
6473 const char* bb = lc->int_curr_symbol;
6474 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6475 if (j == size_t(-1))
6476 __throw_runtime_error("locale not supported");
6477 wchar_t* wbe = wbuf + j;
6478 __curr_symbol_.assign(wbuf, wbe);
6479 if (lc->int_frac_digits != CHAR_MAX)
6480 __frac_digits_ = lc->int_frac_digits;
6482 __frac_digits_ = base::do_frac_digits();
6483 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6484 if (lc->p_sign_posn == 0)
6485 #else // _LIBCPP_MSVCRT
6486 if (lc->int_p_sign_posn == 0)
6487 #endif // !_LIBCPP_MSVCRT
6488 __positive_sign_ = L"()";
6492 bb = lc->positive_sign;
6493 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6494 if (j == size_t(-1))
6495 __throw_runtime_error("locale not supported");
6497 __positive_sign_.assign(wbuf, wbe);
6499 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6500 if (lc->n_sign_posn == 0)
6501 #else // _LIBCPP_MSVCRT
6502 if (lc->int_n_sign_posn == 0)
6503 #endif // !_LIBCPP_MSVCRT
6504 __negative_sign_ = L"()";
6508 bb = lc->negative_sign;
6509 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6510 if (j == size_t(-1))
6511 __throw_runtime_error("locale not supported");
6513 __negative_sign_.assign(wbuf, wbe);
6515 // Assume the positive and negative formats will want spaces in
6516 // the same places in curr_symbol since there's no way to
6517 // represent anything else.
6518 string_type __dummy_curr_symbol = __curr_symbol_;
6519 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6520 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6521 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6522 __init_pat(__neg_format_, __curr_symbol_, true,
6523 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6524 #else // _LIBCPP_MSVCRT
6525 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6526 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6527 lc->int_p_sign_posn, L' ');
6528 __init_pat(__neg_format_, __curr_symbol_, true,
6529 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6530 lc->int_n_sign_posn, L' ');
6531 #endif // !_LIBCPP_MSVCRT
6533 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
6535 void __do_nothing(void*) {}
6537 void __throw_runtime_error(const char* msg)
6539 #ifndef _LIBCPP_NO_EXCEPTIONS
6540 throw runtime_error(msg);
6547 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;
6548 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;)
6550 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<char>;
6551 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<wchar_t>;)
6553 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<char>;
6554 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<wchar_t>;)
6556 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<char>;
6557 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<wchar_t>;)
6559 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<char>;
6560 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<wchar_t>;)
6562 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<char>;
6563 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<wchar_t>;)
6565 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<char>;
6566 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<wchar_t>;)
6568 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<char>;
6569 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<wchar_t>;)
6571 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<char>;
6572 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<wchar_t>;)
6574 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, false>;
6575 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, true>;
6576 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, false>;)
6577 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, true>;)
6579 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, false>;
6580 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, true>;
6581 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, false>;)
6582 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, true>;)
6584 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<char>;
6585 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<wchar_t>;)
6587 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<char>;
6588 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<wchar_t>;)
6590 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<char>;
6591 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<wchar_t>;)
6593 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<char>;
6594 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<wchar_t>;)
6596 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<char>;
6597 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<wchar_t>;)
6599 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<char>;
6600 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t>;)
6602 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>;
6603 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;)
6604 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
6605 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
6606 #ifndef _LIBCPP_HAS_NO_CHAR8_T
6607 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char8_t, mbstate_t>;
6608 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char8_t, mbstate_t>;
6611 _LIBCPP_END_NAMESPACE_STD