1 //===------------------------- locale.cpp ---------------------------------===//
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
21 #ifndef _LIBCPP_NO_EXCEPTIONS
22 # include "type_traits"
26 #if defined(_LIBCPP_MSVCRT)
27 #define _CTYPE_DISABLE_MACROS
30 #include "__sso_allocator"
31 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
32 #include "support/win32/locale_win32.h"
33 #elif !defined(__BIONIC__)
38 #include "include/atomic_support.h"
39 #include "__undef_macros"
41 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
42 // lots of noise in the build log, but no bugs that I know of.
43 #if defined(__clang__)
44 #pragma clang diagnostic ignored "-Wsign-conversion"
47 _LIBCPP_BEGIN_NAMESPACE_STD
49 struct __libcpp_unique_locale {
50 __libcpp_unique_locale(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {}
52 ~__libcpp_unique_locale() {
57 explicit operator bool() const { return __loc_; }
59 locale_t& get() { return __loc_; }
63 __libcpp_unique_locale(__libcpp_unique_locale const&);
64 __libcpp_unique_locale& operator=(__libcpp_unique_locale const&);
69 // In theory this could create a race condition. In practice
70 // the race condition is non-fatal since it will just create
71 // a little resource leak. Better approach would be appreciated.
72 static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
75 #endif // __cloc_defined
81 void operator()(locale::facet* p) {p->__release_shared();}
84 template <class T, class A0>
89 static typename aligned_storage<sizeof(T)>::type buf;
90 auto *obj = ::new (&buf) T(a0);
94 template <class T, class A0, class A1>
99 static typename aligned_storage<sizeof(T)>::type buf;
100 ::new (&buf) T(a0, a1);
101 return *reinterpret_cast<T*>(&buf);
104 template <class T, class A0, class A1, class A2>
107 make(A0 a0, A1 a1, A2 a2)
109 static typename aligned_storage<sizeof(T)>::type buf;
110 auto *obj = ::new (&buf) T(a0, a1, a2);
114 template <typename T, size_t N>
118 countof(const T (&)[N])
123 template <typename T>
127 countof(const T * const begin, const T * const end)
129 return static_cast<size_t>(end - begin);
132 _LIBCPP_NORETURN static void __throw_runtime_error(const string &msg)
134 #ifndef _LIBCPP_NO_EXCEPTIONS
135 throw runtime_error(msg);
145 // Set priority to INT_MIN + 256 + 150
146 # pragma priority ( -2147483242 )
149 const locale::category locale::none;
150 const locale::category locale::collate;
151 const locale::category locale::ctype;
152 const locale::category locale::monetary;
153 const locale::category locale::numeric;
154 const locale::category locale::time;
155 const locale::category locale::messages;
156 const locale::category locale::all;
158 class _LIBCPP_HIDDEN locale::__imp
162 #if defined(_LIBCPP_COMPILER_MSVC)
163 // FIXME: MSVC doesn't support aligned parameters by value.
164 // I can't get the __sso_allocator to work here
165 // for MSVC I think for this reason.
166 vector<facet*> facets_;
168 vector<facet*, __sso_allocator<facet*, N> > facets_;
172 explicit __imp(size_t refs = 0);
173 explicit __imp(const string& name, size_t refs = 0);
175 __imp(const __imp&, const string&, locale::category c);
176 __imp(const __imp& other, const __imp& one, locale::category c);
177 __imp(const __imp&, facet* f, long id);
180 const string& name() const {return name_;}
181 bool has_facet(long id) const
182 {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
183 const locale::facet* use_facet(long id) const;
185 static const locale& make_classic();
186 static locale& make_global();
188 void install(facet* f, long id);
189 template <class F> void install(F* f) {install(f, f->id.__get());}
190 template <class F> void install_from(const __imp& other);
193 locale::__imp::__imp(size_t refs)
199 install(&make<_VSTD::collate<char> >(1u));
200 install(&make<_VSTD::collate<wchar_t> >(1u));
201 install(&make<_VSTD::ctype<char> >(nullptr, false, 1u));
202 install(&make<_VSTD::ctype<wchar_t> >(1u));
203 install(&make<codecvt<char, char, mbstate_t> >(1u));
204 install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
205 install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
206 install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
207 install(&make<numpunct<char> >(1u));
208 install(&make<numpunct<wchar_t> >(1u));
209 install(&make<num_get<char> >(1u));
210 install(&make<num_get<wchar_t> >(1u));
211 install(&make<num_put<char> >(1u));
212 install(&make<num_put<wchar_t> >(1u));
213 install(&make<moneypunct<char, false> >(1u));
214 install(&make<moneypunct<char, true> >(1u));
215 install(&make<moneypunct<wchar_t, false> >(1u));
216 install(&make<moneypunct<wchar_t, true> >(1u));
217 install(&make<money_get<char> >(1u));
218 install(&make<money_get<wchar_t> >(1u));
219 install(&make<money_put<char> >(1u));
220 install(&make<money_put<wchar_t> >(1u));
221 install(&make<time_get<char> >(1u));
222 install(&make<time_get<wchar_t> >(1u));
223 install(&make<time_put<char> >(1u));
224 install(&make<time_put<wchar_t> >(1u));
225 install(&make<_VSTD::messages<char> >(1u));
226 install(&make<_VSTD::messages<wchar_t> >(1u));
229 locale::__imp::__imp(const string& name, size_t refs)
234 #ifndef _LIBCPP_NO_EXCEPTIONS
237 #endif // _LIBCPP_NO_EXCEPTIONS
238 facets_ = locale::classic().__locale_->facets_;
239 for (unsigned i = 0; i < facets_.size(); ++i)
241 facets_[i]->__add_shared();
242 install(new collate_byname<char>(name_));
243 install(new collate_byname<wchar_t>(name_));
244 install(new ctype_byname<char>(name_));
245 install(new ctype_byname<wchar_t>(name_));
246 install(new codecvt_byname<char, char, mbstate_t>(name_));
247 install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
248 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
249 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
250 install(new numpunct_byname<char>(name_));
251 install(new numpunct_byname<wchar_t>(name_));
252 install(new moneypunct_byname<char, false>(name_));
253 install(new moneypunct_byname<char, true>(name_));
254 install(new moneypunct_byname<wchar_t, false>(name_));
255 install(new moneypunct_byname<wchar_t, true>(name_));
256 install(new time_get_byname<char>(name_));
257 install(new time_get_byname<wchar_t>(name_));
258 install(new time_put_byname<char>(name_));
259 install(new time_put_byname<wchar_t>(name_));
260 install(new messages_byname<char>(name_));
261 install(new messages_byname<wchar_t>(name_));
262 #ifndef _LIBCPP_NO_EXCEPTIONS
266 for (unsigned i = 0; i < facets_.size(); ++i)
268 facets_[i]->__release_shared();
271 #endif // _LIBCPP_NO_EXCEPTIONS
274 // NOTE avoid the `base class should be explicitly initialized in the
275 // copy constructor` warning emitted by GCC
276 #if defined(__clang__) || _GNUC_VER >= 406
277 #pragma GCC diagnostic push
278 #pragma GCC diagnostic ignored "-Wextra"
281 locale::__imp::__imp(const __imp& other)
282 : facets_(max<size_t>(N, other.facets_.size())),
285 facets_ = other.facets_;
286 for (unsigned i = 0; i < facets_.size(); ++i)
288 facets_[i]->__add_shared();
291 #if defined(__clang__) || _GNUC_VER >= 406
292 #pragma GCC diagnostic pop
295 locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
299 facets_ = other.facets_;
300 for (unsigned i = 0; i < facets_.size(); ++i)
302 facets_[i]->__add_shared();
303 #ifndef _LIBCPP_NO_EXCEPTIONS
306 #endif // _LIBCPP_NO_EXCEPTIONS
307 if (c & locale::collate)
309 install(new collate_byname<char>(name));
310 install(new collate_byname<wchar_t>(name));
312 if (c & locale::ctype)
314 install(new ctype_byname<char>(name));
315 install(new ctype_byname<wchar_t>(name));
316 install(new codecvt_byname<char, char, mbstate_t>(name));
317 install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
318 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
319 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
321 if (c & locale::monetary)
323 install(new moneypunct_byname<char, false>(name));
324 install(new moneypunct_byname<char, true>(name));
325 install(new moneypunct_byname<wchar_t, false>(name));
326 install(new moneypunct_byname<wchar_t, true>(name));
328 if (c & locale::numeric)
330 install(new numpunct_byname<char>(name));
331 install(new numpunct_byname<wchar_t>(name));
333 if (c & locale::time)
335 install(new time_get_byname<char>(name));
336 install(new time_get_byname<wchar_t>(name));
337 install(new time_put_byname<char>(name));
338 install(new time_put_byname<wchar_t>(name));
340 if (c & locale::messages)
342 install(new messages_byname<char>(name));
343 install(new messages_byname<wchar_t>(name));
345 #ifndef _LIBCPP_NO_EXCEPTIONS
349 for (unsigned i = 0; i < facets_.size(); ++i)
351 facets_[i]->__release_shared();
354 #endif // _LIBCPP_NO_EXCEPTIONS
360 locale::__imp::install_from(const locale::__imp& one)
362 long id = F::id.__get();
363 install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
366 locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
370 facets_ = other.facets_;
371 for (unsigned i = 0; i < facets_.size(); ++i)
373 facets_[i]->__add_shared();
374 #ifndef _LIBCPP_NO_EXCEPTIONS
377 #endif // _LIBCPP_NO_EXCEPTIONS
378 if (c & locale::collate)
380 install_from<_VSTD::collate<char> >(one);
381 install_from<_VSTD::collate<wchar_t> >(one);
383 if (c & locale::ctype)
385 install_from<_VSTD::ctype<char> >(one);
386 install_from<_VSTD::ctype<wchar_t> >(one);
387 install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
388 install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
389 install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
390 install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
392 if (c & locale::monetary)
394 install_from<moneypunct<char, false> >(one);
395 install_from<moneypunct<char, true> >(one);
396 install_from<moneypunct<wchar_t, false> >(one);
397 install_from<moneypunct<wchar_t, true> >(one);
398 install_from<money_get<char> >(one);
399 install_from<money_get<wchar_t> >(one);
400 install_from<money_put<char> >(one);
401 install_from<money_put<wchar_t> >(one);
403 if (c & locale::numeric)
405 install_from<numpunct<char> >(one);
406 install_from<numpunct<wchar_t> >(one);
407 install_from<num_get<char> >(one);
408 install_from<num_get<wchar_t> >(one);
409 install_from<num_put<char> >(one);
410 install_from<num_put<wchar_t> >(one);
412 if (c & locale::time)
414 install_from<time_get<char> >(one);
415 install_from<time_get<wchar_t> >(one);
416 install_from<time_put<char> >(one);
417 install_from<time_put<wchar_t> >(one);
419 if (c & locale::messages)
421 install_from<_VSTD::messages<char> >(one);
422 install_from<_VSTD::messages<wchar_t> >(one);
424 #ifndef _LIBCPP_NO_EXCEPTIONS
428 for (unsigned i = 0; i < facets_.size(); ++i)
430 facets_[i]->__release_shared();
433 #endif // _LIBCPP_NO_EXCEPTIONS
436 locale::__imp::__imp(const __imp& other, facet* f, long id)
437 : facets_(max<size_t>(N, other.facets_.size()+1)),
441 unique_ptr<facet, release> hold(f);
442 facets_ = other.facets_;
443 for (unsigned i = 0; i < other.facets_.size(); ++i)
445 facets_[i]->__add_shared();
446 install(hold.get(), id);
449 locale::__imp::~__imp()
451 for (unsigned i = 0; i < facets_.size(); ++i)
453 facets_[i]->__release_shared();
457 locale::__imp::install(facet* f, long id)
460 unique_ptr<facet, release> hold(f);
461 if (static_cast<size_t>(id) >= facets_.size())
462 facets_.resize(static_cast<size_t>(id+1));
463 if (facets_[static_cast<size_t>(id)])
464 facets_[static_cast<size_t>(id)]->__release_shared();
465 facets_[static_cast<size_t>(id)] = hold.release();
469 locale::__imp::use_facet(long id) const
473 return facets_[static_cast<size_t>(id)];
479 locale::__imp::make_classic()
481 // only one thread can get in here and it only gets in once
482 static aligned_storage<sizeof(locale)>::type buf;
483 locale* c = reinterpret_cast<locale*>(&buf);
484 c->__locale_ = &make<__imp>(1u);
491 static const locale& c = __imp::make_classic();
496 locale::__imp::make_global()
498 // only one thread can get in here and it only gets in once
499 static aligned_storage<sizeof(locale)>::type buf;
500 auto *obj = ::new (&buf) locale(locale::classic());
507 static locale& g = __imp::make_global();
511 locale::locale() _NOEXCEPT
512 : __locale_(__global().__locale_)
514 __locale_->__add_shared();
517 locale::locale(const locale& l) _NOEXCEPT
518 : __locale_(l.__locale_)
520 __locale_->__add_shared();
525 __locale_->__release_shared();
529 locale::operator=(const locale& other) _NOEXCEPT
531 other.__locale_->__add_shared();
532 __locale_->__release_shared();
533 __locale_ = other.__locale_;
537 locale::locale(const char* name)
538 : __locale_(name ? new __imp(name)
539 : (__throw_runtime_error("locale constructed with null"), (__imp*)0))
541 __locale_->__add_shared();
544 locale::locale(const string& name)
545 : __locale_(new __imp(name))
547 __locale_->__add_shared();
550 locale::locale(const locale& other, const char* name, category c)
551 : __locale_(name ? new __imp(*other.__locale_, name, c)
552 : (__throw_runtime_error("locale constructed with null"), (__imp*)0))
554 __locale_->__add_shared();
557 locale::locale(const locale& other, const string& name, category c)
558 : __locale_(new __imp(*other.__locale_, name, c))
560 __locale_->__add_shared();
563 locale::locale(const locale& other, const locale& one, category c)
564 : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
566 __locale_->__add_shared();
572 return __locale_->name();
576 locale::__install_ctor(const locale& other, facet* f, long id)
579 __locale_ = new __imp(*other.__locale_, f, id);
581 __locale_ = other.__locale_;
582 __locale_->__add_shared();
586 locale::global(const locale& loc)
588 locale& g = __global();
592 setlocale(LC_ALL, g.name().c_str());
597 locale::has_facet(id& x) const
599 return __locale_->has_facet(x.__get());
603 locale::use_facet(id& x) const
605 return __locale_->use_facet(x.__get());
609 locale::operator==(const locale& y) const
611 return (__locale_ == y.__locale_)
612 || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
617 locale::facet::~facet()
622 locale::facet::__on_zero_shared() _NOEXCEPT
629 int32_t locale::id::__next_id = 0;
637 void (locale::id::* pmf_)();
639 __fake_bind(void (locale::id::* pmf)(), locale::id* id)
640 : id_(id), pmf_(pmf) {}
642 void operator()() const
653 call_once(__flag_, __fake_bind(&locale::id::__init, this));
660 __id_ = __libcpp_atomic_add(&__next_id, 1);
663 // template <> class collate_byname<char>
665 collate_byname<char>::collate_byname(const char* n, size_t refs)
666 : collate<char>(refs),
667 __l(newlocale(LC_ALL_MASK, n, 0))
670 __throw_runtime_error("collate_byname<char>::collate_byname"
671 " failed to construct for " + string(n));
674 collate_byname<char>::collate_byname(const string& name, size_t refs)
675 : collate<char>(refs),
676 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
679 __throw_runtime_error("collate_byname<char>::collate_byname"
680 " failed to construct for " + name);
683 collate_byname<char>::~collate_byname()
689 collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
690 const char_type* __lo2, const char_type* __hi2) const
692 string_type lhs(__lo1, __hi1);
693 string_type rhs(__lo2, __hi2);
694 int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l);
702 collate_byname<char>::string_type
703 collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
705 const string_type in(lo, hi);
706 string_type out(strxfrm_l(0, in.c_str(), 0, __l), char());
707 strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l);
711 // template <> class collate_byname<wchar_t>
713 collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
714 : collate<wchar_t>(refs),
715 __l(newlocale(LC_ALL_MASK, n, 0))
718 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
719 " failed to construct for " + string(n));
722 collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
723 : collate<wchar_t>(refs),
724 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
727 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
728 " failed to construct for " + name);
731 collate_byname<wchar_t>::~collate_byname()
737 collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
738 const char_type* __lo2, const char_type* __hi2) const
740 string_type lhs(__lo1, __hi1);
741 string_type rhs(__lo2, __hi2);
742 int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l);
750 collate_byname<wchar_t>::string_type
751 collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
753 const string_type in(lo, hi);
754 string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t());
755 wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l);
759 // template <> class ctype<wchar_t>;
761 const ctype_base::mask ctype_base::space;
762 const ctype_base::mask ctype_base::print;
763 const ctype_base::mask ctype_base::cntrl;
764 const ctype_base::mask ctype_base::upper;
765 const ctype_base::mask ctype_base::lower;
766 const ctype_base::mask ctype_base::alpha;
767 const ctype_base::mask ctype_base::digit;
768 const ctype_base::mask ctype_base::punct;
769 const ctype_base::mask ctype_base::xdigit;
770 const ctype_base::mask ctype_base::blank;
771 const ctype_base::mask ctype_base::alnum;
772 const ctype_base::mask ctype_base::graph;
774 locale::id ctype<wchar_t>::id;
776 ctype<wchar_t>::~ctype()
781 ctype<wchar_t>::do_is(mask m, char_type c) const
783 return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
787 ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
789 for (; low != high; ++low, ++vec)
790 *vec = static_cast<mask>(isascii(*low) ?
791 ctype<char>::classic_table()[*low] : 0);
796 ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
798 for (; low != high; ++low)
799 if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
805 ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
807 for (; low != high; ++low)
808 if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
814 ctype<wchar_t>::do_toupper(char_type c) const
816 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
817 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
818 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
820 return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
822 return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;
827 ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
829 for (; low != high; ++low)
830 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
831 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
832 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
834 *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
837 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low;
843 ctype<wchar_t>::do_tolower(char_type c) const
845 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
846 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
847 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
849 return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
851 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;
856 ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
858 for (; low != high; ++low)
859 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
860 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
861 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
863 *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
866 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low;
872 ctype<wchar_t>::do_widen(char c) const
878 ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
880 for (; low != high; ++low, ++dest)
886 ctype<wchar_t>::do_narrow(char_type c, char dfault) const
889 return static_cast<char>(c);
894 ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
896 for (; low != high; ++low, ++dest)
898 *dest = static_cast<char>(*low);
904 // template <> class ctype<char>;
906 locale::id ctype<char>::id;
908 ctype<char>::ctype(const mask* tab, bool del, size_t refs)
909 : locale::facet(refs),
914 __tab_ = classic_table();
917 ctype<char>::~ctype()
919 if (__tab_ && __del_)
924 ctype<char>::do_toupper(char_type c) const
926 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
928 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
929 #elif defined(__NetBSD__)
930 return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
931 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
933 static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
935 return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;
940 ctype<char>::do_toupper(char_type* low, const char_type* high) const
942 for (; low != high; ++low)
943 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
944 *low = isascii(*low) ?
945 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
946 #elif defined(__NetBSD__)
947 *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
948 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
949 *low = isascii(*low) ?
950 static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
952 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low;
958 ctype<char>::do_tolower(char_type c) const
960 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
962 static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
963 #elif defined(__NetBSD__)
964 return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
965 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
967 static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
969 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c;
974 ctype<char>::do_tolower(char_type* low, const char_type* high) const
976 for (; low != high; ++low)
977 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
978 *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
979 #elif defined(__NetBSD__)
980 *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
981 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
982 *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
984 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low;
990 ctype<char>::do_widen(char c) const
996 ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
998 for (; low != high; ++low, ++dest)
1004 ctype<char>::do_narrow(char_type c, char dfault) const
1007 return static_cast<char>(c);
1012 ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1014 for (; low != high; ++low, ++dest)
1022 #if defined(__EMSCRIPTEN__)
1023 extern "C" const unsigned short ** __ctype_b_loc();
1024 extern "C" const int ** __ctype_tolower_loc();
1025 extern "C" const int ** __ctype_toupper_loc();
1028 #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
1029 const ctype<char>::mask*
1030 ctype<char>::classic_table() _NOEXCEPT
1032 static _LIBCPP_CONSTEXPR const ctype<char>::mask builtin_table[table_size] = {
1037 cntrl, cntrl | space | blank,
1038 cntrl | space, cntrl | space,
1039 cntrl | space, cntrl | space,
1049 space | blank | print, punct | print,
1050 punct | print, punct | print,
1051 punct | print, punct | print,
1052 punct | print, punct | print,
1053 punct | print, punct | print,
1054 punct | print, punct | print,
1055 punct | print, punct | print,
1056 punct | print, punct | print,
1057 digit | print | xdigit, digit | print | xdigit,
1058 digit | print | xdigit, digit | print | xdigit,
1059 digit | print | xdigit, digit | print | xdigit,
1060 digit | print | xdigit, digit | print | xdigit,
1061 digit | print | xdigit, digit | print | xdigit,
1062 punct | print, punct | print,
1063 punct | print, punct | print,
1064 punct | print, punct | print,
1065 punct | print, upper | xdigit | print | alpha,
1066 upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1067 upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1068 upper | xdigit | print | alpha, upper | print | alpha,
1069 upper | print | alpha, upper | print | alpha,
1070 upper | print | alpha, upper | print | alpha,
1071 upper | print | alpha, upper | print | alpha,
1072 upper | print | alpha, upper | print | alpha,
1073 upper | print | alpha, upper | print | alpha,
1074 upper | print | alpha, upper | print | alpha,
1075 upper | print | alpha, upper | print | alpha,
1076 upper | print | alpha, upper | print | alpha,
1077 upper | print | alpha, upper | print | alpha,
1078 upper | print | alpha, punct | print,
1079 punct | print, punct | print,
1080 punct | print, punct | print,
1081 punct | print, lower | xdigit | print | alpha,
1082 lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1083 lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1084 lower | xdigit | print | alpha, lower | print | alpha,
1085 lower | print | alpha, lower | print | alpha,
1086 lower | print | alpha, lower | print | alpha,
1087 lower | print | alpha, lower | print | alpha,
1088 lower | print | alpha, lower | print | alpha,
1089 lower | print | alpha, lower | print | alpha,
1090 lower | print | alpha, lower | print | alpha,
1091 lower | print | alpha, lower | print | alpha,
1092 lower | print | alpha, lower | print | alpha,
1093 lower | print | alpha, lower | print | alpha,
1094 lower | print | alpha, punct | print,
1095 punct | print, punct | print,
1096 punct | print, cntrl,
1097 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1098 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1099 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1100 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1106 return builtin_table;
1109 const ctype<char>::mask*
1110 ctype<char>::classic_table() _NOEXCEPT
1112 #if defined(__APPLE__) || defined(__FreeBSD__)
1113 return _DefaultRuneLocale.__runetype;
1114 #elif defined(__NetBSD__)
1115 return _C_ctype_tab_ + 1;
1116 #elif defined(__GLIBC__)
1117 return _LIBCPP_GET_C_LOCALE->__ctype_b;
1119 return __ctype_mask;
1120 #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
1121 return __pctype_func();
1122 #elif defined(__EMSCRIPTEN__)
1123 return *__ctype_b_loc();
1124 #elif defined(_NEWLIB_VERSION)
1125 // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
1128 return (const unsigned int *)__lc_ctype_ptr->obj->mask;
1130 // Platform not supported: abort so the person doing the port knows what to
1132 # warning ctype<char>::classic_table() is not implemented
1133 printf("ctype<char>::classic_table() is not implemented\n");
1140 #if defined(__GLIBC__)
1142 ctype<char>::__classic_lower_table() _NOEXCEPT
1144 return _LIBCPP_GET_C_LOCALE->__ctype_tolower;
1148 ctype<char>::__classic_upper_table() _NOEXCEPT
1150 return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
1154 ctype<char>::__classic_lower_table() _NOEXCEPT
1156 return _C_tolower_tab_ + 1;
1160 ctype<char>::__classic_upper_table() _NOEXCEPT
1162 return _C_toupper_tab_ + 1;
1165 #elif defined(__EMSCRIPTEN__)
1167 ctype<char>::__classic_lower_table() _NOEXCEPT
1169 return *__ctype_tolower_loc();
1173 ctype<char>::__classic_upper_table() _NOEXCEPT
1175 return *__ctype_toupper_loc();
1177 #endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__
1179 // template <> class ctype_byname<char>
1181 ctype_byname<char>::ctype_byname(const char* name, size_t refs)
1182 : ctype<char>(0, false, refs),
1183 __l(newlocale(LC_ALL_MASK, name, 0))
1186 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1187 " failed to construct for " + string(name));
1190 ctype_byname<char>::ctype_byname(const string& name, size_t refs)
1191 : ctype<char>(0, false, refs),
1192 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1195 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1196 " failed to construct for " + name);
1199 ctype_byname<char>::~ctype_byname()
1205 ctype_byname<char>::do_toupper(char_type c) const
1207 return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l));
1211 ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
1213 for (; low != high; ++low)
1214 *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l));
1219 ctype_byname<char>::do_tolower(char_type c) const
1221 return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l));
1225 ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
1227 for (; low != high; ++low)
1228 *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l));
1232 // template <> class ctype_byname<wchar_t>
1234 ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
1235 : ctype<wchar_t>(refs),
1236 __l(newlocale(LC_ALL_MASK, name, 0))
1239 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1240 " failed to construct for " + string(name));
1243 ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
1244 : ctype<wchar_t>(refs),
1245 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1248 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1249 " failed to construct for " + name);
1252 ctype_byname<wchar_t>::~ctype_byname()
1258 ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1260 #ifdef _LIBCPP_WCTYPE_IS_MASK
1261 return static_cast<bool>(iswctype_l(c, m, __l));
1263 bool result = false;
1264 wint_t ch = static_cast<wint_t>(c);
1265 if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0);
1266 if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0);
1267 if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0);
1268 if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0);
1269 if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0);
1270 if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0);
1271 if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0);
1272 if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0);
1273 if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0);
1274 if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0);
1280 ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1282 for (; low != high; ++low, ++vec)
1285 *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
1289 wint_t ch = static_cast<wint_t>(*low);
1290 if (iswspace_l(ch, __l))
1292 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
1293 if (iswprint_l(ch, __l))
1296 if (iswcntrl_l(ch, __l))
1298 if (iswupper_l(ch, __l))
1300 if (iswlower_l(ch, __l))
1302 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
1303 if (iswalpha_l(ch, __l))
1306 if (iswdigit_l(ch, __l))
1308 if (iswpunct_l(ch, __l))
1310 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
1311 if (iswxdigit_l(ch, __l))
1314 #if !defined(__sun__)
1315 if (iswblank_l(ch, __l))
1324 ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1326 for (; low != high; ++low)
1328 #ifdef _LIBCPP_WCTYPE_IS_MASK
1329 if (iswctype_l(*low, m, __l))
1332 wint_t ch = static_cast<wint_t>(*low);
1333 if ((m & space) == space && iswspace_l(ch, __l)) break;
1334 if ((m & print) == print && iswprint_l(ch, __l)) break;
1335 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break;
1336 if ((m & upper) == upper && iswupper_l(ch, __l)) break;
1337 if ((m & lower) == lower && iswlower_l(ch, __l)) break;
1338 if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break;
1339 if ((m & digit) == digit && iswdigit_l(ch, __l)) break;
1340 if ((m & punct) == punct && iswpunct_l(ch, __l)) break;
1341 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break;
1342 if ((m & blank) == blank && iswblank_l(ch, __l)) break;
1349 ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1351 for (; low != high; ++low)
1353 #ifdef _LIBCPP_WCTYPE_IS_MASK
1354 if (!iswctype_l(*low, m, __l))
1357 wint_t ch = static_cast<wint_t>(*low);
1358 if ((m & space) == space && iswspace_l(ch, __l)) continue;
1359 if ((m & print) == print && iswprint_l(ch, __l)) continue;
1360 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue;
1361 if ((m & upper) == upper && iswupper_l(ch, __l)) continue;
1362 if ((m & lower) == lower && iswlower_l(ch, __l)) continue;
1363 if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue;
1364 if ((m & digit) == digit && iswdigit_l(ch, __l)) continue;
1365 if ((m & punct) == punct && iswpunct_l(ch, __l)) continue;
1366 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue;
1367 if ((m & blank) == blank && iswblank_l(ch, __l)) continue;
1375 ctype_byname<wchar_t>::do_toupper(char_type c) const
1377 return towupper_l(c, __l);
1381 ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1383 for (; low != high; ++low)
1384 *low = towupper_l(*low, __l);
1389 ctype_byname<wchar_t>::do_tolower(char_type c) const
1391 return towlower_l(c, __l);
1395 ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1397 for (; low != high; ++low)
1398 *low = towlower_l(*low, __l);
1403 ctype_byname<wchar_t>::do_widen(char c) const
1405 return __libcpp_btowc_l(c, __l);
1409 ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1411 for (; low != high; ++low, ++dest)
1412 *dest = __libcpp_btowc_l(*low, __l);
1417 ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1419 int r = __libcpp_wctob_l(c, __l);
1420 return r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
1424 ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1426 for (; low != high; ++low, ++dest)
1428 int r = __libcpp_wctob_l(*low, __l);
1429 *dest = r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
1434 // template <> class codecvt<char, char, mbstate_t>
1436 locale::id codecvt<char, char, mbstate_t>::id;
1438 codecvt<char, char, mbstate_t>::~codecvt()
1442 codecvt<char, char, mbstate_t>::result
1443 codecvt<char, char, mbstate_t>::do_out(state_type&,
1444 const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
1445 extern_type* to, extern_type*, extern_type*& to_nxt) const
1452 codecvt<char, char, mbstate_t>::result
1453 codecvt<char, char, mbstate_t>::do_in(state_type&,
1454 const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
1455 intern_type* to, intern_type*, intern_type*& to_nxt) const
1462 codecvt<char, char, mbstate_t>::result
1463 codecvt<char, char, mbstate_t>::do_unshift(state_type&,
1464 extern_type* to, extern_type*, extern_type*& to_nxt) const
1471 codecvt<char, char, mbstate_t>::do_encoding() const _NOEXCEPT
1477 codecvt<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
1483 codecvt<char, char, mbstate_t>::do_length(state_type&,
1484 const extern_type* frm, const extern_type* end, size_t mx) const
1486 return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
1490 codecvt<char, char, mbstate_t>::do_max_length() const _NOEXCEPT
1495 // template <> class codecvt<wchar_t, char, mbstate_t>
1497 locale::id codecvt<wchar_t, char, mbstate_t>::id;
1499 codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1500 : locale::facet(refs),
1501 __l(_LIBCPP_GET_C_LOCALE)
1505 codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1506 : locale::facet(refs),
1507 __l(newlocale(LC_ALL_MASK, nm, 0))
1510 __throw_runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1511 " failed to construct for " + string(nm));
1514 codecvt<wchar_t, char, mbstate_t>::~codecvt()
1516 if (__l != _LIBCPP_GET_C_LOCALE)
1520 codecvt<wchar_t, char, mbstate_t>::result
1521 codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
1522 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
1523 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1525 // look for first internal null in frm
1526 const intern_type* fend = frm;
1527 for (; fend != frm_end; ++fend)
1530 // loop over all null-terminated sequences in frm
1532 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1534 // save state in case it is needed to recover to_nxt on error
1535 mbstate_t save_state = st;
1536 size_t n = __libcpp_wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1537 static_cast<size_t>(to_end-to), &st, __l);
1538 if (n == size_t(-1))
1540 // need to recover to_nxt
1541 for (to_nxt = to; frm != frm_nxt; ++frm)
1543 n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l);
1544 if (n == size_t(-1))
1554 if (to_nxt == to_end)
1556 if (fend != frm_end) // set up next null terminated sequence
1558 // Try to write the terminating null
1559 extern_type tmp[MB_LEN_MAX];
1560 n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l);
1561 if (n == size_t(-1)) // on error
1563 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1565 for (extern_type* p = tmp; n; --n) // write it
1568 // look for next null in frm
1569 for (fend = frm_nxt; fend != frm_end; ++fend)
1574 return frm_nxt == frm_end ? ok : partial;
1577 codecvt<wchar_t, char, mbstate_t>::result
1578 codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
1579 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
1580 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1582 // look for first internal null in frm
1583 const extern_type* fend = frm;
1584 for (; fend != frm_end; ++fend)
1587 // loop over all null-terminated sequences in frm
1589 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1591 // save state in case it is needed to recover to_nxt on error
1592 mbstate_t save_state = st;
1593 size_t n = __libcpp_mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1594 static_cast<size_t>(to_end-to), &st, __l);
1595 if (n == size_t(-1))
1597 // need to recover to_nxt
1598 for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1600 n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
1619 return frm_nxt == frm_end ? ok : partial;
1621 if (n == size_t(-1))
1624 if (to_nxt == to_end)
1626 if (fend != frm_end) // set up next null terminated sequence
1628 // Try to write the terminating null
1629 n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1630 if (n != 0) // on error
1634 // look for next null in frm
1635 for (fend = frm_nxt; fend != frm_end; ++fend)
1640 return frm_nxt == frm_end ? ok : partial;
1643 codecvt<wchar_t, char, mbstate_t>::result
1644 codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1645 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1648 extern_type tmp[MB_LEN_MAX];
1649 size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l);
1650 if (n == size_t(-1) || n == 0) // on error
1653 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1655 for (extern_type* p = tmp; n; --n) // write it
1661 codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
1663 if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)
1666 // stateless encoding
1667 if (__l == 0 || __libcpp_mb_cur_max_l(__l) == 1) // there are no known constant length encodings
1668 return 1; // which take more than 1 char to form a wchar_t
1673 codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
1679 codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1680 const extern_type* frm, const extern_type* frm_end, size_t mx) const
1683 for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1685 size_t n = __libcpp_mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l);
1705 codecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
1707 return __l == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l));
1711 // UTF-32 UTF-16 UTF-8 # of code points
1712 // first second first second third fourth
1713 // 000000 - 00007F 0000 - 007F 00 - 7F 127
1714 // 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1715 // 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1716 // 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1717 // 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1718 // 00D800 - 00DFFF invalid
1719 // 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1720 // 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1721 // 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1722 // 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1725 codecvt_base::result
1726 utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1727 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1728 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1732 if (mode & generate_header)
1734 if (to_end-to_nxt < 3)
1735 return codecvt_base::partial;
1736 *to_nxt++ = static_cast<uint8_t>(0xEF);
1737 *to_nxt++ = static_cast<uint8_t>(0xBB);
1738 *to_nxt++ = static_cast<uint8_t>(0xBF);
1740 for (; frm_nxt < frm_end; ++frm_nxt)
1742 uint16_t wc1 = *frm_nxt;
1744 return codecvt_base::error;
1747 if (to_end-to_nxt < 1)
1748 return codecvt_base::partial;
1749 *to_nxt++ = static_cast<uint8_t>(wc1);
1751 else if (wc1 < 0x0800)
1753 if (to_end-to_nxt < 2)
1754 return codecvt_base::partial;
1755 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1756 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1758 else if (wc1 < 0xD800)
1760 if (to_end-to_nxt < 3)
1761 return codecvt_base::partial;
1762 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1763 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1764 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1766 else if (wc1 < 0xDC00)
1768 if (frm_end-frm_nxt < 2)
1769 return codecvt_base::partial;
1770 uint16_t wc2 = frm_nxt[1];
1771 if ((wc2 & 0xFC00) != 0xDC00)
1772 return codecvt_base::error;
1773 if (to_end-to_nxt < 4)
1774 return codecvt_base::partial;
1775 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1776 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1777 return codecvt_base::error;
1779 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1780 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1781 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1782 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1783 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1785 else if (wc1 < 0xE000)
1787 return codecvt_base::error;
1791 if (to_end-to_nxt < 3)
1792 return codecvt_base::partial;
1793 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1794 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1795 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1798 return codecvt_base::ok;
1802 codecvt_base::result
1803 utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1804 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1805 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1809 if (mode & generate_header)
1811 if (to_end-to_nxt < 3)
1812 return codecvt_base::partial;
1813 *to_nxt++ = static_cast<uint8_t>(0xEF);
1814 *to_nxt++ = static_cast<uint8_t>(0xBB);
1815 *to_nxt++ = static_cast<uint8_t>(0xBF);
1817 for (; frm_nxt < frm_end; ++frm_nxt)
1819 uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1821 return codecvt_base::error;
1824 if (to_end-to_nxt < 1)
1825 return codecvt_base::partial;
1826 *to_nxt++ = static_cast<uint8_t>(wc1);
1828 else if (wc1 < 0x0800)
1830 if (to_end-to_nxt < 2)
1831 return codecvt_base::partial;
1832 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1833 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1835 else if (wc1 < 0xD800)
1837 if (to_end-to_nxt < 3)
1838 return codecvt_base::partial;
1839 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1840 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1841 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1843 else if (wc1 < 0xDC00)
1845 if (frm_end-frm_nxt < 2)
1846 return codecvt_base::partial;
1847 uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1848 if ((wc2 & 0xFC00) != 0xDC00)
1849 return codecvt_base::error;
1850 if (to_end-to_nxt < 4)
1851 return codecvt_base::partial;
1852 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1853 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1854 return codecvt_base::error;
1856 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1857 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1858 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1859 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1860 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1862 else if (wc1 < 0xE000)
1864 return codecvt_base::error;
1868 if (to_end-to_nxt < 3)
1869 return codecvt_base::partial;
1870 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1871 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1872 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1875 return codecvt_base::ok;
1879 codecvt_base::result
1880 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1881 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1882 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1886 if (mode & consume_header)
1888 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1892 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1894 uint8_t c1 = *frm_nxt;
1896 return codecvt_base::error;
1899 *to_nxt = static_cast<uint16_t>(c1);
1904 return codecvt_base::error;
1908 if (frm_end-frm_nxt < 2)
1909 return codecvt_base::partial;
1910 uint8_t c2 = frm_nxt[1];
1911 if ((c2 & 0xC0) != 0x80)
1912 return codecvt_base::error;
1913 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1915 return codecvt_base::error;
1921 if (frm_end-frm_nxt < 3)
1922 return codecvt_base::partial;
1923 uint8_t c2 = frm_nxt[1];
1924 uint8_t c3 = frm_nxt[2];
1928 if ((c2 & 0xE0) != 0xA0)
1929 return codecvt_base::error;
1932 if ((c2 & 0xE0) != 0x80)
1933 return codecvt_base::error;
1936 if ((c2 & 0xC0) != 0x80)
1937 return codecvt_base::error;
1940 if ((c3 & 0xC0) != 0x80)
1941 return codecvt_base::error;
1942 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1943 | ((c2 & 0x3F) << 6)
1946 return codecvt_base::error;
1952 if (frm_end-frm_nxt < 4)
1953 return codecvt_base::partial;
1954 uint8_t c2 = frm_nxt[1];
1955 uint8_t c3 = frm_nxt[2];
1956 uint8_t c4 = frm_nxt[3];
1960 if (!(0x90 <= c2 && c2 <= 0xBF))
1961 return codecvt_base::error;
1964 if ((c2 & 0xF0) != 0x80)
1965 return codecvt_base::error;
1968 if ((c2 & 0xC0) != 0x80)
1969 return codecvt_base::error;
1972 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1973 return codecvt_base::error;
1974 if (to_end-to_nxt < 2)
1975 return codecvt_base::partial;
1976 if ((((c1 & 7UL) << 18) +
1977 ((c2 & 0x3FUL) << 12) +
1978 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
1979 return codecvt_base::error;
1980 *to_nxt = static_cast<uint16_t>(
1982 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1983 | ((c2 & 0x0F) << 2)
1984 | ((c3 & 0x30) >> 4));
1985 *++to_nxt = static_cast<uint16_t>(
1987 | ((c3 & 0x0F) << 6)
1993 return codecvt_base::error;
1996 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2000 codecvt_base::result
2001 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2002 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2003 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2007 if (mode & consume_header)
2009 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2013 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2015 uint8_t c1 = *frm_nxt;
2017 return codecvt_base::error;
2020 *to_nxt = static_cast<uint32_t>(c1);
2025 return codecvt_base::error;
2029 if (frm_end-frm_nxt < 2)
2030 return codecvt_base::partial;
2031 uint8_t c2 = frm_nxt[1];
2032 if ((c2 & 0xC0) != 0x80)
2033 return codecvt_base::error;
2034 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2036 return codecvt_base::error;
2037 *to_nxt = static_cast<uint32_t>(t);
2042 if (frm_end-frm_nxt < 3)
2043 return codecvt_base::partial;
2044 uint8_t c2 = frm_nxt[1];
2045 uint8_t c3 = frm_nxt[2];
2049 if ((c2 & 0xE0) != 0xA0)
2050 return codecvt_base::error;
2053 if ((c2 & 0xE0) != 0x80)
2054 return codecvt_base::error;
2057 if ((c2 & 0xC0) != 0x80)
2058 return codecvt_base::error;
2061 if ((c3 & 0xC0) != 0x80)
2062 return codecvt_base::error;
2063 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2064 | ((c2 & 0x3F) << 6)
2067 return codecvt_base::error;
2068 *to_nxt = static_cast<uint32_t>(t);
2073 if (frm_end-frm_nxt < 4)
2074 return codecvt_base::partial;
2075 uint8_t c2 = frm_nxt[1];
2076 uint8_t c3 = frm_nxt[2];
2077 uint8_t c4 = frm_nxt[3];
2081 if (!(0x90 <= c2 && c2 <= 0xBF))
2082 return codecvt_base::error;
2085 if ((c2 & 0xF0) != 0x80)
2086 return codecvt_base::error;
2089 if ((c2 & 0xC0) != 0x80)
2090 return codecvt_base::error;
2093 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2094 return codecvt_base::error;
2095 if (to_end-to_nxt < 2)
2096 return codecvt_base::partial;
2097 if ((((c1 & 7UL) << 18) +
2098 ((c2 & 0x3FUL) << 12) +
2099 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2100 return codecvt_base::error;
2101 *to_nxt = static_cast<uint32_t>(
2103 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2104 | ((c2 & 0x0F) << 2)
2105 | ((c3 & 0x30) >> 4));
2106 *++to_nxt = static_cast<uint32_t>(
2108 | ((c3 & 0x0F) << 6)
2114 return codecvt_base::error;
2117 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2122 utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
2123 size_t mx, unsigned long Maxcode = 0x10FFFF,
2124 codecvt_mode mode = codecvt_mode(0))
2126 const uint8_t* frm_nxt = frm;
2127 if (mode & consume_header)
2129 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2133 for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
2135 uint8_t c1 = *frm_nxt;
2148 if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
2150 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
2157 if (frm_end-frm_nxt < 3)
2159 uint8_t c2 = frm_nxt[1];
2160 uint8_t c3 = frm_nxt[2];
2164 if ((c2 & 0xE0) != 0xA0)
2165 return static_cast<int>(frm_nxt - frm);
2168 if ((c2 & 0xE0) != 0x80)
2169 return static_cast<int>(frm_nxt - frm);
2172 if ((c2 & 0xC0) != 0x80)
2173 return static_cast<int>(frm_nxt - frm);
2176 if ((c3 & 0xC0) != 0x80)
2178 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2184 if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
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 static_cast<int>(frm_nxt - frm);
2196 if ((c2 & 0xF0) != 0x80)
2197 return static_cast<int>(frm_nxt - frm);
2200 if ((c2 & 0xC0) != 0x80)
2201 return static_cast<int>(frm_nxt - frm);
2204 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2206 if ((((c1 & 7UL) << 18) +
2207 ((c2 & 0x3FUL) << 12) +
2208 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2218 return static_cast<int>(frm_nxt - frm);
2222 codecvt_base::result
2223 ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2224 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2225 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2229 if (mode & generate_header)
2231 if (to_end-to_nxt < 3)
2232 return codecvt_base::partial;
2233 *to_nxt++ = static_cast<uint8_t>(0xEF);
2234 *to_nxt++ = static_cast<uint8_t>(0xBB);
2235 *to_nxt++ = static_cast<uint8_t>(0xBF);
2237 for (; frm_nxt < frm_end; ++frm_nxt)
2239 uint32_t wc = *frm_nxt;
2240 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2241 return codecvt_base::error;
2244 if (to_end-to_nxt < 1)
2245 return codecvt_base::partial;
2246 *to_nxt++ = static_cast<uint8_t>(wc);
2248 else if (wc < 0x000800)
2250 if (to_end-to_nxt < 2)
2251 return codecvt_base::partial;
2252 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2253 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2255 else if (wc < 0x010000)
2257 if (to_end-to_nxt < 3)
2258 return codecvt_base::partial;
2259 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2260 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2261 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2263 else // if (wc < 0x110000)
2265 if (to_end-to_nxt < 4)
2266 return codecvt_base::partial;
2267 *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
2268 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2269 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2270 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
2273 return codecvt_base::ok;
2277 codecvt_base::result
2278 utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2279 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2280 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2284 if (mode & consume_header)
2286 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2290 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2292 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2296 return codecvt_base::error;
2297 *to_nxt = static_cast<uint32_t>(c1);
2302 return codecvt_base::error;
2306 if (frm_end-frm_nxt < 2)
2307 return codecvt_base::partial;
2308 uint8_t c2 = frm_nxt[1];
2309 if ((c2 & 0xC0) != 0x80)
2310 return codecvt_base::error;
2311 uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2314 return codecvt_base::error;
2320 if (frm_end-frm_nxt < 3)
2321 return codecvt_base::partial;
2322 uint8_t c2 = frm_nxt[1];
2323 uint8_t c3 = frm_nxt[2];
2327 if ((c2 & 0xE0) != 0xA0)
2328 return codecvt_base::error;
2331 if ((c2 & 0xE0) != 0x80)
2332 return codecvt_base::error;
2335 if ((c2 & 0xC0) != 0x80)
2336 return codecvt_base::error;
2339 if ((c3 & 0xC0) != 0x80)
2340 return codecvt_base::error;
2341 uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2342 | ((c2 & 0x3F) << 6)
2345 return codecvt_base::error;
2351 if (frm_end-frm_nxt < 4)
2352 return codecvt_base::partial;
2353 uint8_t c2 = frm_nxt[1];
2354 uint8_t c3 = frm_nxt[2];
2355 uint8_t c4 = frm_nxt[3];
2359 if (!(0x90 <= c2 && c2 <= 0xBF))
2360 return codecvt_base::error;
2363 if ((c2 & 0xF0) != 0x80)
2364 return codecvt_base::error;
2367 if ((c2 & 0xC0) != 0x80)
2368 return codecvt_base::error;
2371 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2372 return codecvt_base::error;
2373 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2374 | ((c2 & 0x3F) << 12)
2375 | ((c3 & 0x3F) << 6)
2378 return codecvt_base::error;
2384 return codecvt_base::error;
2387 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2392 utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2393 size_t mx, unsigned long Maxcode = 0x10FFFF,
2394 codecvt_mode mode = codecvt_mode(0))
2396 const uint8_t* frm_nxt = frm;
2397 if (mode & consume_header)
2399 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2403 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2405 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2418 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2420 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2426 if (frm_end-frm_nxt < 3)
2428 uint8_t c2 = frm_nxt[1];
2429 uint8_t c3 = frm_nxt[2];
2433 if ((c2 & 0xE0) != 0xA0)
2434 return static_cast<int>(frm_nxt - frm);
2437 if ((c2 & 0xE0) != 0x80)
2438 return static_cast<int>(frm_nxt - frm);
2441 if ((c2 & 0xC0) != 0x80)
2442 return static_cast<int>(frm_nxt - frm);
2445 if ((c3 & 0xC0) != 0x80)
2447 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2453 if (frm_end-frm_nxt < 4)
2455 uint8_t c2 = frm_nxt[1];
2456 uint8_t c3 = frm_nxt[2];
2457 uint8_t c4 = frm_nxt[3];
2461 if (!(0x90 <= c2 && c2 <= 0xBF))
2462 return static_cast<int>(frm_nxt - frm);
2465 if ((c2 & 0xF0) != 0x80)
2466 return static_cast<int>(frm_nxt - frm);
2469 if ((c2 & 0xC0) != 0x80)
2470 return static_cast<int>(frm_nxt - frm);
2473 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2475 if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
2476 ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode)
2485 return static_cast<int>(frm_nxt - frm);
2489 codecvt_base::result
2490 ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2491 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2492 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2496 if (mode & generate_header)
2498 if (to_end-to_nxt < 3)
2499 return codecvt_base::partial;
2500 *to_nxt++ = static_cast<uint8_t>(0xEF);
2501 *to_nxt++ = static_cast<uint8_t>(0xBB);
2502 *to_nxt++ = static_cast<uint8_t>(0xBF);
2504 for (; frm_nxt < frm_end; ++frm_nxt)
2506 uint16_t wc = *frm_nxt;
2507 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2508 return codecvt_base::error;
2511 if (to_end-to_nxt < 1)
2512 return codecvt_base::partial;
2513 *to_nxt++ = static_cast<uint8_t>(wc);
2515 else if (wc < 0x0800)
2517 if (to_end-to_nxt < 2)
2518 return codecvt_base::partial;
2519 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2520 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2522 else // if (wc <= 0xFFFF)
2524 if (to_end-to_nxt < 3)
2525 return codecvt_base::partial;
2526 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2527 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2528 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2531 return codecvt_base::ok;
2535 codecvt_base::result
2536 utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2537 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2538 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2542 if (mode & consume_header)
2544 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2548 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2550 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2554 return codecvt_base::error;
2555 *to_nxt = static_cast<uint16_t>(c1);
2560 return codecvt_base::error;
2564 if (frm_end-frm_nxt < 2)
2565 return codecvt_base::partial;
2566 uint8_t c2 = frm_nxt[1];
2567 if ((c2 & 0xC0) != 0x80)
2568 return codecvt_base::error;
2569 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2572 return codecvt_base::error;
2578 if (frm_end-frm_nxt < 3)
2579 return codecvt_base::partial;
2580 uint8_t c2 = frm_nxt[1];
2581 uint8_t c3 = frm_nxt[2];
2585 if ((c2 & 0xE0) != 0xA0)
2586 return codecvt_base::error;
2589 if ((c2 & 0xE0) != 0x80)
2590 return codecvt_base::error;
2593 if ((c2 & 0xC0) != 0x80)
2594 return codecvt_base::error;
2597 if ((c3 & 0xC0) != 0x80)
2598 return codecvt_base::error;
2599 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2600 | ((c2 & 0x3F) << 6)
2603 return codecvt_base::error;
2609 return codecvt_base::error;
2612 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2617 utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2618 size_t mx, unsigned long Maxcode = 0x10FFFF,
2619 codecvt_mode mode = codecvt_mode(0))
2621 const uint8_t* frm_nxt = frm;
2622 if (mode & consume_header)
2624 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2628 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2630 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2643 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2645 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2651 if (frm_end-frm_nxt < 3)
2653 uint8_t c2 = frm_nxt[1];
2654 uint8_t c3 = frm_nxt[2];
2658 if ((c2 & 0xE0) != 0xA0)
2659 return static_cast<int>(frm_nxt - frm);
2662 if ((c2 & 0xE0) != 0x80)
2663 return static_cast<int>(frm_nxt - frm);
2666 if ((c2 & 0xC0) != 0x80)
2667 return static_cast<int>(frm_nxt - frm);
2670 if ((c3 & 0xC0) != 0x80)
2672 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2681 return static_cast<int>(frm_nxt - frm);
2685 codecvt_base::result
2686 ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2687 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2688 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2692 if (mode & generate_header)
2694 if (to_end-to_nxt < 2)
2695 return codecvt_base::partial;
2696 *to_nxt++ = static_cast<uint8_t>(0xFE);
2697 *to_nxt++ = static_cast<uint8_t>(0xFF);
2699 for (; frm_nxt < frm_end; ++frm_nxt)
2701 uint32_t wc = *frm_nxt;
2702 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2703 return codecvt_base::error;
2706 if (to_end-to_nxt < 2)
2707 return codecvt_base::partial;
2708 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2709 *to_nxt++ = static_cast<uint8_t>(wc);
2713 if (to_end-to_nxt < 4)
2714 return codecvt_base::partial;
2715 uint16_t t = static_cast<uint16_t>(
2717 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2718 | ((wc & 0x00FC00) >> 10));
2719 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2720 *to_nxt++ = static_cast<uint8_t>(t);
2721 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2722 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2723 *to_nxt++ = static_cast<uint8_t>(t);
2726 return codecvt_base::ok;
2730 codecvt_base::result
2731 utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2732 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2733 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2737 if (mode & consume_header)
2739 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2742 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2744 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2745 if ((c1 & 0xFC00) == 0xDC00)
2746 return codecvt_base::error;
2747 if ((c1 & 0xFC00) != 0xD800)
2750 return codecvt_base::error;
2751 *to_nxt = static_cast<uint32_t>(c1);
2756 if (frm_end-frm_nxt < 4)
2757 return codecvt_base::partial;
2758 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2759 if ((c2 & 0xFC00) != 0xDC00)
2760 return codecvt_base::error;
2761 uint32_t t = static_cast<uint32_t>(
2762 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2763 | ((c1 & 0x003F) << 10)
2766 return codecvt_base::error;
2771 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2776 utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2777 size_t mx, unsigned long Maxcode = 0x10FFFF,
2778 codecvt_mode mode = codecvt_mode(0))
2780 const uint8_t* frm_nxt = frm;
2781 if (mode & consume_header)
2783 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2786 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2788 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2789 if ((c1 & 0xFC00) == 0xDC00)
2791 if ((c1 & 0xFC00) != 0xD800)
2799 if (frm_end-frm_nxt < 4)
2801 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2802 if ((c2 & 0xFC00) != 0xDC00)
2804 uint32_t t = static_cast<uint32_t>(
2805 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2806 | ((c1 & 0x003F) << 10)
2813 return static_cast<int>(frm_nxt - frm);
2817 codecvt_base::result
2818 ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2819 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2820 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2824 if (mode & generate_header)
2826 if (to_end - to_nxt < 2)
2827 return codecvt_base::partial;
2828 *to_nxt++ = static_cast<uint8_t>(0xFF);
2829 *to_nxt++ = static_cast<uint8_t>(0xFE);
2831 for (; frm_nxt < frm_end; ++frm_nxt)
2833 uint32_t wc = *frm_nxt;
2834 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2835 return codecvt_base::error;
2838 if (to_end-to_nxt < 2)
2839 return codecvt_base::partial;
2840 *to_nxt++ = static_cast<uint8_t>(wc);
2841 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2845 if (to_end-to_nxt < 4)
2846 return codecvt_base::partial;
2847 uint16_t t = static_cast<uint16_t>(
2849 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2850 | ((wc & 0x00FC00) >> 10));
2851 *to_nxt++ = static_cast<uint8_t>(t);
2852 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2853 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2854 *to_nxt++ = static_cast<uint8_t>(t);
2855 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2858 return codecvt_base::ok;
2862 codecvt_base::result
2863 utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2864 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2865 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2869 if (mode & consume_header)
2871 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2874 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2876 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2877 if ((c1 & 0xFC00) == 0xDC00)
2878 return codecvt_base::error;
2879 if ((c1 & 0xFC00) != 0xD800)
2882 return codecvt_base::error;
2883 *to_nxt = static_cast<uint32_t>(c1);
2888 if (frm_end-frm_nxt < 4)
2889 return codecvt_base::partial;
2890 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2891 if ((c2 & 0xFC00) != 0xDC00)
2892 return codecvt_base::error;
2893 uint32_t t = static_cast<uint32_t>(
2894 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2895 | ((c1 & 0x003F) << 10)
2898 return codecvt_base::error;
2903 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2908 utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2909 size_t mx, unsigned long Maxcode = 0x10FFFF,
2910 codecvt_mode mode = codecvt_mode(0))
2912 const uint8_t* frm_nxt = frm;
2913 if (mode & consume_header)
2915 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2918 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2920 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2921 if ((c1 & 0xFC00) == 0xDC00)
2923 if ((c1 & 0xFC00) != 0xD800)
2931 if (frm_end-frm_nxt < 4)
2933 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2934 if ((c2 & 0xFC00) != 0xDC00)
2936 uint32_t t = static_cast<uint32_t>(
2937 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2938 | ((c1 & 0x003F) << 10)
2945 return static_cast<int>(frm_nxt - frm);
2949 codecvt_base::result
2950 ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2951 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2952 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2956 if (mode & generate_header)
2958 if (to_end-to_nxt < 2)
2959 return codecvt_base::partial;
2960 *to_nxt++ = static_cast<uint8_t>(0xFE);
2961 *to_nxt++ = static_cast<uint8_t>(0xFF);
2963 for (; frm_nxt < frm_end; ++frm_nxt)
2965 uint16_t wc = *frm_nxt;
2966 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2967 return codecvt_base::error;
2968 if (to_end-to_nxt < 2)
2969 return codecvt_base::partial;
2970 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2971 *to_nxt++ = static_cast<uint8_t>(wc);
2973 return codecvt_base::ok;
2977 codecvt_base::result
2978 utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2979 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2980 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2984 if (mode & consume_header)
2986 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2989 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2991 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2992 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2993 return codecvt_base::error;
2997 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3002 utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3003 size_t mx, unsigned long Maxcode = 0x10FFFF,
3004 codecvt_mode mode = codecvt_mode(0))
3006 const uint8_t* frm_nxt = frm;
3007 if (mode & consume_header)
3009 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3012 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3014 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
3015 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3019 return static_cast<int>(frm_nxt - frm);
3023 codecvt_base::result
3024 ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3025 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3026 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3030 if (mode & generate_header)
3032 if (to_end-to_nxt < 2)
3033 return codecvt_base::partial;
3034 *to_nxt++ = static_cast<uint8_t>(0xFF);
3035 *to_nxt++ = static_cast<uint8_t>(0xFE);
3037 for (; frm_nxt < frm_end; ++frm_nxt)
3039 uint16_t wc = *frm_nxt;
3040 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3041 return codecvt_base::error;
3042 if (to_end-to_nxt < 2)
3043 return codecvt_base::partial;
3044 *to_nxt++ = static_cast<uint8_t>(wc);
3045 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3047 return codecvt_base::ok;
3051 codecvt_base::result
3052 utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3053 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3054 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3058 if (mode & consume_header)
3060 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3063 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3065 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3066 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3067 return codecvt_base::error;
3071 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3076 utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3077 size_t mx, unsigned long Maxcode = 0x10FFFF,
3078 codecvt_mode mode = codecvt_mode(0))
3080 const uint8_t* frm_nxt = frm;
3082 if (mode & consume_header)
3084 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3087 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3089 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3090 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3094 return static_cast<int>(frm_nxt - frm);
3097 // template <> class codecvt<char16_t, char, mbstate_t>
3099 locale::id codecvt<char16_t, char, mbstate_t>::id;
3101 codecvt<char16_t, char, mbstate_t>::~codecvt()
3105 codecvt<char16_t, char, mbstate_t>::result
3106 codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
3107 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3108 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3110 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3111 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3112 const uint16_t* _frm_nxt = _frm;
3113 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3114 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3115 uint8_t* _to_nxt = _to;
3116 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3117 frm_nxt = frm + (_frm_nxt - _frm);
3118 to_nxt = to + (_to_nxt - _to);
3122 codecvt<char16_t, char, mbstate_t>::result
3123 codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
3124 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3125 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3127 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3128 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3129 const uint8_t* _frm_nxt = _frm;
3130 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3131 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3132 uint16_t* _to_nxt = _to;
3133 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3134 frm_nxt = frm + (_frm_nxt - _frm);
3135 to_nxt = to + (_to_nxt - _to);
3139 codecvt<char16_t, char, mbstate_t>::result
3140 codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
3141 extern_type* to, extern_type*, extern_type*& to_nxt) const
3148 codecvt<char16_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
3154 codecvt<char16_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
3160 codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
3161 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3163 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3164 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3165 return utf8_to_utf16_length(_frm, _frm_end, mx);
3169 codecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
3174 // template <> class codecvt<char32_t, char, mbstate_t>
3176 locale::id codecvt<char32_t, char, mbstate_t>::id;
3178 codecvt<char32_t, char, mbstate_t>::~codecvt()
3182 codecvt<char32_t, char, mbstate_t>::result
3183 codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
3184 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3185 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3187 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3188 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3189 const uint32_t* _frm_nxt = _frm;
3190 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3191 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3192 uint8_t* _to_nxt = _to;
3193 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3194 frm_nxt = frm + (_frm_nxt - _frm);
3195 to_nxt = to + (_to_nxt - _to);
3199 codecvt<char32_t, char, mbstate_t>::result
3200 codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
3201 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3202 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3204 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3205 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3206 const uint8_t* _frm_nxt = _frm;
3207 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3208 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3209 uint32_t* _to_nxt = _to;
3210 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3211 frm_nxt = frm + (_frm_nxt - _frm);
3212 to_nxt = to + (_to_nxt - _to);
3216 codecvt<char32_t, char, mbstate_t>::result
3217 codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3218 extern_type* to, extern_type*, extern_type*& to_nxt) const
3225 codecvt<char32_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
3231 codecvt<char32_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
3237 codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3238 const extern_type* frm, const extern_type* frm_end, size_t mx) 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 return utf8_to_ucs4_length(_frm, _frm_end, mx);
3246 codecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
3251 // __codecvt_utf8<wchar_t>
3253 __codecvt_utf8<wchar_t>::result
3254 __codecvt_utf8<wchar_t>::do_out(state_type&,
3255 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3256 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3258 #if defined(_LIBCPP_SHORT_WCHAR)
3259 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3260 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3261 const uint16_t* _frm_nxt = _frm;
3263 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3264 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3265 const uint32_t* _frm_nxt = _frm;
3267 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3268 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3269 uint8_t* _to_nxt = _to;
3270 #if defined(_LIBCPP_SHORT_WCHAR)
3271 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3274 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3277 frm_nxt = frm + (_frm_nxt - _frm);
3278 to_nxt = to + (_to_nxt - _to);
3282 __codecvt_utf8<wchar_t>::result
3283 __codecvt_utf8<wchar_t>::do_in(state_type&,
3284 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3285 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3287 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3288 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3289 const uint8_t* _frm_nxt = _frm;
3290 #if defined(_LIBCPP_SHORT_WCHAR)
3291 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3292 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3293 uint16_t* _to_nxt = _to;
3294 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3297 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3298 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3299 uint32_t* _to_nxt = _to;
3300 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3303 frm_nxt = frm + (_frm_nxt - _frm);
3304 to_nxt = to + (_to_nxt - _to);
3308 __codecvt_utf8<wchar_t>::result
3309 __codecvt_utf8<wchar_t>::do_unshift(state_type&,
3310 extern_type* to, extern_type*, extern_type*& to_nxt) const
3317 __codecvt_utf8<wchar_t>::do_encoding() const _NOEXCEPT
3323 __codecvt_utf8<wchar_t>::do_always_noconv() const _NOEXCEPT
3329 __codecvt_utf8<wchar_t>::do_length(state_type&,
3330 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3332 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3333 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3334 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3338 __codecvt_utf8<wchar_t>::do_max_length() const _NOEXCEPT
3340 if (_Mode_ & consume_header)
3345 // __codecvt_utf8<char16_t>
3347 __codecvt_utf8<char16_t>::result
3348 __codecvt_utf8<char16_t>::do_out(state_type&,
3349 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3350 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3352 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3353 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3354 const uint16_t* _frm_nxt = _frm;
3355 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3356 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3357 uint8_t* _to_nxt = _to;
3358 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3360 frm_nxt = frm + (_frm_nxt - _frm);
3361 to_nxt = to + (_to_nxt - _to);
3365 __codecvt_utf8<char16_t>::result
3366 __codecvt_utf8<char16_t>::do_in(state_type&,
3367 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3368 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3370 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3371 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3372 const uint8_t* _frm_nxt = _frm;
3373 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3374 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3375 uint16_t* _to_nxt = _to;
3376 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3378 frm_nxt = frm + (_frm_nxt - _frm);
3379 to_nxt = to + (_to_nxt - _to);
3383 __codecvt_utf8<char16_t>::result
3384 __codecvt_utf8<char16_t>::do_unshift(state_type&,
3385 extern_type* to, extern_type*, extern_type*& to_nxt) const
3392 __codecvt_utf8<char16_t>::do_encoding() const _NOEXCEPT
3398 __codecvt_utf8<char16_t>::do_always_noconv() const _NOEXCEPT
3404 __codecvt_utf8<char16_t>::do_length(state_type&,
3405 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3407 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3408 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3409 return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3413 __codecvt_utf8<char16_t>::do_max_length() const _NOEXCEPT
3415 if (_Mode_ & consume_header)
3420 // __codecvt_utf8<char32_t>
3422 __codecvt_utf8<char32_t>::result
3423 __codecvt_utf8<char32_t>::do_out(state_type&,
3424 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3425 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3427 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3428 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3429 const uint32_t* _frm_nxt = _frm;
3430 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3431 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3432 uint8_t* _to_nxt = _to;
3433 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3435 frm_nxt = frm + (_frm_nxt - _frm);
3436 to_nxt = to + (_to_nxt - _to);
3440 __codecvt_utf8<char32_t>::result
3441 __codecvt_utf8<char32_t>::do_in(state_type&,
3442 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3443 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3445 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3446 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3447 const uint8_t* _frm_nxt = _frm;
3448 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3449 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3450 uint32_t* _to_nxt = _to;
3451 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3453 frm_nxt = frm + (_frm_nxt - _frm);
3454 to_nxt = to + (_to_nxt - _to);
3458 __codecvt_utf8<char32_t>::result
3459 __codecvt_utf8<char32_t>::do_unshift(state_type&,
3460 extern_type* to, extern_type*, extern_type*& to_nxt) const
3467 __codecvt_utf8<char32_t>::do_encoding() const _NOEXCEPT
3473 __codecvt_utf8<char32_t>::do_always_noconv() const _NOEXCEPT
3479 __codecvt_utf8<char32_t>::do_length(state_type&,
3480 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3482 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3483 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3484 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3488 __codecvt_utf8<char32_t>::do_max_length() const _NOEXCEPT
3490 if (_Mode_ & consume_header)
3495 // __codecvt_utf16<wchar_t, false>
3497 __codecvt_utf16<wchar_t, false>::result
3498 __codecvt_utf16<wchar_t, false>::do_out(state_type&,
3499 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3500 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3502 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3503 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3504 const uint32_t* _frm_nxt = _frm;
3505 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3506 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3507 uint8_t* _to_nxt = _to;
3508 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3510 frm_nxt = frm + (_frm_nxt - _frm);
3511 to_nxt = to + (_to_nxt - _to);
3515 __codecvt_utf16<wchar_t, false>::result
3516 __codecvt_utf16<wchar_t, false>::do_in(state_type&,
3517 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3518 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3520 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3521 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3522 const uint8_t* _frm_nxt = _frm;
3523 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3524 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3525 uint32_t* _to_nxt = _to;
3526 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3528 frm_nxt = frm + (_frm_nxt - _frm);
3529 to_nxt = to + (_to_nxt - _to);
3533 __codecvt_utf16<wchar_t, false>::result
3534 __codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3535 extern_type* to, extern_type*, extern_type*& to_nxt) const
3542 __codecvt_utf16<wchar_t, false>::do_encoding() const _NOEXCEPT
3548 __codecvt_utf16<wchar_t, false>::do_always_noconv() const _NOEXCEPT
3554 __codecvt_utf16<wchar_t, false>::do_length(state_type&,
3555 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3557 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3558 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3559 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3563 __codecvt_utf16<wchar_t, false>::do_max_length() const _NOEXCEPT
3565 if (_Mode_ & consume_header)
3570 // __codecvt_utf16<wchar_t, true>
3572 __codecvt_utf16<wchar_t, true>::result
3573 __codecvt_utf16<wchar_t, true>::do_out(state_type&,
3574 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3575 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3577 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3578 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3579 const uint32_t* _frm_nxt = _frm;
3580 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3581 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3582 uint8_t* _to_nxt = _to;
3583 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3585 frm_nxt = frm + (_frm_nxt - _frm);
3586 to_nxt = to + (_to_nxt - _to);
3590 __codecvt_utf16<wchar_t, true>::result
3591 __codecvt_utf16<wchar_t, true>::do_in(state_type&,
3592 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3593 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3595 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3596 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3597 const uint8_t* _frm_nxt = _frm;
3598 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3599 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3600 uint32_t* _to_nxt = _to;
3601 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3603 frm_nxt = frm + (_frm_nxt - _frm);
3604 to_nxt = to + (_to_nxt - _to);
3608 __codecvt_utf16<wchar_t, true>::result
3609 __codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3610 extern_type* to, extern_type*, extern_type*& to_nxt) const
3617 __codecvt_utf16<wchar_t, true>::do_encoding() const _NOEXCEPT
3623 __codecvt_utf16<wchar_t, true>::do_always_noconv() const _NOEXCEPT
3629 __codecvt_utf16<wchar_t, true>::do_length(state_type&,
3630 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3632 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3633 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3634 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3638 __codecvt_utf16<wchar_t, true>::do_max_length() const _NOEXCEPT
3640 if (_Mode_ & consume_header)
3645 // __codecvt_utf16<char16_t, false>
3647 __codecvt_utf16<char16_t, false>::result
3648 __codecvt_utf16<char16_t, false>::do_out(state_type&,
3649 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3650 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3652 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3653 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3654 const uint16_t* _frm_nxt = _frm;
3655 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3656 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3657 uint8_t* _to_nxt = _to;
3658 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3660 frm_nxt = frm + (_frm_nxt - _frm);
3661 to_nxt = to + (_to_nxt - _to);
3665 __codecvt_utf16<char16_t, false>::result
3666 __codecvt_utf16<char16_t, false>::do_in(state_type&,
3667 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3668 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3670 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3671 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3672 const uint8_t* _frm_nxt = _frm;
3673 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3674 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3675 uint16_t* _to_nxt = _to;
3676 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3678 frm_nxt = frm + (_frm_nxt - _frm);
3679 to_nxt = to + (_to_nxt - _to);
3683 __codecvt_utf16<char16_t, false>::result
3684 __codecvt_utf16<char16_t, false>::do_unshift(state_type&,
3685 extern_type* to, extern_type*, extern_type*& to_nxt) const
3692 __codecvt_utf16<char16_t, false>::do_encoding() const _NOEXCEPT
3698 __codecvt_utf16<char16_t, false>::do_always_noconv() const _NOEXCEPT
3704 __codecvt_utf16<char16_t, false>::do_length(state_type&,
3705 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3707 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3708 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3709 return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3713 __codecvt_utf16<char16_t, false>::do_max_length() const _NOEXCEPT
3715 if (_Mode_ & consume_header)
3720 // __codecvt_utf16<char16_t, true>
3722 __codecvt_utf16<char16_t, true>::result
3723 __codecvt_utf16<char16_t, true>::do_out(state_type&,
3724 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3725 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3727 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3728 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3729 const uint16_t* _frm_nxt = _frm;
3730 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3731 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3732 uint8_t* _to_nxt = _to;
3733 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3735 frm_nxt = frm + (_frm_nxt - _frm);
3736 to_nxt = to + (_to_nxt - _to);
3740 __codecvt_utf16<char16_t, true>::result
3741 __codecvt_utf16<char16_t, true>::do_in(state_type&,
3742 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3743 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3745 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3746 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3747 const uint8_t* _frm_nxt = _frm;
3748 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3749 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3750 uint16_t* _to_nxt = _to;
3751 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3753 frm_nxt = frm + (_frm_nxt - _frm);
3754 to_nxt = to + (_to_nxt - _to);
3758 __codecvt_utf16<char16_t, true>::result
3759 __codecvt_utf16<char16_t, true>::do_unshift(state_type&,
3760 extern_type* to, extern_type*, extern_type*& to_nxt) const
3767 __codecvt_utf16<char16_t, true>::do_encoding() const _NOEXCEPT
3773 __codecvt_utf16<char16_t, true>::do_always_noconv() const _NOEXCEPT
3779 __codecvt_utf16<char16_t, true>::do_length(state_type&,
3780 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3782 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3783 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3784 return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3788 __codecvt_utf16<char16_t, true>::do_max_length() const _NOEXCEPT
3790 if (_Mode_ & consume_header)
3795 // __codecvt_utf16<char32_t, false>
3797 __codecvt_utf16<char32_t, false>::result
3798 __codecvt_utf16<char32_t, false>::do_out(state_type&,
3799 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3800 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3802 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3803 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3804 const uint32_t* _frm_nxt = _frm;
3805 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3806 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3807 uint8_t* _to_nxt = _to;
3808 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3810 frm_nxt = frm + (_frm_nxt - _frm);
3811 to_nxt = to + (_to_nxt - _to);
3815 __codecvt_utf16<char32_t, false>::result
3816 __codecvt_utf16<char32_t, false>::do_in(state_type&,
3817 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3818 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3820 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3821 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3822 const uint8_t* _frm_nxt = _frm;
3823 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3824 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3825 uint32_t* _to_nxt = _to;
3826 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3828 frm_nxt = frm + (_frm_nxt - _frm);
3829 to_nxt = to + (_to_nxt - _to);
3833 __codecvt_utf16<char32_t, false>::result
3834 __codecvt_utf16<char32_t, false>::do_unshift(state_type&,
3835 extern_type* to, extern_type*, extern_type*& to_nxt) const
3842 __codecvt_utf16<char32_t, false>::do_encoding() const _NOEXCEPT
3848 __codecvt_utf16<char32_t, false>::do_always_noconv() const _NOEXCEPT
3854 __codecvt_utf16<char32_t, false>::do_length(state_type&,
3855 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3857 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3858 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3859 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3863 __codecvt_utf16<char32_t, false>::do_max_length() const _NOEXCEPT
3865 if (_Mode_ & consume_header)
3870 // __codecvt_utf16<char32_t, true>
3872 __codecvt_utf16<char32_t, true>::result
3873 __codecvt_utf16<char32_t, true>::do_out(state_type&,
3874 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3875 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3877 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3878 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3879 const uint32_t* _frm_nxt = _frm;
3880 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3881 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3882 uint8_t* _to_nxt = _to;
3883 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3885 frm_nxt = frm + (_frm_nxt - _frm);
3886 to_nxt = to + (_to_nxt - _to);
3890 __codecvt_utf16<char32_t, true>::result
3891 __codecvt_utf16<char32_t, true>::do_in(state_type&,
3892 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3893 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3895 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3896 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3897 const uint8_t* _frm_nxt = _frm;
3898 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3899 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3900 uint32_t* _to_nxt = _to;
3901 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3903 frm_nxt = frm + (_frm_nxt - _frm);
3904 to_nxt = to + (_to_nxt - _to);
3908 __codecvt_utf16<char32_t, true>::result
3909 __codecvt_utf16<char32_t, true>::do_unshift(state_type&,
3910 extern_type* to, extern_type*, extern_type*& to_nxt) const
3917 __codecvt_utf16<char32_t, true>::do_encoding() const _NOEXCEPT
3923 __codecvt_utf16<char32_t, true>::do_always_noconv() const _NOEXCEPT
3929 __codecvt_utf16<char32_t, true>::do_length(state_type&,
3930 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3932 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3933 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3934 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3938 __codecvt_utf16<char32_t, true>::do_max_length() const _NOEXCEPT
3940 if (_Mode_ & consume_header)
3945 // __codecvt_utf8_utf16<wchar_t>
3947 __codecvt_utf8_utf16<wchar_t>::result
3948 __codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
3949 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3950 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3952 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3953 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3954 const uint32_t* _frm_nxt = _frm;
3955 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3956 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3957 uint8_t* _to_nxt = _to;
3958 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3960 frm_nxt = frm + (_frm_nxt - _frm);
3961 to_nxt = to + (_to_nxt - _to);
3965 __codecvt_utf8_utf16<wchar_t>::result
3966 __codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
3967 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3968 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3970 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3971 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3972 const uint8_t* _frm_nxt = _frm;
3973 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3974 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3975 uint32_t* _to_nxt = _to;
3976 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3978 frm_nxt = frm + (_frm_nxt - _frm);
3979 to_nxt = to + (_to_nxt - _to);
3983 __codecvt_utf8_utf16<wchar_t>::result
3984 __codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
3985 extern_type* to, extern_type*, extern_type*& to_nxt) const
3992 __codecvt_utf8_utf16<wchar_t>::do_encoding() const _NOEXCEPT
3998 __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const _NOEXCEPT
4004 __codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
4005 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4007 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4008 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4009 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4013 __codecvt_utf8_utf16<wchar_t>::do_max_length() const _NOEXCEPT
4015 if (_Mode_ & consume_header)
4020 // __codecvt_utf8_utf16<char16_t>
4022 __codecvt_utf8_utf16<char16_t>::result
4023 __codecvt_utf8_utf16<char16_t>::do_out(state_type&,
4024 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4025 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4027 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4028 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4029 const uint16_t* _frm_nxt = _frm;
4030 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4031 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4032 uint8_t* _to_nxt = _to;
4033 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4035 frm_nxt = frm + (_frm_nxt - _frm);
4036 to_nxt = to + (_to_nxt - _to);
4040 __codecvt_utf8_utf16<char16_t>::result
4041 __codecvt_utf8_utf16<char16_t>::do_in(state_type&,
4042 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4043 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4045 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4046 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4047 const uint8_t* _frm_nxt = _frm;
4048 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4049 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4050 uint16_t* _to_nxt = _to;
4051 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4053 frm_nxt = frm + (_frm_nxt - _frm);
4054 to_nxt = to + (_to_nxt - _to);
4058 __codecvt_utf8_utf16<char16_t>::result
4059 __codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
4060 extern_type* to, extern_type*, extern_type*& to_nxt) const
4067 __codecvt_utf8_utf16<char16_t>::do_encoding() const _NOEXCEPT
4073 __codecvt_utf8_utf16<char16_t>::do_always_noconv() const _NOEXCEPT
4079 __codecvt_utf8_utf16<char16_t>::do_length(state_type&,
4080 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4082 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4083 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4084 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4088 __codecvt_utf8_utf16<char16_t>::do_max_length() const _NOEXCEPT
4090 if (_Mode_ & consume_header)
4095 // __codecvt_utf8_utf16<char32_t>
4097 __codecvt_utf8_utf16<char32_t>::result
4098 __codecvt_utf8_utf16<char32_t>::do_out(state_type&,
4099 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4100 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4102 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4103 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4104 const uint32_t* _frm_nxt = _frm;
4105 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4106 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4107 uint8_t* _to_nxt = _to;
4108 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4110 frm_nxt = frm + (_frm_nxt - _frm);
4111 to_nxt = to + (_to_nxt - _to);
4115 __codecvt_utf8_utf16<char32_t>::result
4116 __codecvt_utf8_utf16<char32_t>::do_in(state_type&,
4117 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4118 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4120 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4121 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4122 const uint8_t* _frm_nxt = _frm;
4123 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4124 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4125 uint32_t* _to_nxt = _to;
4126 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4128 frm_nxt = frm + (_frm_nxt - _frm);
4129 to_nxt = to + (_to_nxt - _to);
4133 __codecvt_utf8_utf16<char32_t>::result
4134 __codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
4135 extern_type* to, extern_type*, extern_type*& to_nxt) const
4142 __codecvt_utf8_utf16<char32_t>::do_encoding() const _NOEXCEPT
4148 __codecvt_utf8_utf16<char32_t>::do_always_noconv() const _NOEXCEPT
4154 __codecvt_utf8_utf16<char32_t>::do_length(state_type&,
4155 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4157 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4158 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4159 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4163 __codecvt_utf8_utf16<char32_t>::do_max_length() const _NOEXCEPT
4165 if (_Mode_ & consume_header)
4170 // __narrow_to_utf8<16>
4172 __narrow_to_utf8<16>::~__narrow_to_utf8()
4176 // __narrow_to_utf8<32>
4178 __narrow_to_utf8<32>::~__narrow_to_utf8()
4182 // __widen_from_utf8<16>
4184 __widen_from_utf8<16>::~__widen_from_utf8()
4188 // __widen_from_utf8<32>
4190 __widen_from_utf8<32>::~__widen_from_utf8()
4195 static bool checked_string_to_wchar_convert(wchar_t& dest,
4202 size_t ret = __libcpp_mbrtowc_l(&out, ptr, strlen(ptr), &mb, loc);
4203 if (ret == static_cast<size_t>(-1) || ret == static_cast<size_t>(-2)) {
4210 static bool checked_string_to_char_convert(char& dest,
4219 // First convert the MBS into a wide char then attempt to narrow it using
4222 if (!checked_string_to_wchar_convert(wout, ptr, __loc))
4225 if ((res = __libcpp_wctob_l(wout, __loc)) != char_traits<char>::eof()) {
4229 // FIXME: Work around specific multibyte sequences that we can reasonable
4230 // translate into a different single byte.
4232 case L'\u202F': // narrow non-breaking space
4233 case L'\u00A0': // non-breaking space
4239 _LIBCPP_UNREACHABLE();
4243 // numpunct<char> && numpunct<wchar_t>
4245 locale::id numpunct< char >::id;
4246 locale::id numpunct<wchar_t>::id;
4248 numpunct<char>::numpunct(size_t refs)
4249 : locale::facet(refs),
4250 __decimal_point_('.'),
4251 __thousands_sep_(',')
4255 numpunct<wchar_t>::numpunct(size_t refs)
4256 : locale::facet(refs),
4257 __decimal_point_(L'.'),
4258 __thousands_sep_(L',')
4262 numpunct<char>::~numpunct()
4266 numpunct<wchar_t>::~numpunct()
4270 char numpunct< char >::do_decimal_point() const {return __decimal_point_;}
4271 wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
4273 char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;}
4274 wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
4276 string numpunct< char >::do_grouping() const {return __grouping_;}
4277 string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
4279 string numpunct< char >::do_truename() const {return "true";}
4280 wstring numpunct<wchar_t>::do_truename() const {return L"true";}
4282 string numpunct< char >::do_falsename() const {return "false";}
4283 wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
4285 // numpunct_byname<char>
4287 numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4288 : numpunct<char>(refs)
4293 numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4294 : numpunct<char>(refs)
4299 numpunct_byname<char>::~numpunct_byname()
4304 numpunct_byname<char>::__init(const char* nm)
4306 if (strcmp(nm, "C") != 0)
4308 __libcpp_unique_locale loc(nm);
4310 __throw_runtime_error("numpunct_byname<char>::numpunct_byname"
4311 " failed to construct for " + string(nm));
4313 lconv* lc = __libcpp_localeconv_l(loc.get());
4314 checked_string_to_char_convert(__decimal_point_, lc->decimal_point,
4316 checked_string_to_char_convert(__thousands_sep_, lc->thousands_sep,
4318 __grouping_ = lc->grouping;
4319 // localization for truename and falsename is not available
4323 // numpunct_byname<wchar_t>
4325 numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4326 : numpunct<wchar_t>(refs)
4331 numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4332 : numpunct<wchar_t>(refs)
4337 numpunct_byname<wchar_t>::~numpunct_byname()
4342 numpunct_byname<wchar_t>::__init(const char* nm)
4344 if (strcmp(nm, "C") != 0)
4346 __libcpp_unique_locale loc(nm);
4348 __throw_runtime_error("numpunct_byname<wchar_t>::numpunct_byname"
4349 " failed to construct for " + string(nm));
4351 lconv* lc = __libcpp_localeconv_l(loc.get());
4352 checked_string_to_wchar_convert(__decimal_point_, lc->decimal_point,
4354 checked_string_to_wchar_convert(__thousands_sep_, lc->thousands_sep,
4356 __grouping_ = lc->grouping;
4357 // localization for truename and falsename is not available
4364 __num_get_base::__get_base(ios_base& iob)
4366 ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4367 if (__basefield == ios_base::oct)
4369 else if (__basefield == ios_base::hex)
4371 else if (__basefield == 0)
4376 const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4379 __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4380 ios_base::iostate& __err)
4382 // if the grouping pattern is empty _or_ there are no grouping bits, then do nothing
4383 // we always have at least a single entry in [__g, __g_end); the end of the input sequence
4384 if (__grouping.size() != 0 && __g_end - __g > 1)
4386 reverse(__g, __g_end);
4387 const char* __ig = __grouping.data();
4388 const char* __eg = __ig + __grouping.size();
4389 for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4391 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4393 if (static_cast<unsigned>(*__ig) != *__r)
4395 __err = ios_base::failbit;
4399 if (__eg - __ig > 1)
4402 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4404 if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
4405 __err = ios_base::failbit;
4411 __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4412 ios_base::fmtflags __flags)
4414 if (__flags & ios_base::showpos)
4416 if (__flags & ios_base::showbase)
4419 *__fmtp++ = *__len++;
4420 if ((__flags & ios_base::basefield) == ios_base::oct)
4422 else if ((__flags & ios_base::basefield) == ios_base::hex)
4424 if (__flags & ios_base::uppercase)
4436 __num_put_base::__format_float(char* __fmtp, const char* __len,
4437 ios_base::fmtflags __flags)
4439 bool specify_precision = true;
4440 if (__flags & ios_base::showpos)
4442 if (__flags & ios_base::showpoint)
4444 ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4445 bool uppercase = (__flags & ios_base::uppercase) != 0;
4446 if (floatfield == (ios_base::fixed | ios_base::scientific))
4447 specify_precision = false;
4454 *__fmtp++ = *__len++;
4455 if (floatfield == ios_base::fixed)
4462 else if (floatfield == ios_base::scientific)
4469 else if (floatfield == (ios_base::fixed | ios_base::scientific))
4483 return specify_precision;
4487 __num_put_base::__identify_padding(char* __nb, char* __ne,
4488 const ios_base& __iob)
4490 switch (__iob.flags() & ios_base::adjustfield)
4492 case ios_base::internal:
4493 if (__nb[0] == '-' || __nb[0] == '+')
4495 if (__ne - __nb >= 2 && __nb[0] == '0'
4496 && (__nb[1] == 'x' || __nb[1] == 'X'))
4499 case ios_base::left:
4501 case ios_base::right:
4514 static string weeks[14];
4515 weeks[0] = "Sunday";
4516 weeks[1] = "Monday";
4517 weeks[2] = "Tuesday";
4518 weeks[3] = "Wednesday";
4519 weeks[4] = "Thursday";
4520 weeks[5] = "Friday";
4521 weeks[6] = "Saturday";
4536 static wstring weeks[14];
4537 weeks[0] = L"Sunday";
4538 weeks[1] = L"Monday";
4539 weeks[2] = L"Tuesday";
4540 weeks[3] = L"Wednesday";
4541 weeks[4] = L"Thursday";
4542 weeks[5] = L"Friday";
4543 weeks[6] = L"Saturday";
4556 __time_get_c_storage<char>::__weeks() const
4558 static const string* weeks = init_weeks();
4564 __time_get_c_storage<wchar_t>::__weeks() const
4566 static const wstring* weeks = init_wweeks();
4574 static string months[24];
4575 months[0] = "January";
4576 months[1] = "February";
4577 months[2] = "March";
4578 months[3] = "April";
4582 months[7] = "August";
4583 months[8] = "September";
4584 months[9] = "October";
4585 months[10] = "November";
4586 months[11] = "December";
4606 static wstring months[24];
4607 months[0] = L"January";
4608 months[1] = L"February";
4609 months[2] = L"March";
4610 months[3] = L"April";
4612 months[5] = L"June";
4613 months[6] = L"July";
4614 months[7] = L"August";
4615 months[8] = L"September";
4616 months[9] = L"October";
4617 months[10] = L"November";
4618 months[11] = L"December";
4619 months[12] = L"Jan";
4620 months[13] = L"Feb";
4621 months[14] = L"Mar";
4622 months[15] = L"Apr";
4623 months[16] = L"May";
4624 months[17] = L"Jun";
4625 months[18] = L"Jul";
4626 months[19] = L"Aug";
4627 months[20] = L"Sep";
4628 months[21] = L"Oct";
4629 months[22] = L"Nov";
4630 months[23] = L"Dec";
4636 __time_get_c_storage<char>::__months() const
4638 static const string* months = init_months();
4644 __time_get_c_storage<wchar_t>::__months() const
4646 static const wstring* months = init_wmonths();
4654 static string am_pm[2];
4664 static wstring am_pm[2];
4672 __time_get_c_storage<char>::__am_pm() const
4674 static const string* am_pm = init_am_pm();
4680 __time_get_c_storage<wchar_t>::__am_pm() const
4682 static const wstring* am_pm = init_wam_pm();
4688 __time_get_c_storage<char>::__x() const
4690 static string s("%m/%d/%y");
4696 __time_get_c_storage<wchar_t>::__x() const
4698 static wstring s(L"%m/%d/%y");
4704 __time_get_c_storage<char>::__X() const
4706 static string s("%H:%M:%S");
4712 __time_get_c_storage<wchar_t>::__X() const
4714 static wstring s(L"%H:%M:%S");
4720 __time_get_c_storage<char>::__c() const
4722 static string s("%a %b %d %H:%M:%S %Y");
4728 __time_get_c_storage<wchar_t>::__c() const
4730 static wstring s(L"%a %b %d %H:%M:%S %Y");
4736 __time_get_c_storage<char>::__r() const
4738 static string s("%I:%M:%S %p");
4744 __time_get_c_storage<wchar_t>::__r() const
4746 static wstring s(L"%I:%M:%S %p");
4752 __time_get::__time_get(const char* nm)
4753 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
4756 __throw_runtime_error("time_get_byname"
4757 " failed to construct for " + string(nm));
4760 __time_get::__time_get(const string& nm)
4761 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
4764 __throw_runtime_error("time_get_byname"
4765 " failed to construct for " + nm);
4768 __time_get::~__time_get()
4772 #if defined(__clang__)
4773 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
4775 #if defined(__GNUG__)
4776 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
4781 __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
4797 size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);
4803 if (ct.is(ctype_base::space, *bb))
4805 result.push_back(' ');
4806 for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
4811 ios_base::iostate err = ios_base::goodbit;
4812 ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
4817 result.push_back('%');
4819 result.push_back('A');
4821 result.push_back('a');
4826 i = __scan_keyword(w, be, this->__months_, this->__months_+24,
4831 result.push_back('%');
4833 result.push_back('B');
4835 result.push_back('b');
4836 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4837 result.back() = 'm';
4841 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4844 i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
4845 ct, err, false) - this->__am_pm_;
4848 result.push_back('%');
4849 result.push_back('p');
4855 if (ct.is(ctype_base::digit, *bb))
4857 switch(__get_up_to_n_digits(bb, be, err, ct, 4))
4860 result.push_back('%');
4861 result.push_back('w');
4864 result.push_back('%');
4865 result.push_back('u');
4868 result.push_back('%');
4869 result.push_back('I');
4872 result.push_back('%');
4873 result.push_back('m');
4876 result.push_back('%');
4877 result.push_back('H');
4880 result.push_back('%');
4881 result.push_back('d');
4884 result.push_back('%');
4885 result.push_back('M');
4888 result.push_back('%');
4889 result.push_back('S');
4892 result.push_back('%');
4893 result.push_back('y');
4896 result.push_back('%');
4897 result.push_back('j');
4900 result.push_back('%');
4901 result.push_back('Y');
4904 for (; w != bb; ++w)
4905 result.push_back(*w);
4912 result.push_back('%');
4913 result.push_back('%');
4917 result.push_back(*bb);
4923 #if defined(__clang__)
4924 #pragma clang diagnostic ignored "-Wmissing-braces"
4929 __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
4945 strftime_l(buf, countof(buf), f, &t, __loc_);
4947 wchar_t* wbb = wbuf;
4949 const char* bb = buf;
4950 size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
4951 if (j == size_t(-1))
4952 __throw_runtime_error("locale not supported");
4953 wchar_t* wbe = wbb + j;
4957 if (ct.is(ctype_base::space, *wbb))
4959 result.push_back(L' ');
4960 for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
4965 ios_base::iostate err = ios_base::goodbit;
4966 ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
4971 result.push_back(L'%');
4973 result.push_back(L'A');
4975 result.push_back(L'a');
4980 i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
4985 result.push_back(L'%');
4987 result.push_back(L'B');
4989 result.push_back(L'b');
4990 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4991 result.back() = L'm';
4995 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4998 i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
4999 ct, err, false) - this->__am_pm_;
5002 result.push_back(L'%');
5003 result.push_back(L'p');
5009 if (ct.is(ctype_base::digit, *wbb))
5011 switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
5014 result.push_back(L'%');
5015 result.push_back(L'w');
5018 result.push_back(L'%');
5019 result.push_back(L'u');
5022 result.push_back(L'%');
5023 result.push_back(L'I');
5026 result.push_back(L'%');
5027 result.push_back(L'm');
5030 result.push_back(L'%');
5031 result.push_back(L'H');
5034 result.push_back(L'%');
5035 result.push_back(L'd');
5038 result.push_back(L'%');
5039 result.push_back(L'M');
5042 result.push_back(L'%');
5043 result.push_back(L'S');
5046 result.push_back(L'%');
5047 result.push_back(L'y');
5050 result.push_back(L'%');
5051 result.push_back(L'j');
5054 result.push_back(L'%');
5055 result.push_back(L'Y');
5058 for (; w != wbb; ++w)
5059 result.push_back(*w);
5064 if (ct.narrow(*wbb, 0) == '%')
5066 result.push_back(L'%');
5067 result.push_back(L'%');
5071 result.push_back(*wbb);
5079 __time_get_storage<char>::init(const ctype<char>& ct)
5084 for (int i = 0; i < 7; ++i)
5087 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5089 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5090 __weeks_[i+7] = buf;
5093 for (int i = 0; i < 12; ++i)
5096 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5098 strftime_l(buf, countof(buf), "%b", &t, __loc_);
5099 __months_[i+12] = buf;
5103 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5106 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5108 __c_ = __analyze('c', ct);
5109 __r_ = __analyze('r', ct);
5110 __x_ = __analyze('x', ct);
5111 __X_ = __analyze('X', ct);
5116 __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
5124 for (int i = 0; i < 7; ++i)
5127 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5129 const char* bb = buf;
5130 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5131 if (j == size_t(-1))
5132 __throw_runtime_error("locale not supported");
5134 __weeks_[i].assign(wbuf, wbe);
5135 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5138 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5139 if (j == size_t(-1))
5140 __throw_runtime_error("locale not supported");
5142 __weeks_[i+7].assign(wbuf, wbe);
5145 for (int i = 0; i < 12; ++i)
5148 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5150 const char* bb = buf;
5151 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5152 if (j == size_t(-1))
5153 __throw_runtime_error("locale not supported");
5155 __months_[i].assign(wbuf, wbe);
5156 strftime_l(buf, countof(buf), "%b", &t, __loc_);
5159 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5160 if (j == size_t(-1))
5161 __throw_runtime_error("locale not supported");
5163 __months_[i+12].assign(wbuf, wbe);
5167 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5169 const char* bb = buf;
5170 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5171 if (j == size_t(-1))
5172 __throw_runtime_error("locale not supported");
5174 __am_pm_[0].assign(wbuf, wbe);
5176 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5179 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5180 if (j == size_t(-1))
5181 __throw_runtime_error("locale not supported");
5183 __am_pm_[1].assign(wbuf, wbe);
5184 __c_ = __analyze('c', ct);
5185 __r_ = __analyze('r', ct);
5186 __x_ = __analyze('x', ct);
5187 __X_ = __analyze('X', ct);
5190 template <class CharT>
5191 struct _LIBCPP_HIDDEN __time_get_temp
5192 : public ctype_byname<CharT>
5194 explicit __time_get_temp(const char* nm)
5195 : ctype_byname<CharT>(nm, 1) {}
5196 explicit __time_get_temp(const string& nm)
5197 : ctype_byname<CharT>(nm, 1) {}
5201 __time_get_storage<char>::__time_get_storage(const char* __nm)
5204 const __time_get_temp<char> ct(__nm);
5209 __time_get_storage<char>::__time_get_storage(const string& __nm)
5212 const __time_get_temp<char> ct(__nm);
5217 __time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5220 const __time_get_temp<wchar_t> ct(__nm);
5225 __time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5228 const __time_get_temp<wchar_t> ct(__nm);
5233 time_base::dateorder
5234 __time_get_storage<char>::__do_date_order() const
5237 for (i = 0; i < __x_.size(); ++i)
5245 for (++i; i < __x_.size(); ++i)
5248 if (i == __x_.size())
5254 for (++i; i < __x_.size(); ++i)
5257 if (i == __x_.size())
5261 return time_base::ymd;
5264 for (++i; i < __x_.size(); ++i)
5267 if (i == __x_.size())
5271 return time_base::ydm;
5276 for (++i; i < __x_.size(); ++i)
5279 if (i == __x_.size())
5284 for (++i; i < __x_.size(); ++i)
5287 if (i == __x_.size())
5290 if (__x_[i] == 'y' || __x_[i] == 'Y')
5291 return time_base::mdy;
5296 for (++i; i < __x_.size(); ++i)
5299 if (i == __x_.size())
5304 for (++i; i < __x_.size(); ++i)
5307 if (i == __x_.size())
5310 if (__x_[i] == 'y' || __x_[i] == 'Y')
5311 return time_base::dmy;
5316 return time_base::no_order;
5320 time_base::dateorder
5321 __time_get_storage<wchar_t>::__do_date_order() const
5324 for (i = 0; i < __x_.size(); ++i)
5325 if (__x_[i] == L'%')
5332 for (++i; i < __x_.size(); ++i)
5333 if (__x_[i] == L'%')
5335 if (i == __x_.size())
5341 for (++i; i < __x_.size(); ++i)
5342 if (__x_[i] == L'%')
5344 if (i == __x_.size())
5347 if (__x_[i] == L'd')
5348 return time_base::ymd;
5351 for (++i; i < __x_.size(); ++i)
5352 if (__x_[i] == L'%')
5354 if (i == __x_.size())
5357 if (__x_[i] == L'm')
5358 return time_base::ydm;
5363 for (++i; i < __x_.size(); ++i)
5364 if (__x_[i] == L'%')
5366 if (i == __x_.size())
5369 if (__x_[i] == L'd')
5371 for (++i; i < __x_.size(); ++i)
5372 if (__x_[i] == L'%')
5374 if (i == __x_.size())
5377 if (__x_[i] == L'y' || __x_[i] == L'Y')
5378 return time_base::mdy;
5383 for (++i; i < __x_.size(); ++i)
5384 if (__x_[i] == L'%')
5386 if (i == __x_.size())
5389 if (__x_[i] == L'm')
5391 for (++i; i < __x_.size(); ++i)
5392 if (__x_[i] == L'%')
5394 if (i == __x_.size())
5397 if (__x_[i] == L'y' || __x_[i] == L'Y')
5398 return time_base::dmy;
5403 return time_base::no_order;
5408 __time_put::__time_put(const char* nm)
5409 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5412 __throw_runtime_error("time_put_byname"
5413 " failed to construct for " + string(nm));
5416 __time_put::__time_put(const string& nm)
5417 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5420 __throw_runtime_error("time_put_byname"
5421 " failed to construct for " + nm);
5424 __time_put::~__time_put()
5426 if (__loc_ != _LIBCPP_GET_C_LOCALE)
5431 __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5432 char __fmt, char __mod) const
5434 char fmt[] = {'%', __fmt, __mod, 0};
5436 swap(fmt[1], fmt[2]);
5437 size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
5442 __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5443 char __fmt, char __mod) const
5446 char* __ne = __nar + 100;
5447 __do_put(__nar, __ne, __tm, __fmt, __mod);
5449 const char* __nb = __nar;
5450 size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
5451 if (j == size_t(-1))
5452 __throw_runtime_error("locale not supported");
5456 // moneypunct_byname
5458 template <class charT>
5461 __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
5462 bool intl, char cs_precedes, char sep_by_space, char sign_posn,
5465 const char sign = static_cast<char>(money_base::sign);
5466 const char space = static_cast<char>(money_base::space);
5467 const char none = static_cast<char>(money_base::none);
5468 const char symbol = static_cast<char>(money_base::symbol);
5469 const char value = static_cast<char>(money_base::value);
5470 const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
5472 // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5473 // function'. "Space between sign and symbol or value" means that
5474 // if the sign is adjacent to the symbol, there's a space between
5475 // them, and otherwise there's a space between the sign and value.
5477 // C11's localeconv specifies that the fourth character of an
5478 // international curr_symbol is used to separate the sign and
5479 // value when sep_by_space says to do so. C++ can't represent
5480 // that, so we just use a space. When sep_by_space says to
5481 // separate the symbol and value-or-sign with a space, we rearrange the
5482 // curr_symbol to put its spacing character on the correct side of
5485 // We also need to avoid adding an extra space between the sign
5486 // and value when the currency symbol is suppressed (by not
5487 // setting showbase). We match glibc's strfmon by interpreting
5488 // sep_by_space==1 as "omit the space when the currency symbol is
5491 // Users who want to get this right should use ICU instead.
5493 switch (cs_precedes)
5495 case 0: // value before curr_symbol
5496 if (symbol_contains_sep) {
5497 // Move the separator to before the symbol, to place it
5498 // between the value and symbol.
5499 rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,
5500 __curr_symbol_.end());
5504 case 0: // Parentheses surround the quantity and currency symbol.
5505 pat.field[0] = sign;
5506 pat.field[1] = value;
5507 pat.field[2] = none; // Any space appears in the symbol.
5508 pat.field[3] = symbol;
5509 switch (sep_by_space)
5511 case 0: // No space separates the currency symbol and value.
5512 // This case may have changed between C99 and C11;
5513 // assume the currency symbol matches the intention.
5514 case 2: // Space between sign and currency or value.
5515 // The "sign" is two parentheses, so no space here either.
5517 case 1: // Space between currency-and-sign or currency and value.
5518 if (!symbol_contains_sep) {
5519 // We insert the space into the symbol instead of
5520 // setting pat.field[2]=space so that when
5521 // showbase is not set, the space goes away too.
5522 __curr_symbol_.insert(0, 1, space_char);
5529 case 1: // The sign string precedes the quantity and currency symbol.
5530 pat.field[0] = sign;
5531 pat.field[3] = symbol;
5532 switch (sep_by_space)
5534 case 0: // No space separates the currency symbol and value.
5535 pat.field[1] = value;
5536 pat.field[2] = none;
5538 case 1: // Space between currency-and-sign or currency and value.
5539 pat.field[1] = value;
5540 pat.field[2] = none;
5541 if (!symbol_contains_sep) {
5542 // We insert the space into the symbol instead of
5543 // setting pat.field[2]=space so that when
5544 // showbase is not set, the space goes away too.
5545 __curr_symbol_.insert(0, 1, space_char);
5548 case 2: // Space between sign and currency or value.
5549 pat.field[1] = space;
5550 pat.field[2] = value;
5551 if (symbol_contains_sep) {
5552 // Remove the separator from the symbol, since it
5553 // has already appeared after the sign.
5554 __curr_symbol_.erase(__curr_symbol_.begin());
5561 case 2: // The sign string succeeds the quantity and currency symbol.
5562 pat.field[0] = value;
5563 pat.field[3] = sign;
5564 switch (sep_by_space)
5566 case 0: // No space separates the currency symbol and value.
5567 pat.field[1] = none;
5568 pat.field[2] = symbol;
5570 case 1: // Space between currency-and-sign or currency and value.
5571 if (!symbol_contains_sep) {
5572 // We insert the space into the symbol instead of
5573 // setting pat.field[1]=space so that when
5574 // showbase is not set, the space goes away too.
5575 __curr_symbol_.insert(0, 1, space_char);
5577 pat.field[1] = none;
5578 pat.field[2] = symbol;
5580 case 2: // Space between sign and currency or value.
5581 pat.field[1] = symbol;
5582 pat.field[2] = space;
5583 if (symbol_contains_sep) {
5584 // Remove the separator from the symbol, since it
5585 // should not be removed if showbase is absent.
5586 __curr_symbol_.erase(__curr_symbol_.begin());
5593 case 3: // The sign string immediately precedes the currency symbol.
5594 pat.field[0] = value;
5595 pat.field[3] = symbol;
5596 switch (sep_by_space)
5598 case 0: // No space separates the currency symbol and value.
5599 pat.field[1] = none;
5600 pat.field[2] = sign;
5602 case 1: // Space between currency-and-sign or currency and value.
5603 pat.field[1] = space;
5604 pat.field[2] = sign;
5605 if (symbol_contains_sep) {
5606 // Remove the separator from the symbol, since it
5607 // has already appeared before the sign.
5608 __curr_symbol_.erase(__curr_symbol_.begin());
5611 case 2: // Space between sign and currency or value.
5612 pat.field[1] = sign;
5613 pat.field[2] = none;
5614 if (!symbol_contains_sep) {
5615 // We insert the space into the symbol instead of
5616 // setting pat.field[2]=space so that when
5617 // showbase is not set, the space goes away too.
5618 __curr_symbol_.insert(0, 1, space_char);
5625 case 4: // The sign string immediately succeeds the currency symbol.
5626 pat.field[0] = value;
5627 pat.field[3] = sign;
5628 switch (sep_by_space)
5630 case 0: // No space separates the currency symbol and value.
5631 pat.field[1] = none;
5632 pat.field[2] = symbol;
5634 case 1: // Space between currency-and-sign or currency and value.
5635 pat.field[1] = none;
5636 pat.field[2] = symbol;
5637 if (!symbol_contains_sep) {
5638 // We insert the space into the symbol instead of
5639 // setting pat.field[1]=space so that when
5640 // showbase is not set, the space goes away too.
5641 __curr_symbol_.insert(0, 1, space_char);
5644 case 2: // Space between sign and currency or value.
5645 pat.field[1] = symbol;
5646 pat.field[2] = space;
5647 if (symbol_contains_sep) {
5648 // Remove the separator from the symbol, since it
5649 // should not disappear when showbase is absent.
5650 __curr_symbol_.erase(__curr_symbol_.begin());
5661 case 1: // curr_symbol before value
5664 case 0: // Parentheses surround the quantity and currency symbol.
5665 pat.field[0] = sign;
5666 pat.field[1] = symbol;
5667 pat.field[2] = none; // Any space appears in the symbol.
5668 pat.field[3] = value;
5669 switch (sep_by_space)
5671 case 0: // No space separates the currency symbol and value.
5672 // This case may have changed between C99 and C11;
5673 // assume the currency symbol matches the intention.
5674 case 2: // Space between sign and currency or value.
5675 // The "sign" is two parentheses, so no space here either.
5677 case 1: // Space between currency-and-sign or currency and value.
5678 if (!symbol_contains_sep) {
5679 // We insert the space into the symbol instead of
5680 // setting pat.field[2]=space so that when
5681 // showbase is not set, the space goes away too.
5682 __curr_symbol_.insert(0, 1, space_char);
5689 case 1: // The sign string precedes the quantity and currency symbol.
5690 pat.field[0] = sign;
5691 pat.field[3] = value;
5692 switch (sep_by_space)
5694 case 0: // No space separates the currency symbol and value.
5695 pat.field[1] = symbol;
5696 pat.field[2] = none;
5698 case 1: // Space between currency-and-sign or currency and value.
5699 pat.field[1] = symbol;
5700 pat.field[2] = none;
5701 if (!symbol_contains_sep) {
5702 // We insert the space into the symbol instead of
5703 // setting pat.field[2]=space so that when
5704 // showbase is not set, the space goes away too.
5705 __curr_symbol_.push_back(space_char);
5708 case 2: // Space between sign and currency or value.
5709 pat.field[1] = space;
5710 pat.field[2] = symbol;
5711 if (symbol_contains_sep) {
5712 // Remove the separator from the symbol, since it
5713 // has already appeared after the sign.
5714 __curr_symbol_.pop_back();
5721 case 2: // The sign string succeeds the quantity and currency symbol.
5722 pat.field[0] = symbol;
5723 pat.field[3] = sign;
5724 switch (sep_by_space)
5726 case 0: // No space separates the currency symbol and value.
5727 pat.field[1] = none;
5728 pat.field[2] = value;
5730 case 1: // Space between currency-and-sign or currency and value.
5731 pat.field[1] = none;
5732 pat.field[2] = value;
5733 if (!symbol_contains_sep) {
5734 // We insert the space into the symbol instead of
5735 // setting pat.field[1]=space so that when
5736 // showbase is not set, the space goes away too.
5737 __curr_symbol_.push_back(space_char);
5740 case 2: // Space between sign and currency or value.
5741 pat.field[1] = value;
5742 pat.field[2] = space;
5743 if (symbol_contains_sep) {
5744 // Remove the separator from the symbol, since it
5745 // will appear before the sign.
5746 __curr_symbol_.pop_back();
5753 case 3: // The sign string immediately precedes the currency symbol.
5754 pat.field[0] = sign;
5755 pat.field[3] = value;
5756 switch (sep_by_space)
5758 case 0: // No space separates the currency symbol and value.
5759 pat.field[1] = symbol;
5760 pat.field[2] = none;
5762 case 1: // Space between currency-and-sign or currency and value.
5763 pat.field[1] = symbol;
5764 pat.field[2] = none;
5765 if (!symbol_contains_sep) {
5766 // We insert the space into the symbol instead of
5767 // setting pat.field[2]=space so that when
5768 // showbase is not set, the space goes away too.
5769 __curr_symbol_.push_back(space_char);
5772 case 2: // Space between sign and currency or value.
5773 pat.field[1] = space;
5774 pat.field[2] = symbol;
5775 if (symbol_contains_sep) {
5776 // Remove the separator from the symbol, since it
5777 // has already appeared after the sign.
5778 __curr_symbol_.pop_back();
5785 case 4: // The sign string immediately succeeds the currency symbol.
5786 pat.field[0] = symbol;
5787 pat.field[3] = value;
5788 switch (sep_by_space)
5790 case 0: // No space separates the currency symbol and value.
5791 pat.field[1] = sign;
5792 pat.field[2] = none;
5794 case 1: // Space between currency-and-sign or currency and value.
5795 pat.field[1] = sign;
5796 pat.field[2] = space;
5797 if (symbol_contains_sep) {
5798 // Remove the separator from the symbol, since it
5799 // should not disappear when showbase is absent.
5800 __curr_symbol_.pop_back();
5803 case 2: // Space between sign and currency or value.
5804 pat.field[1] = none;
5805 pat.field[2] = sign;
5806 if (!symbol_contains_sep) {
5807 // We insert the space into the symbol instead of
5808 // setting pat.field[1]=space so that when
5809 // showbase is not set, the space goes away too.
5810 __curr_symbol_.push_back(space_char);
5824 pat.field[0] = symbol;
5825 pat.field[1] = sign;
5826 pat.field[2] = none;
5827 pat.field[3] = value;
5832 moneypunct_byname<char, false>::init(const char* nm)
5834 typedef moneypunct<char, false> base;
5835 __libcpp_unique_locale loc(nm);
5837 __throw_runtime_error("moneypunct_byname"
5838 " failed to construct for " + string(nm));
5840 lconv* lc = __libcpp_localeconv_l(loc.get());
5841 if (!checked_string_to_char_convert(__decimal_point_,
5842 lc->mon_decimal_point,
5844 __decimal_point_ = base::do_decimal_point();
5845 if (!checked_string_to_char_convert(__thousands_sep_,
5846 lc->mon_thousands_sep,
5848 __thousands_sep_ = base::do_thousands_sep();
5850 __grouping_ = lc->mon_grouping;
5851 __curr_symbol_ = lc->currency_symbol;
5852 if (lc->frac_digits != CHAR_MAX)
5853 __frac_digits_ = lc->frac_digits;
5855 __frac_digits_ = base::do_frac_digits();
5856 if (lc->p_sign_posn == 0)
5857 __positive_sign_ = "()";
5859 __positive_sign_ = lc->positive_sign;
5860 if (lc->n_sign_posn == 0)
5861 __negative_sign_ = "()";
5863 __negative_sign_ = lc->negative_sign;
5864 // Assume the positive and negative formats will want spaces in
5865 // the same places in curr_symbol since there's no way to
5866 // represent anything else.
5867 string_type __dummy_curr_symbol = __curr_symbol_;
5868 __init_pat(__pos_format_, __dummy_curr_symbol, false,
5869 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5870 __init_pat(__neg_format_, __curr_symbol_, false,
5871 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5876 moneypunct_byname<char, true>::init(const char* nm)
5878 typedef moneypunct<char, true> base;
5879 __libcpp_unique_locale loc(nm);
5881 __throw_runtime_error("moneypunct_byname"
5882 " failed to construct for " + string(nm));
5884 lconv* lc = __libcpp_localeconv_l(loc.get());
5885 if (!checked_string_to_char_convert(__decimal_point_,
5886 lc->mon_decimal_point,
5888 __decimal_point_ = base::do_decimal_point();
5889 if (!checked_string_to_char_convert(__thousands_sep_,
5890 lc->mon_thousands_sep,
5892 __thousands_sep_ = base::do_thousands_sep();
5893 __grouping_ = lc->mon_grouping;
5894 __curr_symbol_ = lc->int_curr_symbol;
5895 if (lc->int_frac_digits != CHAR_MAX)
5896 __frac_digits_ = lc->int_frac_digits;
5898 __frac_digits_ = base::do_frac_digits();
5899 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5900 if (lc->p_sign_posn == 0)
5901 #else // _LIBCPP_MSVCRT
5902 if (lc->int_p_sign_posn == 0)
5903 #endif // !_LIBCPP_MSVCRT
5904 __positive_sign_ = "()";
5906 __positive_sign_ = lc->positive_sign;
5907 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5908 if(lc->n_sign_posn == 0)
5909 #else // _LIBCPP_MSVCRT
5910 if (lc->int_n_sign_posn == 0)
5911 #endif // !_LIBCPP_MSVCRT
5912 __negative_sign_ = "()";
5914 __negative_sign_ = lc->negative_sign;
5915 // Assume the positive and negative formats will want spaces in
5916 // the same places in curr_symbol since there's no way to
5917 // represent anything else.
5918 string_type __dummy_curr_symbol = __curr_symbol_;
5919 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5920 __init_pat(__pos_format_, __dummy_curr_symbol, true,
5921 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5922 __init_pat(__neg_format_, __curr_symbol_, true,
5923 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5924 #else // _LIBCPP_MSVCRT
5925 __init_pat(__pos_format_, __dummy_curr_symbol, true,
5926 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
5927 lc->int_p_sign_posn, ' ');
5928 __init_pat(__neg_format_, __curr_symbol_, true,
5929 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
5930 lc->int_n_sign_posn, ' ');
5931 #endif // !_LIBCPP_MSVCRT
5936 moneypunct_byname<wchar_t, false>::init(const char* nm)
5938 typedef moneypunct<wchar_t, false> base;
5939 __libcpp_unique_locale loc(nm);
5941 __throw_runtime_error("moneypunct_byname"
5942 " failed to construct for " + string(nm));
5943 lconv* lc = __libcpp_localeconv_l(loc.get());
5944 if (!checked_string_to_wchar_convert(__decimal_point_,
5945 lc->mon_decimal_point,
5947 __decimal_point_ = base::do_decimal_point();
5948 if (!checked_string_to_wchar_convert(__thousands_sep_,
5949 lc->mon_thousands_sep,
5951 __thousands_sep_ = base::do_thousands_sep();
5952 __grouping_ = lc->mon_grouping;
5955 const char* bb = lc->currency_symbol;
5956 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5957 if (j == size_t(-1))
5958 __throw_runtime_error("locale not supported");
5959 wchar_t* wbe = wbuf + j;
5960 __curr_symbol_.assign(wbuf, wbe);
5961 if (lc->frac_digits != CHAR_MAX)
5962 __frac_digits_ = lc->frac_digits;
5964 __frac_digits_ = base::do_frac_digits();
5965 if (lc->p_sign_posn == 0)
5966 __positive_sign_ = L"()";
5970 bb = lc->positive_sign;
5971 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5972 if (j == size_t(-1))
5973 __throw_runtime_error("locale not supported");
5975 __positive_sign_.assign(wbuf, wbe);
5977 if (lc->n_sign_posn == 0)
5978 __negative_sign_ = L"()";
5982 bb = lc->negative_sign;
5983 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5984 if (j == size_t(-1))
5985 __throw_runtime_error("locale not supported");
5987 __negative_sign_.assign(wbuf, wbe);
5989 // Assume the positive and negative formats will want spaces in
5990 // the same places in curr_symbol since there's no way to
5991 // represent anything else.
5992 string_type __dummy_curr_symbol = __curr_symbol_;
5993 __init_pat(__pos_format_, __dummy_curr_symbol, false,
5994 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
5995 __init_pat(__neg_format_, __curr_symbol_, false,
5996 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6001 moneypunct_byname<wchar_t, true>::init(const char* nm)
6003 typedef moneypunct<wchar_t, true> base;
6004 __libcpp_unique_locale loc(nm);
6006 __throw_runtime_error("moneypunct_byname"
6007 " failed to construct for " + string(nm));
6009 lconv* lc = __libcpp_localeconv_l(loc.get());
6010 if (!checked_string_to_wchar_convert(__decimal_point_,
6011 lc->mon_decimal_point,
6013 __decimal_point_ = base::do_decimal_point();
6014 if (!checked_string_to_wchar_convert(__thousands_sep_,
6015 lc->mon_thousands_sep,
6017 __thousands_sep_ = base::do_thousands_sep();
6018 __grouping_ = lc->mon_grouping;
6021 const char* bb = lc->int_curr_symbol;
6022 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6023 if (j == size_t(-1))
6024 __throw_runtime_error("locale not supported");
6025 wchar_t* wbe = wbuf + j;
6026 __curr_symbol_.assign(wbuf, wbe);
6027 if (lc->int_frac_digits != CHAR_MAX)
6028 __frac_digits_ = lc->int_frac_digits;
6030 __frac_digits_ = base::do_frac_digits();
6031 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6032 if (lc->p_sign_posn == 0)
6033 #else // _LIBCPP_MSVCRT
6034 if (lc->int_p_sign_posn == 0)
6035 #endif // !_LIBCPP_MSVCRT
6036 __positive_sign_ = L"()";
6040 bb = lc->positive_sign;
6041 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6042 if (j == size_t(-1))
6043 __throw_runtime_error("locale not supported");
6045 __positive_sign_.assign(wbuf, wbe);
6047 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6048 if (lc->n_sign_posn == 0)
6049 #else // _LIBCPP_MSVCRT
6050 if (lc->int_n_sign_posn == 0)
6051 #endif // !_LIBCPP_MSVCRT
6052 __negative_sign_ = L"()";
6056 bb = lc->negative_sign;
6057 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6058 if (j == size_t(-1))
6059 __throw_runtime_error("locale not supported");
6061 __negative_sign_.assign(wbuf, wbe);
6063 // Assume the positive and negative formats will want spaces in
6064 // the same places in curr_symbol since there's no way to
6065 // represent anything else.
6066 string_type __dummy_curr_symbol = __curr_symbol_;
6067 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6068 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6069 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6070 __init_pat(__neg_format_, __curr_symbol_, true,
6071 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6072 #else // _LIBCPP_MSVCRT
6073 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6074 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6075 lc->int_p_sign_posn, L' ');
6076 __init_pat(__neg_format_, __curr_symbol_, true,
6077 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6078 lc->int_n_sign_posn, L' ');
6079 #endif // !_LIBCPP_MSVCRT
6082 void __do_nothing(void*) {}
6084 void __throw_runtime_error(const char* msg)
6086 #ifndef _LIBCPP_NO_EXCEPTIONS
6087 throw runtime_error(msg);
6094 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;
6095 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;
6097 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<char>;
6098 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<wchar_t>;
6100 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<char>;
6101 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<wchar_t>;
6103 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<char>;
6104 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<wchar_t>;
6106 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<char>;
6107 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<wchar_t>;
6109 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<char>;
6110 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<wchar_t>;
6112 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<char>;
6113 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<wchar_t>;
6115 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<char>;
6116 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<wchar_t>;
6118 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<char>;
6119 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<wchar_t>;
6121 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, false>;
6122 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, true>;
6123 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, false>;
6124 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, true>;
6126 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, false>;
6127 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, true>;
6128 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, false>;
6129 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, true>;
6131 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<char>;
6132 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<wchar_t>;
6134 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<char>;
6135 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<wchar_t>;
6137 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<char>;
6138 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<wchar_t>;
6140 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<char>;
6141 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<wchar_t>;
6143 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<char>;
6144 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<wchar_t>;
6146 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<char>;
6147 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t>;
6149 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>;
6150 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;
6151 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
6152 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
6154 _LIBCPP_END_NAMESPACE_STD