1 //===------------------------- locale.cpp ---------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // On Solaris, we need to define something to make the C99 parts of localeconv
22 #ifndef _LIBCPP_NO_EXCEPTIONS
23 # include "type_traits"
27 #if defined(_LIBCPP_MSVCRT)
28 #define _CTYPE_DISABLE_MACROS
31 #include "__sso_allocator"
32 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
33 #include "support/win32/locale_win32.h"
34 #elif !defined(__BIONIC__)
40 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
41 // lots of noise in the build log, but no bugs that I know of.
42 #if defined(__clang__)
43 #pragma clang diagnostic ignored "-Wsign-conversion"
46 _LIBCPP_BEGIN_NAMESPACE_STD
50 // In theory this could create a race condition. In practice
51 // the race condition is non-fatal since it will just create
52 // a little resource leak. Better approach would be appreciated.
53 static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
56 #endif // __cloc_defined
62 void operator()(locale::facet* p) {p->__release_shared();}
65 template <class T, class A0>
70 static typename aligned_storage<sizeof(T)>::type buf;
71 auto *obj = ::new (&buf) T(a0);
75 template <class T, class A0, class A1>
80 static typename aligned_storage<sizeof(T)>::type buf;
81 ::new (&buf) T(a0, a1);
82 return *reinterpret_cast<T*>(&buf);
85 template <class T, class A0, class A1, class A2>
88 make(A0 a0, A1 a1, A2 a2)
90 static typename aligned_storage<sizeof(T)>::type buf;
91 auto *obj = ::new (&buf) T(a0, a1, a2);
95 template <typename T, size_t N>
99 countof(const T (&)[N])
104 template <typename T>
108 countof(const T * const begin, const T * const end)
110 return static_cast<size_t>(end - begin);
113 _LIBCPP_NORETURN static void __throw_runtime_error(const string &msg)
115 #ifndef _LIBCPP_NO_EXCEPTIONS
116 throw runtime_error(msg);
126 // Set priority to INT_MIN + 256 + 150
127 # pragma priority ( -2147483242 )
130 const locale::category locale::none;
131 const locale::category locale::collate;
132 const locale::category locale::ctype;
133 const locale::category locale::monetary;
134 const locale::category locale::numeric;
135 const locale::category locale::time;
136 const locale::category locale::messages;
137 const locale::category locale::all;
139 class _LIBCPP_HIDDEN locale::__imp
143 #if defined(_LIBCPP_COMPILER_MSVC)
144 // FIXME: MSVC doesn't support aligned parameters by value.
145 // I can't get the __sso_allocator to work here
146 // for MSVC I think for this reason.
147 vector<facet*> facets_;
149 vector<facet*, __sso_allocator<facet*, N> > facets_;
153 explicit __imp(size_t refs = 0);
154 explicit __imp(const string& name, size_t refs = 0);
156 __imp(const __imp&, const string&, locale::category c);
157 __imp(const __imp& other, const __imp& one, locale::category c);
158 __imp(const __imp&, facet* f, long id);
161 const string& name() const {return name_;}
162 bool has_facet(long id) const
163 {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
164 const locale::facet* use_facet(long id) const;
166 static const locale& make_classic();
167 static locale& make_global();
169 void install(facet* f, long id);
170 template <class F> void install(F* f) {install(f, f->id.__get());}
171 template <class F> void install_from(const __imp& other);
174 locale::__imp::__imp(size_t refs)
180 install(&make<_VSTD::collate<char> >(1u));
181 install(&make<_VSTD::collate<wchar_t> >(1u));
182 install(&make<_VSTD::ctype<char> >(nullptr, false, 1u));
183 install(&make<_VSTD::ctype<wchar_t> >(1u));
184 install(&make<codecvt<char, char, mbstate_t> >(1u));
185 install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
186 install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
187 install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
188 install(&make<numpunct<char> >(1u));
189 install(&make<numpunct<wchar_t> >(1u));
190 install(&make<num_get<char> >(1u));
191 install(&make<num_get<wchar_t> >(1u));
192 install(&make<num_put<char> >(1u));
193 install(&make<num_put<wchar_t> >(1u));
194 install(&make<moneypunct<char, false> >(1u));
195 install(&make<moneypunct<char, true> >(1u));
196 install(&make<moneypunct<wchar_t, false> >(1u));
197 install(&make<moneypunct<wchar_t, true> >(1u));
198 install(&make<money_get<char> >(1u));
199 install(&make<money_get<wchar_t> >(1u));
200 install(&make<money_put<char> >(1u));
201 install(&make<money_put<wchar_t> >(1u));
202 install(&make<time_get<char> >(1u));
203 install(&make<time_get<wchar_t> >(1u));
204 install(&make<time_put<char> >(1u));
205 install(&make<time_put<wchar_t> >(1u));
206 install(&make<_VSTD::messages<char> >(1u));
207 install(&make<_VSTD::messages<wchar_t> >(1u));
210 locale::__imp::__imp(const string& name, size_t refs)
215 #ifndef _LIBCPP_NO_EXCEPTIONS
218 #endif // _LIBCPP_NO_EXCEPTIONS
219 facets_ = locale::classic().__locale_->facets_;
220 for (unsigned i = 0; i < facets_.size(); ++i)
222 facets_[i]->__add_shared();
223 install(new collate_byname<char>(name_));
224 install(new collate_byname<wchar_t>(name_));
225 install(new ctype_byname<char>(name_));
226 install(new ctype_byname<wchar_t>(name_));
227 install(new codecvt_byname<char, char, mbstate_t>(name_));
228 install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
229 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
230 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
231 install(new numpunct_byname<char>(name_));
232 install(new numpunct_byname<wchar_t>(name_));
233 install(new moneypunct_byname<char, false>(name_));
234 install(new moneypunct_byname<char, true>(name_));
235 install(new moneypunct_byname<wchar_t, false>(name_));
236 install(new moneypunct_byname<wchar_t, true>(name_));
237 install(new time_get_byname<char>(name_));
238 install(new time_get_byname<wchar_t>(name_));
239 install(new time_put_byname<char>(name_));
240 install(new time_put_byname<wchar_t>(name_));
241 install(new messages_byname<char>(name_));
242 install(new messages_byname<wchar_t>(name_));
243 #ifndef _LIBCPP_NO_EXCEPTIONS
247 for (unsigned i = 0; i < facets_.size(); ++i)
249 facets_[i]->__release_shared();
252 #endif // _LIBCPP_NO_EXCEPTIONS
255 // NOTE avoid the `base class should be explicitly initialized in the
256 // copy constructor` warning emitted by GCC
257 #if defined(__clang__) || _GNUC_VER >= 406
258 #pragma GCC diagnostic push
259 #pragma GCC diagnostic ignored "-Wextra"
262 locale::__imp::__imp(const __imp& other)
263 : facets_(max<size_t>(N, other.facets_.size())),
266 facets_ = other.facets_;
267 for (unsigned i = 0; i < facets_.size(); ++i)
269 facets_[i]->__add_shared();
272 #if defined(__clang__) || _GNUC_VER >= 406
273 #pragma GCC diagnostic pop
276 locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
280 facets_ = other.facets_;
281 for (unsigned i = 0; i < facets_.size(); ++i)
283 facets_[i]->__add_shared();
284 #ifndef _LIBCPP_NO_EXCEPTIONS
287 #endif // _LIBCPP_NO_EXCEPTIONS
288 if (c & locale::collate)
290 install(new collate_byname<char>(name));
291 install(new collate_byname<wchar_t>(name));
293 if (c & locale::ctype)
295 install(new ctype_byname<char>(name));
296 install(new ctype_byname<wchar_t>(name));
297 install(new codecvt_byname<char, char, mbstate_t>(name));
298 install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
299 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
300 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
302 if (c & locale::monetary)
304 install(new moneypunct_byname<char, false>(name));
305 install(new moneypunct_byname<char, true>(name));
306 install(new moneypunct_byname<wchar_t, false>(name));
307 install(new moneypunct_byname<wchar_t, true>(name));
309 if (c & locale::numeric)
311 install(new numpunct_byname<char>(name));
312 install(new numpunct_byname<wchar_t>(name));
314 if (c & locale::time)
316 install(new time_get_byname<char>(name));
317 install(new time_get_byname<wchar_t>(name));
318 install(new time_put_byname<char>(name));
319 install(new time_put_byname<wchar_t>(name));
321 if (c & locale::messages)
323 install(new messages_byname<char>(name));
324 install(new messages_byname<wchar_t>(name));
326 #ifndef _LIBCPP_NO_EXCEPTIONS
330 for (unsigned i = 0; i < facets_.size(); ++i)
332 facets_[i]->__release_shared();
335 #endif // _LIBCPP_NO_EXCEPTIONS
341 locale::__imp::install_from(const locale::__imp& one)
343 long id = F::id.__get();
344 install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
347 locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
351 facets_ = other.facets_;
352 for (unsigned i = 0; i < facets_.size(); ++i)
354 facets_[i]->__add_shared();
355 #ifndef _LIBCPP_NO_EXCEPTIONS
358 #endif // _LIBCPP_NO_EXCEPTIONS
359 if (c & locale::collate)
361 install_from<_VSTD::collate<char> >(one);
362 install_from<_VSTD::collate<wchar_t> >(one);
364 if (c & locale::ctype)
366 install_from<_VSTD::ctype<char> >(one);
367 install_from<_VSTD::ctype<wchar_t> >(one);
368 install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
369 install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
370 install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
371 install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
373 if (c & locale::monetary)
375 install_from<moneypunct<char, false> >(one);
376 install_from<moneypunct<char, true> >(one);
377 install_from<moneypunct<wchar_t, false> >(one);
378 install_from<moneypunct<wchar_t, true> >(one);
379 install_from<money_get<char> >(one);
380 install_from<money_get<wchar_t> >(one);
381 install_from<money_put<char> >(one);
382 install_from<money_put<wchar_t> >(one);
384 if (c & locale::numeric)
386 install_from<numpunct<char> >(one);
387 install_from<numpunct<wchar_t> >(one);
388 install_from<num_get<char> >(one);
389 install_from<num_get<wchar_t> >(one);
390 install_from<num_put<char> >(one);
391 install_from<num_put<wchar_t> >(one);
393 if (c & locale::time)
395 install_from<time_get<char> >(one);
396 install_from<time_get<wchar_t> >(one);
397 install_from<time_put<char> >(one);
398 install_from<time_put<wchar_t> >(one);
400 if (c & locale::messages)
402 install_from<_VSTD::messages<char> >(one);
403 install_from<_VSTD::messages<wchar_t> >(one);
405 #ifndef _LIBCPP_NO_EXCEPTIONS
409 for (unsigned i = 0; i < facets_.size(); ++i)
411 facets_[i]->__release_shared();
414 #endif // _LIBCPP_NO_EXCEPTIONS
417 locale::__imp::__imp(const __imp& other, facet* f, long id)
418 : facets_(max<size_t>(N, other.facets_.size()+1)),
422 unique_ptr<facet, release> hold(f);
423 facets_ = other.facets_;
424 for (unsigned i = 0; i < other.facets_.size(); ++i)
426 facets_[i]->__add_shared();
427 install(hold.get(), id);
430 locale::__imp::~__imp()
432 for (unsigned i = 0; i < facets_.size(); ++i)
434 facets_[i]->__release_shared();
438 locale::__imp::install(facet* f, long id)
441 unique_ptr<facet, release> hold(f);
442 if (static_cast<size_t>(id) >= facets_.size())
443 facets_.resize(static_cast<size_t>(id+1));
444 if (facets_[static_cast<size_t>(id)])
445 facets_[static_cast<size_t>(id)]->__release_shared();
446 facets_[static_cast<size_t>(id)] = hold.release();
450 locale::__imp::use_facet(long id) const
452 #ifndef _LIBCPP_NO_EXCEPTIONS
455 #endif // _LIBCPP_NO_EXCEPTIONS
456 return facets_[static_cast<size_t>(id)];
462 locale::__imp::make_classic()
464 // only one thread can get in here and it only gets in once
465 static aligned_storage<sizeof(locale)>::type buf;
466 locale* c = reinterpret_cast<locale*>(&buf);
467 c->__locale_ = &make<__imp>(1u);
474 static const locale& c = __imp::make_classic();
479 locale::__imp::make_global()
481 // only one thread can get in here and it only gets in once
482 static aligned_storage<sizeof(locale)>::type buf;
483 auto *obj = ::new (&buf) locale(locale::classic());
490 static locale& g = __imp::make_global();
494 locale::locale() _NOEXCEPT
495 : __locale_(__global().__locale_)
497 __locale_->__add_shared();
500 locale::locale(const locale& l) _NOEXCEPT
501 : __locale_(l.__locale_)
503 __locale_->__add_shared();
508 __locale_->__release_shared();
512 locale::operator=(const locale& other) _NOEXCEPT
514 other.__locale_->__add_shared();
515 __locale_->__release_shared();
516 __locale_ = other.__locale_;
520 locale::locale(const char* name)
521 #ifndef _LIBCPP_NO_EXCEPTIONS
522 : __locale_(name ? new __imp(name)
523 : throw runtime_error("locale constructed with null"))
524 #else // _LIBCPP_NO_EXCEPTIONS
525 : __locale_(new __imp(name))
528 __locale_->__add_shared();
531 locale::locale(const string& name)
532 : __locale_(new __imp(name))
534 __locale_->__add_shared();
537 locale::locale(const locale& other, const char* name, category c)
538 #ifndef _LIBCPP_NO_EXCEPTIONS
539 : __locale_(name ? new __imp(*other.__locale_, name, c)
540 : throw runtime_error("locale constructed with null"))
541 #else // _LIBCPP_NO_EXCEPTIONS
542 : __locale_(new __imp(*other.__locale_, name, c))
545 __locale_->__add_shared();
548 locale::locale(const locale& other, const string& name, category c)
549 : __locale_(new __imp(*other.__locale_, name, c))
551 __locale_->__add_shared();
554 locale::locale(const locale& other, const locale& one, category c)
555 : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
557 __locale_->__add_shared();
563 return __locale_->name();
567 locale::__install_ctor(const locale& other, facet* f, long id)
570 __locale_ = new __imp(*other.__locale_, f, id);
572 __locale_ = other.__locale_;
573 __locale_->__add_shared();
577 locale::global(const locale& loc)
579 locale& g = __global();
583 setlocale(LC_ALL, g.name().c_str());
588 locale::has_facet(id& x) const
590 return __locale_->has_facet(x.__get());
594 locale::use_facet(id& x) const
596 return __locale_->use_facet(x.__get());
600 locale::operator==(const locale& y) const
602 return (__locale_ == y.__locale_)
603 || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
608 locale::facet::~facet()
613 locale::facet::__on_zero_shared() _NOEXCEPT
620 int32_t locale::id::__next_id = 0;
628 void (locale::id::* pmf_)();
630 __fake_bind(void (locale::id::* pmf)(), locale::id* id)
631 : id_(id), pmf_(pmf) {}
633 void operator()() const
644 call_once(__flag_, __fake_bind(&locale::id::__init, this));
651 __id_ = __sync_add_and_fetch(&__next_id, 1);
654 // template <> class collate_byname<char>
656 collate_byname<char>::collate_byname(const char* n, size_t refs)
657 : collate<char>(refs),
658 __l(newlocale(LC_ALL_MASK, n, 0))
661 __throw_runtime_error("collate_byname<char>::collate_byname"
662 " failed to construct for " + string(n));
665 collate_byname<char>::collate_byname(const string& name, size_t refs)
666 : collate<char>(refs),
667 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
670 __throw_runtime_error("collate_byname<char>::collate_byname"
671 " failed to construct for " + name);
674 collate_byname<char>::~collate_byname()
680 collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
681 const char_type* __lo2, const char_type* __hi2) const
683 string_type lhs(__lo1, __hi1);
684 string_type rhs(__lo2, __hi2);
685 int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l);
693 collate_byname<char>::string_type
694 collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
696 const string_type in(lo, hi);
697 string_type out(strxfrm_l(0, in.c_str(), 0, __l), char());
698 strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l);
702 // template <> class collate_byname<wchar_t>
704 collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
705 : collate<wchar_t>(refs),
706 __l(newlocale(LC_ALL_MASK, n, 0))
709 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
710 " failed to construct for " + string(n));
713 collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
714 : collate<wchar_t>(refs),
715 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
718 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
719 " failed to construct for " + name);
722 collate_byname<wchar_t>::~collate_byname()
728 collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
729 const char_type* __lo2, const char_type* __hi2) const
731 string_type lhs(__lo1, __hi1);
732 string_type rhs(__lo2, __hi2);
733 int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l);
741 collate_byname<wchar_t>::string_type
742 collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
744 const string_type in(lo, hi);
745 string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t());
746 wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l);
750 // template <> class ctype<wchar_t>;
752 const ctype_base::mask ctype_base::space;
753 const ctype_base::mask ctype_base::print;
754 const ctype_base::mask ctype_base::cntrl;
755 const ctype_base::mask ctype_base::upper;
756 const ctype_base::mask ctype_base::lower;
757 const ctype_base::mask ctype_base::alpha;
758 const ctype_base::mask ctype_base::digit;
759 const ctype_base::mask ctype_base::punct;
760 const ctype_base::mask ctype_base::xdigit;
761 const ctype_base::mask ctype_base::blank;
762 const ctype_base::mask ctype_base::alnum;
763 const ctype_base::mask ctype_base::graph;
765 locale::id ctype<wchar_t>::id;
767 ctype<wchar_t>::~ctype()
772 ctype<wchar_t>::do_is(mask m, char_type c) const
774 return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
778 ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
780 for (; low != high; ++low, ++vec)
781 *vec = static_cast<mask>(isascii(*low) ?
782 ctype<char>::classic_table()[*low] : 0);
787 ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
789 for (; low != high; ++low)
790 if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
796 ctype<wchar_t>::do_scan_not(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_toupper(char_type c) const
807 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
808 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
809 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
811 return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
813 return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;
818 ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
820 for (; low != high; ++low)
821 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
822 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
823 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
825 *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
828 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low;
834 ctype<wchar_t>::do_tolower(char_type c) const
836 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
837 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
838 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
840 return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
842 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;
847 ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
849 for (; low != high; ++low)
850 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
851 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
852 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
854 *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
857 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low;
863 ctype<wchar_t>::do_widen(char c) const
869 ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
871 for (; low != high; ++low, ++dest)
877 ctype<wchar_t>::do_narrow(char_type c, char dfault) const
880 return static_cast<char>(c);
885 ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
887 for (; low != high; ++low, ++dest)
889 *dest = static_cast<char>(*low);
895 // template <> class ctype<char>;
897 locale::id ctype<char>::id;
899 ctype<char>::ctype(const mask* tab, bool del, size_t refs)
900 : locale::facet(refs),
905 __tab_ = classic_table();
908 ctype<char>::~ctype()
910 if (__tab_ && __del_)
915 ctype<char>::do_toupper(char_type c) const
917 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
919 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
920 #elif defined(__NetBSD__)
921 return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
922 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
924 static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
926 return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;
931 ctype<char>::do_toupper(char_type* low, const char_type* high) const
933 for (; low != high; ++low)
934 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
935 *low = isascii(*low) ?
936 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
937 #elif defined(__NetBSD__)
938 *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
939 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
940 *low = isascii(*low) ?
941 static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
943 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low;
949 ctype<char>::do_tolower(char_type c) const
951 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
953 static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
954 #elif defined(__NetBSD__)
955 return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
956 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
958 static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
960 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c;
965 ctype<char>::do_tolower(char_type* low, const char_type* high) const
967 for (; low != high; ++low)
968 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
969 *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
970 #elif defined(__NetBSD__)
971 *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
972 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
973 *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
975 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low;
981 ctype<char>::do_widen(char c) const
987 ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
989 for (; low != high; ++low, ++dest)
995 ctype<char>::do_narrow(char_type c, char dfault) const
998 return static_cast<char>(c);
1003 ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1005 for (; low != high; ++low, ++dest)
1013 #if defined(__EMSCRIPTEN__)
1014 extern "C" const unsigned short ** __ctype_b_loc();
1015 extern "C" const int ** __ctype_tolower_loc();
1016 extern "C" const int ** __ctype_toupper_loc();
1019 #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
1020 const ctype<char>::mask*
1021 ctype<char>::classic_table() _NOEXCEPT
1023 static _LIBCPP_CONSTEXPR const ctype<char>::mask builtin_table[table_size] = {
1028 cntrl, cntrl | space | blank,
1029 cntrl | space, cntrl | space,
1030 cntrl | space, cntrl | space,
1040 space | blank | print, punct | print,
1041 punct | print, punct | print,
1042 punct | print, punct | print,
1043 punct | print, punct | print,
1044 punct | print, punct | print,
1045 punct | print, punct | print,
1046 punct | print, punct | print,
1047 punct | print, punct | print,
1048 digit | print | xdigit, digit | print | xdigit,
1049 digit | print | xdigit, digit | print | xdigit,
1050 digit | print | xdigit, digit | print | xdigit,
1051 digit | print | xdigit, digit | print | xdigit,
1052 digit | print | xdigit, digit | print | xdigit,
1053 punct | print, punct | print,
1054 punct | print, punct | print,
1055 punct | print, punct | print,
1056 punct | print, upper | xdigit | print | alpha,
1057 upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1058 upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1059 upper | xdigit | print | alpha, upper | print | alpha,
1060 upper | print | alpha, upper | print | alpha,
1061 upper | print | alpha, upper | print | alpha,
1062 upper | print | alpha, upper | print | alpha,
1063 upper | print | alpha, upper | print | alpha,
1064 upper | print | alpha, upper | print | alpha,
1065 upper | print | alpha, upper | print | alpha,
1066 upper | print | alpha, upper | print | alpha,
1067 upper | print | alpha, upper | print | alpha,
1068 upper | print | alpha, upper | print | alpha,
1069 upper | print | alpha, punct | print,
1070 punct | print, punct | print,
1071 punct | print, punct | print,
1072 punct | print, lower | xdigit | print | alpha,
1073 lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1074 lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1075 lower | xdigit | print | alpha, lower | print | alpha,
1076 lower | print | alpha, lower | print | alpha,
1077 lower | print | alpha, lower | print | alpha,
1078 lower | print | alpha, lower | print | alpha,
1079 lower | print | alpha, lower | print | alpha,
1080 lower | print | alpha, lower | print | alpha,
1081 lower | print | alpha, lower | print | alpha,
1082 lower | print | alpha, lower | print | alpha,
1083 lower | print | alpha, lower | print | alpha,
1084 lower | print | alpha, lower | print | alpha,
1085 lower | print | alpha, punct | print,
1086 punct | print, punct | print,
1087 punct | print, cntrl,
1088 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1089 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1090 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1091 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1092 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1093 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1094 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1095 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1097 return builtin_table;
1100 const ctype<char>::mask*
1101 ctype<char>::classic_table() _NOEXCEPT
1103 #if defined(__APPLE__) || defined(__FreeBSD__)
1104 return _DefaultRuneLocale.__runetype;
1105 #elif defined(__NetBSD__)
1106 return _C_ctype_tab_ + 1;
1107 #elif defined(__GLIBC__)
1108 return _LIBCPP_GET_C_LOCALE->__ctype_b;
1110 return __ctype_mask;
1111 #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
1112 return __pctype_func();
1113 #elif defined(__EMSCRIPTEN__)
1114 return *__ctype_b_loc();
1115 #elif defined(_NEWLIB_VERSION)
1116 // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
1119 return (const unsigned int *)__lc_ctype_ptr->obj->mask;
1121 // Platform not supported: abort so the person doing the port knows what to
1123 # warning ctype<char>::classic_table() is not implemented
1124 printf("ctype<char>::classic_table() is not implemented\n");
1131 #if defined(__GLIBC__)
1133 ctype<char>::__classic_lower_table() _NOEXCEPT
1135 return _LIBCPP_GET_C_LOCALE->__ctype_tolower;
1139 ctype<char>::__classic_upper_table() _NOEXCEPT
1141 return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
1145 ctype<char>::__classic_lower_table() _NOEXCEPT
1147 return _C_tolower_tab_ + 1;
1151 ctype<char>::__classic_upper_table() _NOEXCEPT
1153 return _C_toupper_tab_ + 1;
1156 #elif defined(__EMSCRIPTEN__)
1158 ctype<char>::__classic_lower_table() _NOEXCEPT
1160 return *__ctype_tolower_loc();
1164 ctype<char>::__classic_upper_table() _NOEXCEPT
1166 return *__ctype_toupper_loc();
1168 #endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__
1170 // template <> class ctype_byname<char>
1172 ctype_byname<char>::ctype_byname(const char* name, size_t refs)
1173 : ctype<char>(0, false, refs),
1174 __l(newlocale(LC_ALL_MASK, name, 0))
1177 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1178 " failed to construct for " + string(name));
1181 ctype_byname<char>::ctype_byname(const string& name, size_t refs)
1182 : ctype<char>(0, false, refs),
1183 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1186 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1187 " failed to construct for " + name);
1190 ctype_byname<char>::~ctype_byname()
1196 ctype_byname<char>::do_toupper(char_type c) const
1198 return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l));
1202 ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
1204 for (; low != high; ++low)
1205 *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l));
1210 ctype_byname<char>::do_tolower(char_type c) const
1212 return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l));
1216 ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
1218 for (; low != high; ++low)
1219 *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l));
1223 // template <> class ctype_byname<wchar_t>
1225 ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
1226 : ctype<wchar_t>(refs),
1227 __l(newlocale(LC_ALL_MASK, name, 0))
1230 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1231 " failed to construct for " + string(name));
1234 ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
1235 : ctype<wchar_t>(refs),
1236 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1239 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1240 " failed to construct for " + name);
1243 ctype_byname<wchar_t>::~ctype_byname()
1249 ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1251 #ifdef _LIBCPP_WCTYPE_IS_MASK
1252 return static_cast<bool>(iswctype_l(c, m, __l));
1254 bool result = false;
1255 wint_t ch = static_cast<wint_t>(c);
1256 if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0);
1257 if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0);
1258 if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0);
1259 if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0);
1260 if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0);
1261 if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0);
1262 if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0);
1263 if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0);
1264 if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0);
1265 if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0);
1271 ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1273 for (; low != high; ++low, ++vec)
1276 *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
1280 wint_t ch = static_cast<wint_t>(*low);
1281 if (iswspace_l(ch, __l))
1283 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
1284 if (iswprint_l(ch, __l))
1287 if (iswcntrl_l(ch, __l))
1289 if (iswupper_l(ch, __l))
1291 if (iswlower_l(ch, __l))
1293 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
1294 if (iswalpha_l(ch, __l))
1297 if (iswdigit_l(ch, __l))
1299 if (iswpunct_l(ch, __l))
1301 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
1302 if (iswxdigit_l(ch, __l))
1305 #if !defined(__sun__)
1306 if (iswblank_l(ch, __l))
1315 ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1317 for (; low != high; ++low)
1319 #ifdef _LIBCPP_WCTYPE_IS_MASK
1320 if (iswctype_l(*low, m, __l))
1323 wint_t ch = static_cast<wint_t>(*low);
1324 if ((m & space) == space && iswspace_l(ch, __l)) break;
1325 if ((m & print) == print && iswprint_l(ch, __l)) break;
1326 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break;
1327 if ((m & upper) == upper && iswupper_l(ch, __l)) break;
1328 if ((m & lower) == lower && iswlower_l(ch, __l)) break;
1329 if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break;
1330 if ((m & digit) == digit && iswdigit_l(ch, __l)) break;
1331 if ((m & punct) == punct && iswpunct_l(ch, __l)) break;
1332 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break;
1333 if ((m & blank) == blank && iswblank_l(ch, __l)) break;
1340 ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1342 for (; low != high; ++low)
1344 #ifdef _LIBCPP_WCTYPE_IS_MASK
1345 if (!iswctype_l(*low, m, __l))
1348 wint_t ch = static_cast<wint_t>(*low);
1349 if ((m & space) == space && iswspace_l(ch, __l)) continue;
1350 if ((m & print) == print && iswprint_l(ch, __l)) continue;
1351 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue;
1352 if ((m & upper) == upper && iswupper_l(ch, __l)) continue;
1353 if ((m & lower) == lower && iswlower_l(ch, __l)) continue;
1354 if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue;
1355 if ((m & digit) == digit && iswdigit_l(ch, __l)) continue;
1356 if ((m & punct) == punct && iswpunct_l(ch, __l)) continue;
1357 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue;
1358 if ((m & blank) == blank && iswblank_l(ch, __l)) continue;
1366 ctype_byname<wchar_t>::do_toupper(char_type c) const
1368 return towupper_l(c, __l);
1372 ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1374 for (; low != high; ++low)
1375 *low = towupper_l(*low, __l);
1380 ctype_byname<wchar_t>::do_tolower(char_type c) const
1382 return towlower_l(c, __l);
1386 ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1388 for (; low != high; ++low)
1389 *low = towlower_l(*low, __l);
1394 ctype_byname<wchar_t>::do_widen(char c) const
1396 return __libcpp_btowc_l(c, __l);
1400 ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1402 for (; low != high; ++low, ++dest)
1403 *dest = __libcpp_btowc_l(*low, __l);
1408 ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1410 int r = __libcpp_wctob_l(c, __l);
1411 return r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
1415 ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1417 for (; low != high; ++low, ++dest)
1419 int r = __libcpp_wctob_l(*low, __l);
1420 *dest = r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
1425 // template <> class codecvt<char, char, mbstate_t>
1427 locale::id codecvt<char, char, mbstate_t>::id;
1429 codecvt<char, char, mbstate_t>::~codecvt()
1433 codecvt<char, char, mbstate_t>::result
1434 codecvt<char, char, mbstate_t>::do_out(state_type&,
1435 const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
1436 extern_type* to, extern_type*, extern_type*& to_nxt) const
1443 codecvt<char, char, mbstate_t>::result
1444 codecvt<char, char, mbstate_t>::do_in(state_type&,
1445 const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
1446 intern_type* to, intern_type*, intern_type*& to_nxt) const
1453 codecvt<char, char, mbstate_t>::result
1454 codecvt<char, char, mbstate_t>::do_unshift(state_type&,
1455 extern_type* to, extern_type*, extern_type*& to_nxt) const
1462 codecvt<char, char, mbstate_t>::do_encoding() const _NOEXCEPT
1468 codecvt<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
1474 codecvt<char, char, mbstate_t>::do_length(state_type&,
1475 const extern_type* frm, const extern_type* end, size_t mx) const
1477 return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
1481 codecvt<char, char, mbstate_t>::do_max_length() const _NOEXCEPT
1486 // template <> class codecvt<wchar_t, char, mbstate_t>
1488 locale::id codecvt<wchar_t, char, mbstate_t>::id;
1490 codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1491 : locale::facet(refs),
1492 __l(_LIBCPP_GET_C_LOCALE)
1496 codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1497 : locale::facet(refs),
1498 __l(newlocale(LC_ALL_MASK, nm, 0))
1501 __throw_runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1502 " failed to construct for " + string(nm));
1505 codecvt<wchar_t, char, mbstate_t>::~codecvt()
1507 if (__l != _LIBCPP_GET_C_LOCALE)
1511 codecvt<wchar_t, char, mbstate_t>::result
1512 codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
1513 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
1514 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1516 // look for first internal null in frm
1517 const intern_type* fend = frm;
1518 for (; fend != frm_end; ++fend)
1521 // loop over all null-terminated sequences in frm
1523 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1525 // save state in case it is needed to recover to_nxt on error
1526 mbstate_t save_state = st;
1527 size_t n = __libcpp_wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1528 static_cast<size_t>(to_end-to), &st, __l);
1529 if (n == size_t(-1))
1531 // need to recover to_nxt
1532 for (to_nxt = to; frm != frm_nxt; ++frm)
1534 n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l);
1535 if (n == size_t(-1))
1545 if (to_nxt == to_end)
1547 if (fend != frm_end) // set up next null terminated sequence
1549 // Try to write the terminating null
1550 extern_type tmp[MB_LEN_MAX];
1551 n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l);
1552 if (n == size_t(-1)) // on error
1554 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1556 for (extern_type* p = tmp; n; --n) // write it
1559 // look for next null in frm
1560 for (fend = frm_nxt; fend != frm_end; ++fend)
1565 return frm_nxt == frm_end ? ok : partial;
1568 codecvt<wchar_t, char, mbstate_t>::result
1569 codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
1570 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
1571 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1573 // look for first internal null in frm
1574 const extern_type* fend = frm;
1575 for (; fend != frm_end; ++fend)
1578 // loop over all null-terminated sequences in frm
1580 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1582 // save state in case it is needed to recover to_nxt on error
1583 mbstate_t save_state = st;
1584 size_t n = __libcpp_mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1585 static_cast<size_t>(to_end-to), &st, __l);
1586 if (n == size_t(-1))
1588 // need to recover to_nxt
1589 for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1591 n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
1610 return frm_nxt == frm_end ? ok : partial;
1612 if (n == size_t(-1))
1615 if (to_nxt == to_end)
1617 if (fend != frm_end) // set up next null terminated sequence
1619 // Try to write the terminating null
1620 n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1621 if (n != 0) // on error
1625 // look for next null in frm
1626 for (fend = frm_nxt; fend != frm_end; ++fend)
1631 return frm_nxt == frm_end ? ok : partial;
1634 codecvt<wchar_t, char, mbstate_t>::result
1635 codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1636 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1639 extern_type tmp[MB_LEN_MAX];
1640 size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l);
1641 if (n == size_t(-1) || n == 0) // on error
1644 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1646 for (extern_type* p = tmp; n; --n) // write it
1652 codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
1654 if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)
1657 // stateless encoding
1658 if (__l == 0 || __libcpp_mb_cur_max_l(__l) == 1) // there are no known constant length encodings
1659 return 1; // which take more than 1 char to form a wchar_t
1664 codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
1670 codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1671 const extern_type* frm, const extern_type* frm_end, size_t mx) const
1674 for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1676 size_t n = __libcpp_mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l);
1696 codecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
1698 return __l == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l));
1702 // UTF-32 UTF-16 UTF-8 # of code points
1703 // first second first second third fourth
1704 // 000000 - 00007F 0000 - 007F 00 - 7F 127
1705 // 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1706 // 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1707 // 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1708 // 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1709 // 00D800 - 00DFFF invalid
1710 // 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1711 // 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1712 // 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1713 // 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1716 codecvt_base::result
1717 utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1718 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1719 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1723 if (mode & generate_header)
1725 if (to_end-to_nxt < 3)
1726 return codecvt_base::partial;
1727 *to_nxt++ = static_cast<uint8_t>(0xEF);
1728 *to_nxt++ = static_cast<uint8_t>(0xBB);
1729 *to_nxt++ = static_cast<uint8_t>(0xBF);
1731 for (; frm_nxt < frm_end; ++frm_nxt)
1733 uint16_t wc1 = *frm_nxt;
1735 return codecvt_base::error;
1738 if (to_end-to_nxt < 1)
1739 return codecvt_base::partial;
1740 *to_nxt++ = static_cast<uint8_t>(wc1);
1742 else if (wc1 < 0x0800)
1744 if (to_end-to_nxt < 2)
1745 return codecvt_base::partial;
1746 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1747 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1749 else if (wc1 < 0xD800)
1751 if (to_end-to_nxt < 3)
1752 return codecvt_base::partial;
1753 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1754 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1755 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1757 else if (wc1 < 0xDC00)
1759 if (frm_end-frm_nxt < 2)
1760 return codecvt_base::partial;
1761 uint16_t wc2 = frm_nxt[1];
1762 if ((wc2 & 0xFC00) != 0xDC00)
1763 return codecvt_base::error;
1764 if (to_end-to_nxt < 4)
1765 return codecvt_base::partial;
1766 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1767 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1768 return codecvt_base::error;
1770 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1771 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1772 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1773 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1774 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1776 else if (wc1 < 0xE000)
1778 return codecvt_base::error;
1782 if (to_end-to_nxt < 3)
1783 return codecvt_base::partial;
1784 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1785 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1786 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1789 return codecvt_base::ok;
1793 codecvt_base::result
1794 utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1795 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1796 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1800 if (mode & generate_header)
1802 if (to_end-to_nxt < 3)
1803 return codecvt_base::partial;
1804 *to_nxt++ = static_cast<uint8_t>(0xEF);
1805 *to_nxt++ = static_cast<uint8_t>(0xBB);
1806 *to_nxt++ = static_cast<uint8_t>(0xBF);
1808 for (; frm_nxt < frm_end; ++frm_nxt)
1810 uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1812 return codecvt_base::error;
1815 if (to_end-to_nxt < 1)
1816 return codecvt_base::partial;
1817 *to_nxt++ = static_cast<uint8_t>(wc1);
1819 else if (wc1 < 0x0800)
1821 if (to_end-to_nxt < 2)
1822 return codecvt_base::partial;
1823 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1824 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1826 else if (wc1 < 0xD800)
1828 if (to_end-to_nxt < 3)
1829 return codecvt_base::partial;
1830 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1831 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1832 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1834 else if (wc1 < 0xDC00)
1836 if (frm_end-frm_nxt < 2)
1837 return codecvt_base::partial;
1838 uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1839 if ((wc2 & 0xFC00) != 0xDC00)
1840 return codecvt_base::error;
1841 if (to_end-to_nxt < 4)
1842 return codecvt_base::partial;
1843 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1844 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1845 return codecvt_base::error;
1847 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1848 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1849 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1850 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1851 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1853 else if (wc1 < 0xE000)
1855 return codecvt_base::error;
1859 if (to_end-to_nxt < 3)
1860 return codecvt_base::partial;
1861 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1862 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1863 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1866 return codecvt_base::ok;
1870 codecvt_base::result
1871 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1872 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1873 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1877 if (mode & consume_header)
1879 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1883 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1885 uint8_t c1 = *frm_nxt;
1887 return codecvt_base::error;
1890 *to_nxt = static_cast<uint16_t>(c1);
1895 return codecvt_base::error;
1899 if (frm_end-frm_nxt < 2)
1900 return codecvt_base::partial;
1901 uint8_t c2 = frm_nxt[1];
1902 if ((c2 & 0xC0) != 0x80)
1903 return codecvt_base::error;
1904 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1906 return codecvt_base::error;
1912 if (frm_end-frm_nxt < 3)
1913 return codecvt_base::partial;
1914 uint8_t c2 = frm_nxt[1];
1915 uint8_t c3 = frm_nxt[2];
1919 if ((c2 & 0xE0) != 0xA0)
1920 return codecvt_base::error;
1923 if ((c2 & 0xE0) != 0x80)
1924 return codecvt_base::error;
1927 if ((c2 & 0xC0) != 0x80)
1928 return codecvt_base::error;
1931 if ((c3 & 0xC0) != 0x80)
1932 return codecvt_base::error;
1933 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1934 | ((c2 & 0x3F) << 6)
1937 return codecvt_base::error;
1943 if (frm_end-frm_nxt < 4)
1944 return codecvt_base::partial;
1945 uint8_t c2 = frm_nxt[1];
1946 uint8_t c3 = frm_nxt[2];
1947 uint8_t c4 = frm_nxt[3];
1951 if (!(0x90 <= c2 && c2 <= 0xBF))
1952 return codecvt_base::error;
1955 if ((c2 & 0xF0) != 0x80)
1956 return codecvt_base::error;
1959 if ((c2 & 0xC0) != 0x80)
1960 return codecvt_base::error;
1963 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1964 return codecvt_base::error;
1965 if (to_end-to_nxt < 2)
1966 return codecvt_base::partial;
1967 if ((((c1 & 7UL) << 18) +
1968 ((c2 & 0x3FUL) << 12) +
1969 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
1970 return codecvt_base::error;
1971 *to_nxt = static_cast<uint16_t>(
1973 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1974 | ((c2 & 0x0F) << 2)
1975 | ((c3 & 0x30) >> 4));
1976 *++to_nxt = static_cast<uint16_t>(
1978 | ((c3 & 0x0F) << 6)
1984 return codecvt_base::error;
1987 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1991 codecvt_base::result
1992 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1993 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
1994 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1998 if (mode & consume_header)
2000 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2004 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2006 uint8_t c1 = *frm_nxt;
2008 return codecvt_base::error;
2011 *to_nxt = static_cast<uint32_t>(c1);
2016 return codecvt_base::error;
2020 if (frm_end-frm_nxt < 2)
2021 return codecvt_base::partial;
2022 uint8_t c2 = frm_nxt[1];
2023 if ((c2 & 0xC0) != 0x80)
2024 return codecvt_base::error;
2025 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2027 return codecvt_base::error;
2028 *to_nxt = static_cast<uint32_t>(t);
2033 if (frm_end-frm_nxt < 3)
2034 return codecvt_base::partial;
2035 uint8_t c2 = frm_nxt[1];
2036 uint8_t c3 = frm_nxt[2];
2040 if ((c2 & 0xE0) != 0xA0)
2041 return codecvt_base::error;
2044 if ((c2 & 0xE0) != 0x80)
2045 return codecvt_base::error;
2048 if ((c2 & 0xC0) != 0x80)
2049 return codecvt_base::error;
2052 if ((c3 & 0xC0) != 0x80)
2053 return codecvt_base::error;
2054 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2055 | ((c2 & 0x3F) << 6)
2058 return codecvt_base::error;
2059 *to_nxt = static_cast<uint32_t>(t);
2064 if (frm_end-frm_nxt < 4)
2065 return codecvt_base::partial;
2066 uint8_t c2 = frm_nxt[1];
2067 uint8_t c3 = frm_nxt[2];
2068 uint8_t c4 = frm_nxt[3];
2072 if (!(0x90 <= c2 && c2 <= 0xBF))
2073 return codecvt_base::error;
2076 if ((c2 & 0xF0) != 0x80)
2077 return codecvt_base::error;
2080 if ((c2 & 0xC0) != 0x80)
2081 return codecvt_base::error;
2084 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2085 return codecvt_base::error;
2086 if (to_end-to_nxt < 2)
2087 return codecvt_base::partial;
2088 if ((((c1 & 7UL) << 18) +
2089 ((c2 & 0x3FUL) << 12) +
2090 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2091 return codecvt_base::error;
2092 *to_nxt = static_cast<uint32_t>(
2094 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2095 | ((c2 & 0x0F) << 2)
2096 | ((c3 & 0x30) >> 4));
2097 *++to_nxt = static_cast<uint32_t>(
2099 | ((c3 & 0x0F) << 6)
2105 return codecvt_base::error;
2108 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2113 utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
2114 size_t mx, unsigned long Maxcode = 0x10FFFF,
2115 codecvt_mode mode = codecvt_mode(0))
2117 const uint8_t* frm_nxt = frm;
2118 if (mode & consume_header)
2120 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2124 for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
2126 uint8_t c1 = *frm_nxt;
2139 if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
2141 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
2148 if (frm_end-frm_nxt < 3)
2150 uint8_t c2 = frm_nxt[1];
2151 uint8_t c3 = frm_nxt[2];
2155 if ((c2 & 0xE0) != 0xA0)
2156 return static_cast<int>(frm_nxt - frm);
2159 if ((c2 & 0xE0) != 0x80)
2160 return static_cast<int>(frm_nxt - frm);
2163 if ((c2 & 0xC0) != 0x80)
2164 return static_cast<int>(frm_nxt - frm);
2167 if ((c3 & 0xC0) != 0x80)
2169 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2175 if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
2177 uint8_t c2 = frm_nxt[1];
2178 uint8_t c3 = frm_nxt[2];
2179 uint8_t c4 = frm_nxt[3];
2183 if (!(0x90 <= c2 && c2 <= 0xBF))
2184 return static_cast<int>(frm_nxt - frm);
2187 if ((c2 & 0xF0) != 0x80)
2188 return static_cast<int>(frm_nxt - frm);
2191 if ((c2 & 0xC0) != 0x80)
2192 return static_cast<int>(frm_nxt - frm);
2195 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2197 if ((((c1 & 7UL) << 18) +
2198 ((c2 & 0x3FUL) << 12) +
2199 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2209 return static_cast<int>(frm_nxt - frm);
2213 codecvt_base::result
2214 ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2215 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2216 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2220 if (mode & generate_header)
2222 if (to_end-to_nxt < 3)
2223 return codecvt_base::partial;
2224 *to_nxt++ = static_cast<uint8_t>(0xEF);
2225 *to_nxt++ = static_cast<uint8_t>(0xBB);
2226 *to_nxt++ = static_cast<uint8_t>(0xBF);
2228 for (; frm_nxt < frm_end; ++frm_nxt)
2230 uint32_t wc = *frm_nxt;
2231 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2232 return codecvt_base::error;
2235 if (to_end-to_nxt < 1)
2236 return codecvt_base::partial;
2237 *to_nxt++ = static_cast<uint8_t>(wc);
2239 else if (wc < 0x000800)
2241 if (to_end-to_nxt < 2)
2242 return codecvt_base::partial;
2243 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2244 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2246 else if (wc < 0x010000)
2248 if (to_end-to_nxt < 3)
2249 return codecvt_base::partial;
2250 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2251 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2252 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2254 else // if (wc < 0x110000)
2256 if (to_end-to_nxt < 4)
2257 return codecvt_base::partial;
2258 *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
2259 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2260 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2261 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
2264 return codecvt_base::ok;
2268 codecvt_base::result
2269 utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2270 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2271 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2275 if (mode & consume_header)
2277 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2281 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2283 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2287 return codecvt_base::error;
2288 *to_nxt = static_cast<uint32_t>(c1);
2293 return codecvt_base::error;
2297 if (frm_end-frm_nxt < 2)
2298 return codecvt_base::partial;
2299 uint8_t c2 = frm_nxt[1];
2300 if ((c2 & 0xC0) != 0x80)
2301 return codecvt_base::error;
2302 uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2305 return codecvt_base::error;
2311 if (frm_end-frm_nxt < 3)
2312 return codecvt_base::partial;
2313 uint8_t c2 = frm_nxt[1];
2314 uint8_t c3 = frm_nxt[2];
2318 if ((c2 & 0xE0) != 0xA0)
2319 return codecvt_base::error;
2322 if ((c2 & 0xE0) != 0x80)
2323 return codecvt_base::error;
2326 if ((c2 & 0xC0) != 0x80)
2327 return codecvt_base::error;
2330 if ((c3 & 0xC0) != 0x80)
2331 return codecvt_base::error;
2332 uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2333 | ((c2 & 0x3F) << 6)
2336 return codecvt_base::error;
2342 if (frm_end-frm_nxt < 4)
2343 return codecvt_base::partial;
2344 uint8_t c2 = frm_nxt[1];
2345 uint8_t c3 = frm_nxt[2];
2346 uint8_t c4 = frm_nxt[3];
2350 if (!(0x90 <= c2 && c2 <= 0xBF))
2351 return codecvt_base::error;
2354 if ((c2 & 0xF0) != 0x80)
2355 return codecvt_base::error;
2358 if ((c2 & 0xC0) != 0x80)
2359 return codecvt_base::error;
2362 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2363 return codecvt_base::error;
2364 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2365 | ((c2 & 0x3F) << 12)
2366 | ((c3 & 0x3F) << 6)
2369 return codecvt_base::error;
2375 return codecvt_base::error;
2378 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2383 utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2384 size_t mx, unsigned long Maxcode = 0x10FFFF,
2385 codecvt_mode mode = codecvt_mode(0))
2387 const uint8_t* frm_nxt = frm;
2388 if (mode & consume_header)
2390 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2394 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2396 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2409 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2411 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2417 if (frm_end-frm_nxt < 3)
2419 uint8_t c2 = frm_nxt[1];
2420 uint8_t c3 = frm_nxt[2];
2424 if ((c2 & 0xE0) != 0xA0)
2425 return static_cast<int>(frm_nxt - frm);
2428 if ((c2 & 0xE0) != 0x80)
2429 return static_cast<int>(frm_nxt - frm);
2432 if ((c2 & 0xC0) != 0x80)
2433 return static_cast<int>(frm_nxt - frm);
2436 if ((c3 & 0xC0) != 0x80)
2438 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2444 if (frm_end-frm_nxt < 4)
2446 uint8_t c2 = frm_nxt[1];
2447 uint8_t c3 = frm_nxt[2];
2448 uint8_t c4 = frm_nxt[3];
2452 if (!(0x90 <= c2 && c2 <= 0xBF))
2453 return static_cast<int>(frm_nxt - frm);
2456 if ((c2 & 0xF0) != 0x80)
2457 return static_cast<int>(frm_nxt - frm);
2460 if ((c2 & 0xC0) != 0x80)
2461 return static_cast<int>(frm_nxt - frm);
2464 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2466 if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
2467 ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode)
2476 return static_cast<int>(frm_nxt - frm);
2480 codecvt_base::result
2481 ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2482 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2483 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2487 if (mode & generate_header)
2489 if (to_end-to_nxt < 3)
2490 return codecvt_base::partial;
2491 *to_nxt++ = static_cast<uint8_t>(0xEF);
2492 *to_nxt++ = static_cast<uint8_t>(0xBB);
2493 *to_nxt++ = static_cast<uint8_t>(0xBF);
2495 for (; frm_nxt < frm_end; ++frm_nxt)
2497 uint16_t wc = *frm_nxt;
2498 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2499 return codecvt_base::error;
2502 if (to_end-to_nxt < 1)
2503 return codecvt_base::partial;
2504 *to_nxt++ = static_cast<uint8_t>(wc);
2506 else if (wc < 0x0800)
2508 if (to_end-to_nxt < 2)
2509 return codecvt_base::partial;
2510 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2511 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2513 else // if (wc <= 0xFFFF)
2515 if (to_end-to_nxt < 3)
2516 return codecvt_base::partial;
2517 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2518 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2519 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2522 return codecvt_base::ok;
2526 codecvt_base::result
2527 utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2528 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2529 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2533 if (mode & consume_header)
2535 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2539 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2541 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2545 return codecvt_base::error;
2546 *to_nxt = static_cast<uint16_t>(c1);
2551 return codecvt_base::error;
2555 if (frm_end-frm_nxt < 2)
2556 return codecvt_base::partial;
2557 uint8_t c2 = frm_nxt[1];
2558 if ((c2 & 0xC0) != 0x80)
2559 return codecvt_base::error;
2560 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2563 return codecvt_base::error;
2569 if (frm_end-frm_nxt < 3)
2570 return codecvt_base::partial;
2571 uint8_t c2 = frm_nxt[1];
2572 uint8_t c3 = frm_nxt[2];
2576 if ((c2 & 0xE0) != 0xA0)
2577 return codecvt_base::error;
2580 if ((c2 & 0xE0) != 0x80)
2581 return codecvt_base::error;
2584 if ((c2 & 0xC0) != 0x80)
2585 return codecvt_base::error;
2588 if ((c3 & 0xC0) != 0x80)
2589 return codecvt_base::error;
2590 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2591 | ((c2 & 0x3F) << 6)
2594 return codecvt_base::error;
2600 return codecvt_base::error;
2603 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2608 utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2609 size_t mx, unsigned long Maxcode = 0x10FFFF,
2610 codecvt_mode mode = codecvt_mode(0))
2612 const uint8_t* frm_nxt = frm;
2613 if (mode & consume_header)
2615 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2619 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2621 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2634 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2636 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2642 if (frm_end-frm_nxt < 3)
2644 uint8_t c2 = frm_nxt[1];
2645 uint8_t c3 = frm_nxt[2];
2649 if ((c2 & 0xE0) != 0xA0)
2650 return static_cast<int>(frm_nxt - frm);
2653 if ((c2 & 0xE0) != 0x80)
2654 return static_cast<int>(frm_nxt - frm);
2657 if ((c2 & 0xC0) != 0x80)
2658 return static_cast<int>(frm_nxt - frm);
2661 if ((c3 & 0xC0) != 0x80)
2663 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2672 return static_cast<int>(frm_nxt - frm);
2676 codecvt_base::result
2677 ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2678 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2679 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2683 if (mode & generate_header)
2685 if (to_end-to_nxt < 2)
2686 return codecvt_base::partial;
2687 *to_nxt++ = static_cast<uint8_t>(0xFE);
2688 *to_nxt++ = static_cast<uint8_t>(0xFF);
2690 for (; frm_nxt < frm_end; ++frm_nxt)
2692 uint32_t wc = *frm_nxt;
2693 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2694 return codecvt_base::error;
2697 if (to_end-to_nxt < 2)
2698 return codecvt_base::partial;
2699 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2700 *to_nxt++ = static_cast<uint8_t>(wc);
2704 if (to_end-to_nxt < 4)
2705 return codecvt_base::partial;
2706 uint16_t t = static_cast<uint16_t>(
2708 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2709 | ((wc & 0x00FC00) >> 10));
2710 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2711 *to_nxt++ = static_cast<uint8_t>(t);
2712 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2713 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2714 *to_nxt++ = static_cast<uint8_t>(t);
2717 return codecvt_base::ok;
2721 codecvt_base::result
2722 utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2723 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2724 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2728 if (mode & consume_header)
2730 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2733 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2735 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2736 if ((c1 & 0xFC00) == 0xDC00)
2737 return codecvt_base::error;
2738 if ((c1 & 0xFC00) != 0xD800)
2741 return codecvt_base::error;
2742 *to_nxt = static_cast<uint32_t>(c1);
2747 if (frm_end-frm_nxt < 4)
2748 return codecvt_base::partial;
2749 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2750 if ((c2 & 0xFC00) != 0xDC00)
2751 return codecvt_base::error;
2752 uint32_t t = static_cast<uint32_t>(
2753 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2754 | ((c1 & 0x003F) << 10)
2757 return codecvt_base::error;
2762 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2767 utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2768 size_t mx, unsigned long Maxcode = 0x10FFFF,
2769 codecvt_mode mode = codecvt_mode(0))
2771 const uint8_t* frm_nxt = frm;
2772 if (mode & consume_header)
2774 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2777 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2779 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2780 if ((c1 & 0xFC00) == 0xDC00)
2782 if ((c1 & 0xFC00) != 0xD800)
2790 if (frm_end-frm_nxt < 4)
2792 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2793 if ((c2 & 0xFC00) != 0xDC00)
2795 uint32_t t = static_cast<uint32_t>(
2796 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2797 | ((c1 & 0x003F) << 10)
2804 return static_cast<int>(frm_nxt - frm);
2808 codecvt_base::result
2809 ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2810 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2811 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2815 if (mode & generate_header)
2817 if (to_end - to_nxt < 2)
2818 return codecvt_base::partial;
2819 *to_nxt++ = static_cast<uint8_t>(0xFF);
2820 *to_nxt++ = static_cast<uint8_t>(0xFE);
2822 for (; frm_nxt < frm_end; ++frm_nxt)
2824 uint32_t wc = *frm_nxt;
2825 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2826 return codecvt_base::error;
2829 if (to_end-to_nxt < 2)
2830 return codecvt_base::partial;
2831 *to_nxt++ = static_cast<uint8_t>(wc);
2832 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2836 if (to_end-to_nxt < 4)
2837 return codecvt_base::partial;
2838 uint16_t t = static_cast<uint16_t>(
2840 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2841 | ((wc & 0x00FC00) >> 10));
2842 *to_nxt++ = static_cast<uint8_t>(t);
2843 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2844 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2845 *to_nxt++ = static_cast<uint8_t>(t);
2846 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2849 return codecvt_base::ok;
2853 codecvt_base::result
2854 utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2855 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2856 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2860 if (mode & consume_header)
2862 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2865 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2867 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2868 if ((c1 & 0xFC00) == 0xDC00)
2869 return codecvt_base::error;
2870 if ((c1 & 0xFC00) != 0xD800)
2873 return codecvt_base::error;
2874 *to_nxt = static_cast<uint32_t>(c1);
2879 if (frm_end-frm_nxt < 4)
2880 return codecvt_base::partial;
2881 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2882 if ((c2 & 0xFC00) != 0xDC00)
2883 return codecvt_base::error;
2884 uint32_t t = static_cast<uint32_t>(
2885 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2886 | ((c1 & 0x003F) << 10)
2889 return codecvt_base::error;
2894 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2899 utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2900 size_t mx, unsigned long Maxcode = 0x10FFFF,
2901 codecvt_mode mode = codecvt_mode(0))
2903 const uint8_t* frm_nxt = frm;
2904 if (mode & consume_header)
2906 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2909 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2911 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2912 if ((c1 & 0xFC00) == 0xDC00)
2914 if ((c1 & 0xFC00) != 0xD800)
2922 if (frm_end-frm_nxt < 4)
2924 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2925 if ((c2 & 0xFC00) != 0xDC00)
2927 uint32_t t = static_cast<uint32_t>(
2928 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2929 | ((c1 & 0x003F) << 10)
2936 return static_cast<int>(frm_nxt - frm);
2940 codecvt_base::result
2941 ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2942 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2943 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2947 if (mode & generate_header)
2949 if (to_end-to_nxt < 2)
2950 return codecvt_base::partial;
2951 *to_nxt++ = static_cast<uint8_t>(0xFE);
2952 *to_nxt++ = static_cast<uint8_t>(0xFF);
2954 for (; frm_nxt < frm_end; ++frm_nxt)
2956 uint16_t wc = *frm_nxt;
2957 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2958 return codecvt_base::error;
2959 if (to_end-to_nxt < 2)
2960 return codecvt_base::partial;
2961 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2962 *to_nxt++ = static_cast<uint8_t>(wc);
2964 return codecvt_base::ok;
2968 codecvt_base::result
2969 utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2970 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2971 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2975 if (mode & consume_header)
2977 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2980 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2982 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2983 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2984 return codecvt_base::error;
2988 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2993 utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2994 size_t mx, unsigned long Maxcode = 0x10FFFF,
2995 codecvt_mode mode = codecvt_mode(0))
2997 const uint8_t* frm_nxt = frm;
2998 if (mode & consume_header)
3000 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3003 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3005 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
3006 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3010 return static_cast<int>(frm_nxt - frm);
3014 codecvt_base::result
3015 ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3016 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3017 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3021 if (mode & generate_header)
3023 if (to_end-to_nxt < 2)
3024 return codecvt_base::partial;
3025 *to_nxt++ = static_cast<uint8_t>(0xFF);
3026 *to_nxt++ = static_cast<uint8_t>(0xFE);
3028 for (; frm_nxt < frm_end; ++frm_nxt)
3030 uint16_t wc = *frm_nxt;
3031 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3032 return codecvt_base::error;
3033 if (to_end-to_nxt < 2)
3034 return codecvt_base::partial;
3035 *to_nxt++ = static_cast<uint8_t>(wc);
3036 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3038 return codecvt_base::ok;
3042 codecvt_base::result
3043 utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3044 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3045 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3049 if (mode & consume_header)
3051 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3054 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3056 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3057 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3058 return codecvt_base::error;
3062 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3067 utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3068 size_t mx, unsigned long Maxcode = 0x10FFFF,
3069 codecvt_mode mode = codecvt_mode(0))
3071 const uint8_t* frm_nxt = frm;
3073 if (mode & consume_header)
3075 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3078 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3080 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3081 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3085 return static_cast<int>(frm_nxt - frm);
3088 // template <> class codecvt<char16_t, char, mbstate_t>
3090 locale::id codecvt<char16_t, char, mbstate_t>::id;
3092 codecvt<char16_t, char, mbstate_t>::~codecvt()
3096 codecvt<char16_t, char, mbstate_t>::result
3097 codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
3098 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3099 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3101 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3102 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3103 const uint16_t* _frm_nxt = _frm;
3104 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3105 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3106 uint8_t* _to_nxt = _to;
3107 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3108 frm_nxt = frm + (_frm_nxt - _frm);
3109 to_nxt = to + (_to_nxt - _to);
3113 codecvt<char16_t, char, mbstate_t>::result
3114 codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
3115 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3116 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3118 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3119 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3120 const uint8_t* _frm_nxt = _frm;
3121 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3122 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3123 uint16_t* _to_nxt = _to;
3124 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3125 frm_nxt = frm + (_frm_nxt - _frm);
3126 to_nxt = to + (_to_nxt - _to);
3130 codecvt<char16_t, char, mbstate_t>::result
3131 codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
3132 extern_type* to, extern_type*, extern_type*& to_nxt) const
3139 codecvt<char16_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
3145 codecvt<char16_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
3151 codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
3152 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3154 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3155 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3156 return utf8_to_utf16_length(_frm, _frm_end, mx);
3160 codecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
3165 // template <> class codecvt<char32_t, char, mbstate_t>
3167 locale::id codecvt<char32_t, char, mbstate_t>::id;
3169 codecvt<char32_t, char, mbstate_t>::~codecvt()
3173 codecvt<char32_t, char, mbstate_t>::result
3174 codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
3175 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3176 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3178 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3179 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3180 const uint32_t* _frm_nxt = _frm;
3181 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3182 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3183 uint8_t* _to_nxt = _to;
3184 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3185 frm_nxt = frm + (_frm_nxt - _frm);
3186 to_nxt = to + (_to_nxt - _to);
3190 codecvt<char32_t, char, mbstate_t>::result
3191 codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
3192 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3193 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3195 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3196 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3197 const uint8_t* _frm_nxt = _frm;
3198 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3199 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3200 uint32_t* _to_nxt = _to;
3201 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3202 frm_nxt = frm + (_frm_nxt - _frm);
3203 to_nxt = to + (_to_nxt - _to);
3207 codecvt<char32_t, char, mbstate_t>::result
3208 codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3209 extern_type* to, extern_type*, extern_type*& to_nxt) const
3216 codecvt<char32_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
3222 codecvt<char32_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
3228 codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3229 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3231 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3232 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3233 return utf8_to_ucs4_length(_frm, _frm_end, mx);
3237 codecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
3242 // __codecvt_utf8<wchar_t>
3244 __codecvt_utf8<wchar_t>::result
3245 __codecvt_utf8<wchar_t>::do_out(state_type&,
3246 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3247 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3249 #if defined(_LIBCPP_SHORT_WCHAR)
3250 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3251 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3252 const uint16_t* _frm_nxt = _frm;
3254 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3255 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3256 const uint32_t* _frm_nxt = _frm;
3258 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3259 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3260 uint8_t* _to_nxt = _to;
3261 #if defined(_LIBCPP_SHORT_WCHAR)
3262 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3265 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3268 frm_nxt = frm + (_frm_nxt - _frm);
3269 to_nxt = to + (_to_nxt - _to);
3273 __codecvt_utf8<wchar_t>::result
3274 __codecvt_utf8<wchar_t>::do_in(state_type&,
3275 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3276 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3278 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3279 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3280 const uint8_t* _frm_nxt = _frm;
3281 #if defined(_LIBCPP_SHORT_WCHAR)
3282 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3283 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3284 uint16_t* _to_nxt = _to;
3285 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3288 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3289 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3290 uint32_t* _to_nxt = _to;
3291 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3294 frm_nxt = frm + (_frm_nxt - _frm);
3295 to_nxt = to + (_to_nxt - _to);
3299 __codecvt_utf8<wchar_t>::result
3300 __codecvt_utf8<wchar_t>::do_unshift(state_type&,
3301 extern_type* to, extern_type*, extern_type*& to_nxt) const
3308 __codecvt_utf8<wchar_t>::do_encoding() const _NOEXCEPT
3314 __codecvt_utf8<wchar_t>::do_always_noconv() const _NOEXCEPT
3320 __codecvt_utf8<wchar_t>::do_length(state_type&,
3321 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3323 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3324 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3325 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3329 __codecvt_utf8<wchar_t>::do_max_length() const _NOEXCEPT
3331 if (_Mode_ & consume_header)
3336 // __codecvt_utf8<char16_t>
3338 __codecvt_utf8<char16_t>::result
3339 __codecvt_utf8<char16_t>::do_out(state_type&,
3340 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3341 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3343 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3344 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3345 const uint16_t* _frm_nxt = _frm;
3346 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3347 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3348 uint8_t* _to_nxt = _to;
3349 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3351 frm_nxt = frm + (_frm_nxt - _frm);
3352 to_nxt = to + (_to_nxt - _to);
3356 __codecvt_utf8<char16_t>::result
3357 __codecvt_utf8<char16_t>::do_in(state_type&,
3358 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3359 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3361 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3362 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3363 const uint8_t* _frm_nxt = _frm;
3364 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3365 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3366 uint16_t* _to_nxt = _to;
3367 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3369 frm_nxt = frm + (_frm_nxt - _frm);
3370 to_nxt = to + (_to_nxt - _to);
3374 __codecvt_utf8<char16_t>::result
3375 __codecvt_utf8<char16_t>::do_unshift(state_type&,
3376 extern_type* to, extern_type*, extern_type*& to_nxt) const
3383 __codecvt_utf8<char16_t>::do_encoding() const _NOEXCEPT
3389 __codecvt_utf8<char16_t>::do_always_noconv() const _NOEXCEPT
3395 __codecvt_utf8<char16_t>::do_length(state_type&,
3396 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3398 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3399 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3400 return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3404 __codecvt_utf8<char16_t>::do_max_length() const _NOEXCEPT
3406 if (_Mode_ & consume_header)
3411 // __codecvt_utf8<char32_t>
3413 __codecvt_utf8<char32_t>::result
3414 __codecvt_utf8<char32_t>::do_out(state_type&,
3415 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3416 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3418 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3419 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3420 const uint32_t* _frm_nxt = _frm;
3421 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3422 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3423 uint8_t* _to_nxt = _to;
3424 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3426 frm_nxt = frm + (_frm_nxt - _frm);
3427 to_nxt = to + (_to_nxt - _to);
3431 __codecvt_utf8<char32_t>::result
3432 __codecvt_utf8<char32_t>::do_in(state_type&,
3433 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3434 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3436 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3437 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3438 const uint8_t* _frm_nxt = _frm;
3439 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3440 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3441 uint32_t* _to_nxt = _to;
3442 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3444 frm_nxt = frm + (_frm_nxt - _frm);
3445 to_nxt = to + (_to_nxt - _to);
3449 __codecvt_utf8<char32_t>::result
3450 __codecvt_utf8<char32_t>::do_unshift(state_type&,
3451 extern_type* to, extern_type*, extern_type*& to_nxt) const
3458 __codecvt_utf8<char32_t>::do_encoding() const _NOEXCEPT
3464 __codecvt_utf8<char32_t>::do_always_noconv() const _NOEXCEPT
3470 __codecvt_utf8<char32_t>::do_length(state_type&,
3471 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3473 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3474 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3475 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3479 __codecvt_utf8<char32_t>::do_max_length() const _NOEXCEPT
3481 if (_Mode_ & consume_header)
3486 // __codecvt_utf16<wchar_t, false>
3488 __codecvt_utf16<wchar_t, false>::result
3489 __codecvt_utf16<wchar_t, false>::do_out(state_type&,
3490 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3491 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3493 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3494 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3495 const uint32_t* _frm_nxt = _frm;
3496 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3497 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3498 uint8_t* _to_nxt = _to;
3499 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3501 frm_nxt = frm + (_frm_nxt - _frm);
3502 to_nxt = to + (_to_nxt - _to);
3506 __codecvt_utf16<wchar_t, false>::result
3507 __codecvt_utf16<wchar_t, false>::do_in(state_type&,
3508 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3509 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3511 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3512 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3513 const uint8_t* _frm_nxt = _frm;
3514 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3515 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3516 uint32_t* _to_nxt = _to;
3517 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3519 frm_nxt = frm + (_frm_nxt - _frm);
3520 to_nxt = to + (_to_nxt - _to);
3524 __codecvt_utf16<wchar_t, false>::result
3525 __codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3526 extern_type* to, extern_type*, extern_type*& to_nxt) const
3533 __codecvt_utf16<wchar_t, false>::do_encoding() const _NOEXCEPT
3539 __codecvt_utf16<wchar_t, false>::do_always_noconv() const _NOEXCEPT
3545 __codecvt_utf16<wchar_t, false>::do_length(state_type&,
3546 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3548 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3549 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3550 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3554 __codecvt_utf16<wchar_t, false>::do_max_length() const _NOEXCEPT
3556 if (_Mode_ & consume_header)
3561 // __codecvt_utf16<wchar_t, true>
3563 __codecvt_utf16<wchar_t, true>::result
3564 __codecvt_utf16<wchar_t, true>::do_out(state_type&,
3565 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3566 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3568 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3569 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3570 const uint32_t* _frm_nxt = _frm;
3571 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3572 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3573 uint8_t* _to_nxt = _to;
3574 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3576 frm_nxt = frm + (_frm_nxt - _frm);
3577 to_nxt = to + (_to_nxt - _to);
3581 __codecvt_utf16<wchar_t, true>::result
3582 __codecvt_utf16<wchar_t, true>::do_in(state_type&,
3583 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3584 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3586 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3587 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3588 const uint8_t* _frm_nxt = _frm;
3589 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3590 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3591 uint32_t* _to_nxt = _to;
3592 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3594 frm_nxt = frm + (_frm_nxt - _frm);
3595 to_nxt = to + (_to_nxt - _to);
3599 __codecvt_utf16<wchar_t, true>::result
3600 __codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3601 extern_type* to, extern_type*, extern_type*& to_nxt) const
3608 __codecvt_utf16<wchar_t, true>::do_encoding() const _NOEXCEPT
3614 __codecvt_utf16<wchar_t, true>::do_always_noconv() const _NOEXCEPT
3620 __codecvt_utf16<wchar_t, true>::do_length(state_type&,
3621 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3623 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3624 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3625 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3629 __codecvt_utf16<wchar_t, true>::do_max_length() const _NOEXCEPT
3631 if (_Mode_ & consume_header)
3636 // __codecvt_utf16<char16_t, false>
3638 __codecvt_utf16<char16_t, false>::result
3639 __codecvt_utf16<char16_t, false>::do_out(state_type&,
3640 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3641 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3643 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3644 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3645 const uint16_t* _frm_nxt = _frm;
3646 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3647 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3648 uint8_t* _to_nxt = _to;
3649 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3651 frm_nxt = frm + (_frm_nxt - _frm);
3652 to_nxt = to + (_to_nxt - _to);
3656 __codecvt_utf16<char16_t, false>::result
3657 __codecvt_utf16<char16_t, false>::do_in(state_type&,
3658 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3659 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3661 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3662 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3663 const uint8_t* _frm_nxt = _frm;
3664 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3665 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3666 uint16_t* _to_nxt = _to;
3667 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3669 frm_nxt = frm + (_frm_nxt - _frm);
3670 to_nxt = to + (_to_nxt - _to);
3674 __codecvt_utf16<char16_t, false>::result
3675 __codecvt_utf16<char16_t, false>::do_unshift(state_type&,
3676 extern_type* to, extern_type*, extern_type*& to_nxt) const
3683 __codecvt_utf16<char16_t, false>::do_encoding() const _NOEXCEPT
3689 __codecvt_utf16<char16_t, false>::do_always_noconv() const _NOEXCEPT
3695 __codecvt_utf16<char16_t, false>::do_length(state_type&,
3696 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3698 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3699 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3700 return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3704 __codecvt_utf16<char16_t, false>::do_max_length() const _NOEXCEPT
3706 if (_Mode_ & consume_header)
3711 // __codecvt_utf16<char16_t, true>
3713 __codecvt_utf16<char16_t, true>::result
3714 __codecvt_utf16<char16_t, true>::do_out(state_type&,
3715 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3716 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3718 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3719 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3720 const uint16_t* _frm_nxt = _frm;
3721 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3722 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3723 uint8_t* _to_nxt = _to;
3724 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3726 frm_nxt = frm + (_frm_nxt - _frm);
3727 to_nxt = to + (_to_nxt - _to);
3731 __codecvt_utf16<char16_t, true>::result
3732 __codecvt_utf16<char16_t, true>::do_in(state_type&,
3733 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3734 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3736 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3737 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3738 const uint8_t* _frm_nxt = _frm;
3739 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3740 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3741 uint16_t* _to_nxt = _to;
3742 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3744 frm_nxt = frm + (_frm_nxt - _frm);
3745 to_nxt = to + (_to_nxt - _to);
3749 __codecvt_utf16<char16_t, true>::result
3750 __codecvt_utf16<char16_t, true>::do_unshift(state_type&,
3751 extern_type* to, extern_type*, extern_type*& to_nxt) const
3758 __codecvt_utf16<char16_t, true>::do_encoding() const _NOEXCEPT
3764 __codecvt_utf16<char16_t, true>::do_always_noconv() const _NOEXCEPT
3770 __codecvt_utf16<char16_t, true>::do_length(state_type&,
3771 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3773 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3774 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3775 return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3779 __codecvt_utf16<char16_t, true>::do_max_length() const _NOEXCEPT
3781 if (_Mode_ & consume_header)
3786 // __codecvt_utf16<char32_t, false>
3788 __codecvt_utf16<char32_t, false>::result
3789 __codecvt_utf16<char32_t, false>::do_out(state_type&,
3790 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3791 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3793 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3794 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3795 const uint32_t* _frm_nxt = _frm;
3796 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3797 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3798 uint8_t* _to_nxt = _to;
3799 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3801 frm_nxt = frm + (_frm_nxt - _frm);
3802 to_nxt = to + (_to_nxt - _to);
3806 __codecvt_utf16<char32_t, false>::result
3807 __codecvt_utf16<char32_t, false>::do_in(state_type&,
3808 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3809 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3811 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3812 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3813 const uint8_t* _frm_nxt = _frm;
3814 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3815 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3816 uint32_t* _to_nxt = _to;
3817 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3819 frm_nxt = frm + (_frm_nxt - _frm);
3820 to_nxt = to + (_to_nxt - _to);
3824 __codecvt_utf16<char32_t, false>::result
3825 __codecvt_utf16<char32_t, false>::do_unshift(state_type&,
3826 extern_type* to, extern_type*, extern_type*& to_nxt) const
3833 __codecvt_utf16<char32_t, false>::do_encoding() const _NOEXCEPT
3839 __codecvt_utf16<char32_t, false>::do_always_noconv() const _NOEXCEPT
3845 __codecvt_utf16<char32_t, false>::do_length(state_type&,
3846 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3848 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3849 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3850 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3854 __codecvt_utf16<char32_t, false>::do_max_length() const _NOEXCEPT
3856 if (_Mode_ & consume_header)
3861 // __codecvt_utf16<char32_t, true>
3863 __codecvt_utf16<char32_t, true>::result
3864 __codecvt_utf16<char32_t, true>::do_out(state_type&,
3865 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3866 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3868 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3869 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3870 const uint32_t* _frm_nxt = _frm;
3871 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3872 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3873 uint8_t* _to_nxt = _to;
3874 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3876 frm_nxt = frm + (_frm_nxt - _frm);
3877 to_nxt = to + (_to_nxt - _to);
3881 __codecvt_utf16<char32_t, true>::result
3882 __codecvt_utf16<char32_t, true>::do_in(state_type&,
3883 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3884 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3886 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3887 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3888 const uint8_t* _frm_nxt = _frm;
3889 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3890 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3891 uint32_t* _to_nxt = _to;
3892 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3894 frm_nxt = frm + (_frm_nxt - _frm);
3895 to_nxt = to + (_to_nxt - _to);
3899 __codecvt_utf16<char32_t, true>::result
3900 __codecvt_utf16<char32_t, true>::do_unshift(state_type&,
3901 extern_type* to, extern_type*, extern_type*& to_nxt) const
3908 __codecvt_utf16<char32_t, true>::do_encoding() const _NOEXCEPT
3914 __codecvt_utf16<char32_t, true>::do_always_noconv() const _NOEXCEPT
3920 __codecvt_utf16<char32_t, true>::do_length(state_type&,
3921 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3923 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3924 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3925 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3929 __codecvt_utf16<char32_t, true>::do_max_length() const _NOEXCEPT
3931 if (_Mode_ & consume_header)
3936 // __codecvt_utf8_utf16<wchar_t>
3938 __codecvt_utf8_utf16<wchar_t>::result
3939 __codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
3940 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3941 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3943 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3944 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3945 const uint32_t* _frm_nxt = _frm;
3946 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3947 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3948 uint8_t* _to_nxt = _to;
3949 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3951 frm_nxt = frm + (_frm_nxt - _frm);
3952 to_nxt = to + (_to_nxt - _to);
3956 __codecvt_utf8_utf16<wchar_t>::result
3957 __codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
3958 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3959 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3961 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3962 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3963 const uint8_t* _frm_nxt = _frm;
3964 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3965 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3966 uint32_t* _to_nxt = _to;
3967 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3969 frm_nxt = frm + (_frm_nxt - _frm);
3970 to_nxt = to + (_to_nxt - _to);
3974 __codecvt_utf8_utf16<wchar_t>::result
3975 __codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
3976 extern_type* to, extern_type*, extern_type*& to_nxt) const
3983 __codecvt_utf8_utf16<wchar_t>::do_encoding() const _NOEXCEPT
3989 __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const _NOEXCEPT
3995 __codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
3996 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3998 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3999 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4000 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4004 __codecvt_utf8_utf16<wchar_t>::do_max_length() const _NOEXCEPT
4006 if (_Mode_ & consume_header)
4011 // __codecvt_utf8_utf16<char16_t>
4013 __codecvt_utf8_utf16<char16_t>::result
4014 __codecvt_utf8_utf16<char16_t>::do_out(state_type&,
4015 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4016 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4018 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4019 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4020 const uint16_t* _frm_nxt = _frm;
4021 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4022 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4023 uint8_t* _to_nxt = _to;
4024 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4026 frm_nxt = frm + (_frm_nxt - _frm);
4027 to_nxt = to + (_to_nxt - _to);
4031 __codecvt_utf8_utf16<char16_t>::result
4032 __codecvt_utf8_utf16<char16_t>::do_in(state_type&,
4033 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4034 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4036 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4037 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4038 const uint8_t* _frm_nxt = _frm;
4039 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4040 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4041 uint16_t* _to_nxt = _to;
4042 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4044 frm_nxt = frm + (_frm_nxt - _frm);
4045 to_nxt = to + (_to_nxt - _to);
4049 __codecvt_utf8_utf16<char16_t>::result
4050 __codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
4051 extern_type* to, extern_type*, extern_type*& to_nxt) const
4058 __codecvt_utf8_utf16<char16_t>::do_encoding() const _NOEXCEPT
4064 __codecvt_utf8_utf16<char16_t>::do_always_noconv() const _NOEXCEPT
4070 __codecvt_utf8_utf16<char16_t>::do_length(state_type&,
4071 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4073 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4074 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4075 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4079 __codecvt_utf8_utf16<char16_t>::do_max_length() const _NOEXCEPT
4081 if (_Mode_ & consume_header)
4086 // __codecvt_utf8_utf16<char32_t>
4088 __codecvt_utf8_utf16<char32_t>::result
4089 __codecvt_utf8_utf16<char32_t>::do_out(state_type&,
4090 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4091 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4093 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4094 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4095 const uint32_t* _frm_nxt = _frm;
4096 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4097 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4098 uint8_t* _to_nxt = _to;
4099 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4101 frm_nxt = frm + (_frm_nxt - _frm);
4102 to_nxt = to + (_to_nxt - _to);
4106 __codecvt_utf8_utf16<char32_t>::result
4107 __codecvt_utf8_utf16<char32_t>::do_in(state_type&,
4108 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4109 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4111 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4112 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4113 const uint8_t* _frm_nxt = _frm;
4114 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4115 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4116 uint32_t* _to_nxt = _to;
4117 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4119 frm_nxt = frm + (_frm_nxt - _frm);
4120 to_nxt = to + (_to_nxt - _to);
4124 __codecvt_utf8_utf16<char32_t>::result
4125 __codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
4126 extern_type* to, extern_type*, extern_type*& to_nxt) const
4133 __codecvt_utf8_utf16<char32_t>::do_encoding() const _NOEXCEPT
4139 __codecvt_utf8_utf16<char32_t>::do_always_noconv() const _NOEXCEPT
4145 __codecvt_utf8_utf16<char32_t>::do_length(state_type&,
4146 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4148 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4149 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4150 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4154 __codecvt_utf8_utf16<char32_t>::do_max_length() const _NOEXCEPT
4156 if (_Mode_ & consume_header)
4161 // __narrow_to_utf8<16>
4163 __narrow_to_utf8<16>::~__narrow_to_utf8()
4167 // __narrow_to_utf8<32>
4169 __narrow_to_utf8<32>::~__narrow_to_utf8()
4173 // __widen_from_utf8<16>
4175 __widen_from_utf8<16>::~__widen_from_utf8()
4179 // __widen_from_utf8<32>
4181 __widen_from_utf8<32>::~__widen_from_utf8()
4186 static bool checked_string_to_wchar_convert(wchar_t& dest,
4188 __locale_struct* loc) {
4193 size_t ret = __libcpp_mbrtowc_l(&out, ptr, strlen(ptr), &mb, loc);
4194 if (ret == static_cast<size_t>(-1) || ret == static_cast<size_t>(-2)) {
4201 static bool checked_string_to_char_convert(char& dest,
4203 __locale_struct* __loc) {
4210 // First convert the MBS into a wide char then attempt to narrow it using
4213 if (!checked_string_to_wchar_convert(wout, ptr, __loc))
4216 if ((res = __libcpp_wctob_l(wout, __loc)) != char_traits<char>::eof()) {
4220 // FIXME: Work around specific multibyte sequences that we can reasonable
4221 // translate into a different single byte.
4223 case L'\u00A0': // non-breaking space
4229 _LIBCPP_UNREACHABLE();
4233 // numpunct<char> && numpunct<wchar_t>
4235 locale::id numpunct< char >::id;
4236 locale::id numpunct<wchar_t>::id;
4238 numpunct<char>::numpunct(size_t refs)
4239 : locale::facet(refs),
4240 __decimal_point_('.'),
4241 __thousands_sep_(',')
4245 numpunct<wchar_t>::numpunct(size_t refs)
4246 : locale::facet(refs),
4247 __decimal_point_(L'.'),
4248 __thousands_sep_(L',')
4252 numpunct<char>::~numpunct()
4256 numpunct<wchar_t>::~numpunct()
4260 char numpunct< char >::do_decimal_point() const {return __decimal_point_;}
4261 wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
4263 char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;}
4264 wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
4266 string numpunct< char >::do_grouping() const {return __grouping_;}
4267 string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
4269 string numpunct< char >::do_truename() const {return "true";}
4270 wstring numpunct<wchar_t>::do_truename() const {return L"true";}
4272 string numpunct< char >::do_falsename() const {return "false";}
4273 wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
4275 // numpunct_byname<char>
4277 numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4278 : numpunct<char>(refs)
4283 numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4284 : numpunct<char>(refs)
4289 numpunct_byname<char>::~numpunct_byname()
4294 numpunct_byname<char>::__init(const char* nm)
4296 if (strcmp(nm, "C") != 0)
4298 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
4300 __throw_runtime_error("numpunct_byname<char>::numpunct_byname"
4301 " failed to construct for " + string(nm));
4303 lconv* lc = __libcpp_localeconv_l(loc.get());
4304 checked_string_to_char_convert(__decimal_point_, lc->decimal_point,
4306 checked_string_to_char_convert(__thousands_sep_, lc->thousands_sep,
4308 __grouping_ = lc->grouping;
4309 // localization for truename and falsename is not available
4313 // numpunct_byname<wchar_t>
4315 numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4316 : numpunct<wchar_t>(refs)
4321 numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4322 : numpunct<wchar_t>(refs)
4327 numpunct_byname<wchar_t>::~numpunct_byname()
4332 numpunct_byname<wchar_t>::__init(const char* nm)
4334 if (strcmp(nm, "C") != 0)
4336 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
4338 __throw_runtime_error("numpunct_byname<wchar_t>::numpunct_byname"
4339 " failed to construct for " + string(nm));
4341 lconv* lc = __libcpp_localeconv_l(loc.get());
4342 checked_string_to_wchar_convert(__decimal_point_, lc->decimal_point,
4344 checked_string_to_wchar_convert(__thousands_sep_, lc->thousands_sep,
4346 __grouping_ = lc->grouping;
4347 // localization for truename and falsename is not available
4354 __num_get_base::__get_base(ios_base& iob)
4356 ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4357 if (__basefield == ios_base::oct)
4359 else if (__basefield == ios_base::hex)
4361 else if (__basefield == 0)
4366 const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4369 __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4370 ios_base::iostate& __err)
4372 if (__grouping.size() != 0)
4374 reverse(__g, __g_end);
4375 const char* __ig = __grouping.data();
4376 const char* __eg = __ig + __grouping.size();
4377 for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4379 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4381 if (static_cast<unsigned>(*__ig) != *__r)
4383 __err = ios_base::failbit;
4387 if (__eg - __ig > 1)
4390 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4392 if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
4393 __err = ios_base::failbit;
4399 __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4400 ios_base::fmtflags __flags)
4402 if (__flags & ios_base::showpos)
4404 if (__flags & ios_base::showbase)
4407 *__fmtp++ = *__len++;
4408 if ((__flags & ios_base::basefield) == ios_base::oct)
4410 else if ((__flags & ios_base::basefield) == ios_base::hex)
4412 if (__flags & ios_base::uppercase)
4424 __num_put_base::__format_float(char* __fmtp, const char* __len,
4425 ios_base::fmtflags __flags)
4427 bool specify_precision = true;
4428 if (__flags & ios_base::showpos)
4430 if (__flags & ios_base::showpoint)
4432 ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4433 bool uppercase = (__flags & ios_base::uppercase) != 0;
4434 if (floatfield == (ios_base::fixed | ios_base::scientific))
4435 specify_precision = false;
4442 *__fmtp++ = *__len++;
4443 if (floatfield == ios_base::fixed)
4450 else if (floatfield == ios_base::scientific)
4457 else if (floatfield == (ios_base::fixed | ios_base::scientific))
4471 return specify_precision;
4475 __num_put_base::__identify_padding(char* __nb, char* __ne,
4476 const ios_base& __iob)
4478 switch (__iob.flags() & ios_base::adjustfield)
4480 case ios_base::internal:
4481 if (__nb[0] == '-' || __nb[0] == '+')
4483 if (__ne - __nb >= 2 && __nb[0] == '0'
4484 && (__nb[1] == 'x' || __nb[1] == 'X'))
4487 case ios_base::left:
4489 case ios_base::right:
4502 static string weeks[14];
4503 weeks[0] = "Sunday";
4504 weeks[1] = "Monday";
4505 weeks[2] = "Tuesday";
4506 weeks[3] = "Wednesday";
4507 weeks[4] = "Thursday";
4508 weeks[5] = "Friday";
4509 weeks[6] = "Saturday";
4524 static wstring weeks[14];
4525 weeks[0] = L"Sunday";
4526 weeks[1] = L"Monday";
4527 weeks[2] = L"Tuesday";
4528 weeks[3] = L"Wednesday";
4529 weeks[4] = L"Thursday";
4530 weeks[5] = L"Friday";
4531 weeks[6] = L"Saturday";
4544 __time_get_c_storage<char>::__weeks() const
4546 static const string* weeks = init_weeks();
4552 __time_get_c_storage<wchar_t>::__weeks() const
4554 static const wstring* weeks = init_wweeks();
4562 static string months[24];
4563 months[0] = "January";
4564 months[1] = "February";
4565 months[2] = "March";
4566 months[3] = "April";
4570 months[7] = "August";
4571 months[8] = "September";
4572 months[9] = "October";
4573 months[10] = "November";
4574 months[11] = "December";
4594 static wstring months[24];
4595 months[0] = L"January";
4596 months[1] = L"February";
4597 months[2] = L"March";
4598 months[3] = L"April";
4600 months[5] = L"June";
4601 months[6] = L"July";
4602 months[7] = L"August";
4603 months[8] = L"September";
4604 months[9] = L"October";
4605 months[10] = L"November";
4606 months[11] = L"December";
4607 months[12] = L"Jan";
4608 months[13] = L"Feb";
4609 months[14] = L"Mar";
4610 months[15] = L"Apr";
4611 months[16] = L"May";
4612 months[17] = L"Jun";
4613 months[18] = L"Jul";
4614 months[19] = L"Aug";
4615 months[20] = L"Sep";
4616 months[21] = L"Oct";
4617 months[22] = L"Nov";
4618 months[23] = L"Dec";
4624 __time_get_c_storage<char>::__months() const
4626 static const string* months = init_months();
4632 __time_get_c_storage<wchar_t>::__months() const
4634 static const wstring* months = init_wmonths();
4642 static string am_pm[24];
4652 static wstring am_pm[24];
4660 __time_get_c_storage<char>::__am_pm() const
4662 static const string* am_pm = init_am_pm();
4668 __time_get_c_storage<wchar_t>::__am_pm() const
4670 static const wstring* am_pm = init_wam_pm();
4676 __time_get_c_storage<char>::__x() const
4678 static string s("%m/%d/%y");
4684 __time_get_c_storage<wchar_t>::__x() const
4686 static wstring s(L"%m/%d/%y");
4692 __time_get_c_storage<char>::__X() const
4694 static string s("%H:%M:%S");
4700 __time_get_c_storage<wchar_t>::__X() const
4702 static wstring s(L"%H:%M:%S");
4708 __time_get_c_storage<char>::__c() const
4710 static string s("%a %b %d %H:%M:%S %Y");
4716 __time_get_c_storage<wchar_t>::__c() const
4718 static wstring s(L"%a %b %d %H:%M:%S %Y");
4724 __time_get_c_storage<char>::__r() const
4726 static string s("%I:%M:%S %p");
4732 __time_get_c_storage<wchar_t>::__r() const
4734 static wstring s(L"%I:%M:%S %p");
4740 __time_get::__time_get(const char* nm)
4741 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
4744 __throw_runtime_error("time_get_byname"
4745 " failed to construct for " + string(nm));
4748 __time_get::__time_get(const string& nm)
4749 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
4752 __throw_runtime_error("time_get_byname"
4753 " failed to construct for " + nm);
4756 __time_get::~__time_get()
4760 #if defined(__clang__)
4761 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
4763 #if defined(__GNUG__)
4764 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
4769 __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
4785 size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);
4791 if (ct.is(ctype_base::space, *bb))
4793 result.push_back(' ');
4794 for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
4799 ios_base::iostate err = ios_base::goodbit;
4800 ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
4805 result.push_back('%');
4807 result.push_back('A');
4809 result.push_back('a');
4814 i = __scan_keyword(w, be, this->__months_, this->__months_+24,
4819 result.push_back('%');
4821 result.push_back('B');
4823 result.push_back('b');
4824 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4825 result.back() = 'm';
4829 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4832 i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
4833 ct, err, false) - this->__am_pm_;
4836 result.push_back('%');
4837 result.push_back('p');
4843 if (ct.is(ctype_base::digit, *bb))
4845 switch(__get_up_to_n_digits(bb, be, err, ct, 4))
4848 result.push_back('%');
4849 result.push_back('w');
4852 result.push_back('%');
4853 result.push_back('u');
4856 result.push_back('%');
4857 result.push_back('I');
4860 result.push_back('%');
4861 result.push_back('m');
4864 result.push_back('%');
4865 result.push_back('H');
4868 result.push_back('%');
4869 result.push_back('d');
4872 result.push_back('%');
4873 result.push_back('M');
4876 result.push_back('%');
4877 result.push_back('S');
4880 result.push_back('%');
4881 result.push_back('y');
4884 result.push_back('%');
4885 result.push_back('j');
4888 result.push_back('%');
4889 result.push_back('Y');
4892 for (; w != bb; ++w)
4893 result.push_back(*w);
4900 result.push_back('%');
4901 result.push_back('%');
4905 result.push_back(*bb);
4911 #if defined(__clang__)
4912 #pragma clang diagnostic ignored "-Wmissing-braces"
4917 __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
4933 strftime_l(buf, countof(buf), f, &t, __loc_);
4935 wchar_t* wbb = wbuf;
4937 const char* bb = buf;
4938 size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
4939 if (j == size_t(-1))
4940 __throw_runtime_error("locale not supported");
4941 wchar_t* wbe = wbb + j;
4945 if (ct.is(ctype_base::space, *wbb))
4947 result.push_back(L' ');
4948 for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
4953 ios_base::iostate err = ios_base::goodbit;
4954 ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
4959 result.push_back(L'%');
4961 result.push_back(L'A');
4963 result.push_back(L'a');
4968 i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
4973 result.push_back(L'%');
4975 result.push_back(L'B');
4977 result.push_back(L'b');
4978 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4979 result.back() = L'm';
4983 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4986 i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
4987 ct, err, false) - this->__am_pm_;
4990 result.push_back(L'%');
4991 result.push_back(L'p');
4997 if (ct.is(ctype_base::digit, *wbb))
4999 switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
5002 result.push_back(L'%');
5003 result.push_back(L'w');
5006 result.push_back(L'%');
5007 result.push_back(L'u');
5010 result.push_back(L'%');
5011 result.push_back(L'I');
5014 result.push_back(L'%');
5015 result.push_back(L'm');
5018 result.push_back(L'%');
5019 result.push_back(L'H');
5022 result.push_back(L'%');
5023 result.push_back(L'd');
5026 result.push_back(L'%');
5027 result.push_back(L'M');
5030 result.push_back(L'%');
5031 result.push_back(L'S');
5034 result.push_back(L'%');
5035 result.push_back(L'y');
5038 result.push_back(L'%');
5039 result.push_back(L'j');
5042 result.push_back(L'%');
5043 result.push_back(L'Y');
5046 for (; w != wbb; ++w)
5047 result.push_back(*w);
5052 if (ct.narrow(*wbb, 0) == '%')
5054 result.push_back(L'%');
5055 result.push_back(L'%');
5059 result.push_back(*wbb);
5067 __time_get_storage<char>::init(const ctype<char>& ct)
5072 for (int i = 0; i < 7; ++i)
5075 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5077 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5078 __weeks_[i+7] = buf;
5081 for (int i = 0; i < 12; ++i)
5084 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5086 strftime_l(buf, countof(buf), "%b", &t, __loc_);
5087 __months_[i+12] = buf;
5091 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5094 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5096 __c_ = __analyze('c', ct);
5097 __r_ = __analyze('r', ct);
5098 __x_ = __analyze('x', ct);
5099 __X_ = __analyze('X', ct);
5104 __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
5112 for (int i = 0; i < 7; ++i)
5115 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5117 const char* bb = buf;
5118 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5119 if (j == size_t(-1))
5120 __throw_runtime_error("locale not supported");
5122 __weeks_[i].assign(wbuf, wbe);
5123 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5126 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5127 if (j == size_t(-1))
5128 __throw_runtime_error("locale not supported");
5130 __weeks_[i+7].assign(wbuf, wbe);
5133 for (int i = 0; i < 12; ++i)
5136 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5138 const char* bb = buf;
5139 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5140 if (j == size_t(-1))
5141 __throw_runtime_error("locale not supported");
5143 __months_[i].assign(wbuf, wbe);
5144 strftime_l(buf, countof(buf), "%b", &t, __loc_);
5147 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5148 if (j == size_t(-1))
5149 __throw_runtime_error("locale not supported");
5151 __months_[i+12].assign(wbuf, wbe);
5155 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5157 const char* bb = buf;
5158 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5159 if (j == size_t(-1))
5160 __throw_runtime_error("locale not supported");
5162 __am_pm_[0].assign(wbuf, wbe);
5164 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5167 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5168 if (j == size_t(-1))
5169 __throw_runtime_error("locale not supported");
5171 __am_pm_[1].assign(wbuf, wbe);
5172 __c_ = __analyze('c', ct);
5173 __r_ = __analyze('r', ct);
5174 __x_ = __analyze('x', ct);
5175 __X_ = __analyze('X', ct);
5178 template <class CharT>
5179 struct _LIBCPP_HIDDEN __time_get_temp
5180 : public ctype_byname<CharT>
5182 explicit __time_get_temp(const char* nm)
5183 : ctype_byname<CharT>(nm, 1) {}
5184 explicit __time_get_temp(const string& nm)
5185 : ctype_byname<CharT>(nm, 1) {}
5189 __time_get_storage<char>::__time_get_storage(const char* __nm)
5192 const __time_get_temp<char> ct(__nm);
5197 __time_get_storage<char>::__time_get_storage(const string& __nm)
5200 const __time_get_temp<char> ct(__nm);
5205 __time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5208 const __time_get_temp<wchar_t> ct(__nm);
5213 __time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5216 const __time_get_temp<wchar_t> ct(__nm);
5221 time_base::dateorder
5222 __time_get_storage<char>::__do_date_order() const
5225 for (i = 0; i < __x_.size(); ++i)
5233 for (++i; i < __x_.size(); ++i)
5236 if (i == __x_.size())
5242 for (++i; i < __x_.size(); ++i)
5245 if (i == __x_.size())
5249 return time_base::ymd;
5252 for (++i; i < __x_.size(); ++i)
5255 if (i == __x_.size())
5259 return time_base::ydm;
5264 for (++i; i < __x_.size(); ++i)
5267 if (i == __x_.size())
5272 for (++i; i < __x_.size(); ++i)
5275 if (i == __x_.size())
5278 if (__x_[i] == 'y' || __x_[i] == 'Y')
5279 return time_base::mdy;
5284 for (++i; i < __x_.size(); ++i)
5287 if (i == __x_.size())
5292 for (++i; i < __x_.size(); ++i)
5295 if (i == __x_.size())
5298 if (__x_[i] == 'y' || __x_[i] == 'Y')
5299 return time_base::dmy;
5304 return time_base::no_order;
5308 time_base::dateorder
5309 __time_get_storage<wchar_t>::__do_date_order() const
5312 for (i = 0; i < __x_.size(); ++i)
5313 if (__x_[i] == L'%')
5320 for (++i; i < __x_.size(); ++i)
5321 if (__x_[i] == L'%')
5323 if (i == __x_.size())
5329 for (++i; i < __x_.size(); ++i)
5330 if (__x_[i] == L'%')
5332 if (i == __x_.size())
5335 if (__x_[i] == L'd')
5336 return time_base::ymd;
5339 for (++i; i < __x_.size(); ++i)
5340 if (__x_[i] == L'%')
5342 if (i == __x_.size())
5345 if (__x_[i] == L'm')
5346 return time_base::ydm;
5351 for (++i; i < __x_.size(); ++i)
5352 if (__x_[i] == L'%')
5354 if (i == __x_.size())
5357 if (__x_[i] == L'd')
5359 for (++i; i < __x_.size(); ++i)
5360 if (__x_[i] == L'%')
5362 if (i == __x_.size())
5365 if (__x_[i] == L'y' || __x_[i] == L'Y')
5366 return time_base::mdy;
5371 for (++i; i < __x_.size(); ++i)
5372 if (__x_[i] == L'%')
5374 if (i == __x_.size())
5377 if (__x_[i] == L'm')
5379 for (++i; i < __x_.size(); ++i)
5380 if (__x_[i] == L'%')
5382 if (i == __x_.size())
5385 if (__x_[i] == L'y' || __x_[i] == L'Y')
5386 return time_base::dmy;
5391 return time_base::no_order;
5396 __time_put::__time_put(const char* nm)
5397 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5400 __throw_runtime_error("time_put_byname"
5401 " failed to construct for " + string(nm));
5404 __time_put::__time_put(const string& nm)
5405 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5408 __throw_runtime_error("time_put_byname"
5409 " failed to construct for " + nm);
5412 __time_put::~__time_put()
5414 if (__loc_ != _LIBCPP_GET_C_LOCALE)
5419 __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5420 char __fmt, char __mod) const
5422 char fmt[] = {'%', __fmt, __mod, 0};
5424 swap(fmt[1], fmt[2]);
5425 size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
5430 __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5431 char __fmt, char __mod) const
5434 char* __ne = __nar + 100;
5435 __do_put(__nar, __ne, __tm, __fmt, __mod);
5437 const char* __nb = __nar;
5438 size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
5439 if (j == size_t(-1))
5440 __throw_runtime_error("locale not supported");
5444 // moneypunct_byname
5446 template <class charT>
5449 __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
5450 bool intl, char cs_precedes, char sep_by_space, char sign_posn,
5453 const char sign = static_cast<char>(money_base::sign);
5454 const char space = static_cast<char>(money_base::space);
5455 const char none = static_cast<char>(money_base::none);
5456 const char symbol = static_cast<char>(money_base::symbol);
5457 const char value = static_cast<char>(money_base::value);
5458 const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
5460 // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5461 // function'. "Space between sign and symbol or value" means that
5462 // if the sign is adjacent to the symbol, there's a space between
5463 // them, and otherwise there's a space between the sign and value.
5465 // C11's localeconv specifies that the fourth character of an
5466 // international curr_symbol is used to separate the sign and
5467 // value when sep_by_space says to do so. C++ can't represent
5468 // that, so we just use a space. When sep_by_space says to
5469 // separate the symbol and value-or-sign with a space, we rearrange the
5470 // curr_symbol to put its spacing character on the correct side of
5473 // We also need to avoid adding an extra space between the sign
5474 // and value when the currency symbol is suppressed (by not
5475 // setting showbase). We match glibc's strfmon by interpreting
5476 // sep_by_space==1 as "omit the space when the currency symbol is
5479 // Users who want to get this right should use ICU instead.
5481 switch (cs_precedes)
5483 case 0: // value before curr_symbol
5484 if (symbol_contains_sep) {
5485 // Move the separator to before the symbol, to place it
5486 // between the value and symbol.
5487 rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,
5488 __curr_symbol_.end());
5492 case 0: // Parentheses surround the quantity and currency symbol.
5493 pat.field[0] = sign;
5494 pat.field[1] = value;
5495 pat.field[2] = none; // Any space appears in the symbol.
5496 pat.field[3] = symbol;
5497 switch (sep_by_space)
5499 case 0: // No space separates the currency symbol and value.
5500 // This case may have changed between C99 and C11;
5501 // assume the currency symbol matches the intention.
5502 case 2: // Space between sign and currency or value.
5503 // The "sign" is two parentheses, so no space here either.
5505 case 1: // Space between currency-and-sign or currency and value.
5506 if (!symbol_contains_sep) {
5507 // We insert the space into the symbol instead of
5508 // setting pat.field[2]=space so that when
5509 // showbase is not set, the space goes away too.
5510 __curr_symbol_.insert(0, 1, space_char);
5517 case 1: // The sign string precedes the quantity and currency symbol.
5518 pat.field[0] = sign;
5519 pat.field[3] = symbol;
5520 switch (sep_by_space)
5522 case 0: // No space separates the currency symbol and value.
5523 pat.field[1] = value;
5524 pat.field[2] = none;
5526 case 1: // Space between currency-and-sign or currency and value.
5527 pat.field[1] = value;
5528 pat.field[2] = none;
5529 if (!symbol_contains_sep) {
5530 // We insert the space into the symbol instead of
5531 // setting pat.field[2]=space so that when
5532 // showbase is not set, the space goes away too.
5533 __curr_symbol_.insert(0, 1, space_char);
5536 case 2: // Space between sign and currency or value.
5537 pat.field[1] = space;
5538 pat.field[2] = value;
5539 if (symbol_contains_sep) {
5540 // Remove the separator from the symbol, since it
5541 // has already appeared after the sign.
5542 __curr_symbol_.erase(__curr_symbol_.begin());
5549 case 2: // The sign string succeeds the quantity and currency symbol.
5550 pat.field[0] = value;
5551 pat.field[3] = sign;
5552 switch (sep_by_space)
5554 case 0: // No space separates the currency symbol and value.
5555 pat.field[1] = none;
5556 pat.field[2] = symbol;
5558 case 1: // Space between currency-and-sign or currency and value.
5559 if (!symbol_contains_sep) {
5560 // We insert the space into the symbol instead of
5561 // setting pat.field[1]=space so that when
5562 // showbase is not set, the space goes away too.
5563 __curr_symbol_.insert(0, 1, space_char);
5565 pat.field[1] = none;
5566 pat.field[2] = symbol;
5568 case 2: // Space between sign and currency or value.
5569 pat.field[1] = symbol;
5570 pat.field[2] = space;
5571 if (symbol_contains_sep) {
5572 // Remove the separator from the symbol, since it
5573 // should not be removed if showbase is absent.
5574 __curr_symbol_.erase(__curr_symbol_.begin());
5581 case 3: // The sign string immediately precedes the currency symbol.
5582 pat.field[0] = value;
5583 pat.field[3] = symbol;
5584 switch (sep_by_space)
5586 case 0: // No space separates the currency symbol and value.
5587 pat.field[1] = none;
5588 pat.field[2] = sign;
5590 case 1: // Space between currency-and-sign or currency and value.
5591 pat.field[1] = space;
5592 pat.field[2] = sign;
5593 if (symbol_contains_sep) {
5594 // Remove the separator from the symbol, since it
5595 // has already appeared before the sign.
5596 __curr_symbol_.erase(__curr_symbol_.begin());
5599 case 2: // Space between sign and currency or value.
5600 pat.field[1] = sign;
5601 pat.field[2] = none;
5602 if (!symbol_contains_sep) {
5603 // We insert the space into the symbol instead of
5604 // setting pat.field[2]=space so that when
5605 // showbase is not set, the space goes away too.
5606 __curr_symbol_.insert(0, 1, space_char);
5613 case 4: // The sign string immediately succeeds the currency symbol.
5614 pat.field[0] = value;
5615 pat.field[3] = sign;
5616 switch (sep_by_space)
5618 case 0: // No space separates the currency symbol and value.
5619 pat.field[1] = none;
5620 pat.field[2] = symbol;
5622 case 1: // Space between currency-and-sign or currency and value.
5623 pat.field[1] = none;
5624 pat.field[2] = symbol;
5625 if (!symbol_contains_sep) {
5626 // We insert the space into the symbol instead of
5627 // setting pat.field[1]=space so that when
5628 // showbase is not set, the space goes away too.
5629 __curr_symbol_.insert(0, 1, space_char);
5632 case 2: // Space between sign and currency or value.
5633 pat.field[1] = symbol;
5634 pat.field[2] = space;
5635 if (symbol_contains_sep) {
5636 // Remove the separator from the symbol, since it
5637 // should not disappear when showbase is absent.
5638 __curr_symbol_.erase(__curr_symbol_.begin());
5649 case 1: // curr_symbol before value
5652 case 0: // Parentheses surround the quantity and currency symbol.
5653 pat.field[0] = sign;
5654 pat.field[1] = symbol;
5655 pat.field[2] = none; // Any space appears in the symbol.
5656 pat.field[3] = value;
5657 switch (sep_by_space)
5659 case 0: // No space separates the currency symbol and value.
5660 // This case may have changed between C99 and C11;
5661 // assume the currency symbol matches the intention.
5662 case 2: // Space between sign and currency or value.
5663 // The "sign" is two parentheses, so no space here either.
5665 case 1: // Space between currency-and-sign or currency and value.
5666 if (!symbol_contains_sep) {
5667 // We insert the space into the symbol instead of
5668 // setting pat.field[2]=space so that when
5669 // showbase is not set, the space goes away too.
5670 __curr_symbol_.insert(0, 1, space_char);
5677 case 1: // The sign string precedes the quantity and currency symbol.
5678 pat.field[0] = sign;
5679 pat.field[3] = value;
5680 switch (sep_by_space)
5682 case 0: // No space separates the currency symbol and value.
5683 pat.field[1] = symbol;
5684 pat.field[2] = none;
5686 case 1: // Space between currency-and-sign or currency and value.
5687 pat.field[1] = symbol;
5688 pat.field[2] = none;
5689 if (!symbol_contains_sep) {
5690 // We insert the space into the symbol instead of
5691 // setting pat.field[2]=space so that when
5692 // showbase is not set, the space goes away too.
5693 __curr_symbol_.push_back(space_char);
5696 case 2: // Space between sign and currency or value.
5697 pat.field[1] = space;
5698 pat.field[2] = symbol;
5699 if (symbol_contains_sep) {
5700 // Remove the separator from the symbol, since it
5701 // has already appeared after the sign.
5702 __curr_symbol_.pop_back();
5709 case 2: // The sign string succeeds the quantity and currency symbol.
5710 pat.field[0] = symbol;
5711 pat.field[3] = sign;
5712 switch (sep_by_space)
5714 case 0: // No space separates the currency symbol and value.
5715 pat.field[1] = none;
5716 pat.field[2] = value;
5718 case 1: // Space between currency-and-sign or currency and value.
5719 pat.field[1] = none;
5720 pat.field[2] = value;
5721 if (!symbol_contains_sep) {
5722 // We insert the space into the symbol instead of
5723 // setting pat.field[1]=space so that when
5724 // showbase is not set, the space goes away too.
5725 __curr_symbol_.push_back(space_char);
5728 case 2: // Space between sign and currency or value.
5729 pat.field[1] = value;
5730 pat.field[2] = space;
5731 if (symbol_contains_sep) {
5732 // Remove the separator from the symbol, since it
5733 // will appear before the sign.
5734 __curr_symbol_.pop_back();
5741 case 3: // The sign string immediately precedes the currency symbol.
5742 pat.field[0] = sign;
5743 pat.field[3] = value;
5744 switch (sep_by_space)
5746 case 0: // No space separates the currency symbol and value.
5747 pat.field[1] = symbol;
5748 pat.field[2] = none;
5750 case 1: // Space between currency-and-sign or currency and value.
5751 pat.field[1] = symbol;
5752 pat.field[2] = none;
5753 if (!symbol_contains_sep) {
5754 // We insert the space into the symbol instead of
5755 // setting pat.field[2]=space so that when
5756 // showbase is not set, the space goes away too.
5757 __curr_symbol_.push_back(space_char);
5760 case 2: // Space between sign and currency or value.
5761 pat.field[1] = space;
5762 pat.field[2] = symbol;
5763 if (symbol_contains_sep) {
5764 // Remove the separator from the symbol, since it
5765 // has already appeared after the sign.
5766 __curr_symbol_.pop_back();
5773 case 4: // The sign string immediately succeeds the currency symbol.
5774 pat.field[0] = symbol;
5775 pat.field[3] = value;
5776 switch (sep_by_space)
5778 case 0: // No space separates the currency symbol and value.
5779 pat.field[1] = sign;
5780 pat.field[2] = none;
5782 case 1: // Space between currency-and-sign or currency and value.
5783 pat.field[1] = sign;
5784 pat.field[2] = space;
5785 if (symbol_contains_sep) {
5786 // Remove the separator from the symbol, since it
5787 // should not disappear when showbase is absent.
5788 __curr_symbol_.pop_back();
5791 case 2: // Space between sign and currency or value.
5792 pat.field[1] = none;
5793 pat.field[2] = sign;
5794 if (!symbol_contains_sep) {
5795 // We insert the space into the symbol instead of
5796 // setting pat.field[1]=space so that when
5797 // showbase is not set, the space goes away too.
5798 __curr_symbol_.push_back(space_char);
5812 pat.field[0] = symbol;
5813 pat.field[1] = sign;
5814 pat.field[2] = none;
5815 pat.field[3] = value;
5820 moneypunct_byname<char, false>::init(const char* nm)
5822 typedef moneypunct<char, false> base;
5823 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5825 __throw_runtime_error("moneypunct_byname"
5826 " failed to construct for " + string(nm));
5828 lconv* lc = __libcpp_localeconv_l(loc.get());
5829 if (!checked_string_to_char_convert(__decimal_point_,
5830 lc->mon_decimal_point,
5832 __decimal_point_ = base::do_decimal_point();
5833 if (!checked_string_to_char_convert(__thousands_sep_,
5834 lc->mon_thousands_sep,
5836 __thousands_sep_ = base::do_thousands_sep();
5838 __grouping_ = lc->mon_grouping;
5839 __curr_symbol_ = lc->currency_symbol;
5840 if (lc->frac_digits != CHAR_MAX)
5841 __frac_digits_ = lc->frac_digits;
5843 __frac_digits_ = base::do_frac_digits();
5844 if (lc->p_sign_posn == 0)
5845 __positive_sign_ = "()";
5847 __positive_sign_ = lc->positive_sign;
5848 if (lc->n_sign_posn == 0)
5849 __negative_sign_ = "()";
5851 __negative_sign_ = lc->negative_sign;
5852 // Assume the positive and negative formats will want spaces in
5853 // the same places in curr_symbol since there's no way to
5854 // represent anything else.
5855 string_type __dummy_curr_symbol = __curr_symbol_;
5856 __init_pat(__pos_format_, __dummy_curr_symbol, false,
5857 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5858 __init_pat(__neg_format_, __curr_symbol_, false,
5859 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5864 moneypunct_byname<char, true>::init(const char* nm)
5866 typedef moneypunct<char, true> base;
5867 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5869 __throw_runtime_error("moneypunct_byname"
5870 " failed to construct for " + string(nm));
5872 lconv* lc = __libcpp_localeconv_l(loc.get());
5873 if (!checked_string_to_char_convert(__decimal_point_,
5874 lc->mon_decimal_point,
5876 __decimal_point_ = base::do_decimal_point();
5877 if (!checked_string_to_char_convert(__thousands_sep_,
5878 lc->mon_thousands_sep,
5880 __thousands_sep_ = base::do_thousands_sep();
5881 __grouping_ = lc->mon_grouping;
5882 __curr_symbol_ = lc->int_curr_symbol;
5883 if (lc->int_frac_digits != CHAR_MAX)
5884 __frac_digits_ = lc->int_frac_digits;
5886 __frac_digits_ = base::do_frac_digits();
5887 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5888 if (lc->p_sign_posn == 0)
5889 #else // _LIBCPP_MSVCRT
5890 if (lc->int_p_sign_posn == 0)
5891 #endif // !_LIBCPP_MSVCRT
5892 __positive_sign_ = "()";
5894 __positive_sign_ = lc->positive_sign;
5895 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5896 if(lc->n_sign_posn == 0)
5897 #else // _LIBCPP_MSVCRT
5898 if (lc->int_n_sign_posn == 0)
5899 #endif // !_LIBCPP_MSVCRT
5900 __negative_sign_ = "()";
5902 __negative_sign_ = lc->negative_sign;
5903 // Assume the positive and negative formats will want spaces in
5904 // the same places in curr_symbol since there's no way to
5905 // represent anything else.
5906 string_type __dummy_curr_symbol = __curr_symbol_;
5907 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5908 __init_pat(__pos_format_, __dummy_curr_symbol, true,
5909 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5910 __init_pat(__neg_format_, __curr_symbol_, true,
5911 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5912 #else // _LIBCPP_MSVCRT
5913 __init_pat(__pos_format_, __dummy_curr_symbol, true,
5914 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
5915 lc->int_p_sign_posn, ' ');
5916 __init_pat(__neg_format_, __curr_symbol_, true,
5917 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
5918 lc->int_n_sign_posn, ' ');
5919 #endif // !_LIBCPP_MSVCRT
5924 moneypunct_byname<wchar_t, false>::init(const char* nm)
5926 typedef moneypunct<wchar_t, false> base;
5927 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5929 __throw_runtime_error("moneypunct_byname"
5930 " failed to construct for " + string(nm));
5931 lconv* lc = __libcpp_localeconv_l(loc.get());
5932 if (!checked_string_to_wchar_convert(__decimal_point_,
5933 lc->mon_decimal_point,
5935 __decimal_point_ = base::do_decimal_point();
5936 if (!checked_string_to_wchar_convert(__thousands_sep_,
5937 lc->mon_thousands_sep,
5939 __thousands_sep_ = base::do_thousands_sep();
5940 __grouping_ = lc->mon_grouping;
5943 const char* bb = lc->currency_symbol;
5944 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5945 if (j == size_t(-1))
5946 __throw_runtime_error("locale not supported");
5947 wchar_t* wbe = wbuf + j;
5948 __curr_symbol_.assign(wbuf, wbe);
5949 if (lc->frac_digits != CHAR_MAX)
5950 __frac_digits_ = lc->frac_digits;
5952 __frac_digits_ = base::do_frac_digits();
5953 if (lc->p_sign_posn == 0)
5954 __positive_sign_ = L"()";
5958 bb = lc->positive_sign;
5959 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5960 if (j == size_t(-1))
5961 __throw_runtime_error("locale not supported");
5963 __positive_sign_.assign(wbuf, wbe);
5965 if (lc->n_sign_posn == 0)
5966 __negative_sign_ = L"()";
5970 bb = lc->negative_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 __negative_sign_.assign(wbuf, wbe);
5977 // Assume the positive and negative formats will want spaces in
5978 // the same places in curr_symbol since there's no way to
5979 // represent anything else.
5980 string_type __dummy_curr_symbol = __curr_symbol_;
5981 __init_pat(__pos_format_, __dummy_curr_symbol, false,
5982 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
5983 __init_pat(__neg_format_, __curr_symbol_, false,
5984 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
5989 moneypunct_byname<wchar_t, true>::init(const char* nm)
5991 typedef moneypunct<wchar_t, true> base;
5992 __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5994 __throw_runtime_error("moneypunct_byname"
5995 " failed to construct for " + string(nm));
5997 lconv* lc = __libcpp_localeconv_l(loc.get());
5998 if (!checked_string_to_wchar_convert(__decimal_point_,
5999 lc->mon_decimal_point,
6001 __decimal_point_ = base::do_decimal_point();
6002 if (!checked_string_to_wchar_convert(__thousands_sep_,
6003 lc->mon_thousands_sep,
6005 __thousands_sep_ = base::do_thousands_sep();
6006 __grouping_ = lc->mon_grouping;
6009 const char* bb = lc->int_curr_symbol;
6010 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6011 if (j == size_t(-1))
6012 __throw_runtime_error("locale not supported");
6013 wchar_t* wbe = wbuf + j;
6014 __curr_symbol_.assign(wbuf, wbe);
6015 if (lc->int_frac_digits != CHAR_MAX)
6016 __frac_digits_ = lc->int_frac_digits;
6018 __frac_digits_ = base::do_frac_digits();
6019 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6020 if (lc->p_sign_posn == 0)
6021 #else // _LIBCPP_MSVCRT
6022 if (lc->int_p_sign_posn == 0)
6023 #endif // !_LIBCPP_MSVCRT
6024 __positive_sign_ = L"()";
6028 bb = lc->positive_sign;
6029 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6030 if (j == size_t(-1))
6031 __throw_runtime_error("locale not supported");
6033 __positive_sign_.assign(wbuf, wbe);
6035 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6036 if (lc->n_sign_posn == 0)
6037 #else // _LIBCPP_MSVCRT
6038 if (lc->int_n_sign_posn == 0)
6039 #endif // !_LIBCPP_MSVCRT
6040 __negative_sign_ = L"()";
6044 bb = lc->negative_sign;
6045 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6046 if (j == size_t(-1))
6047 __throw_runtime_error("locale not supported");
6049 __negative_sign_.assign(wbuf, wbe);
6051 // Assume the positive and negative formats will want spaces in
6052 // the same places in curr_symbol since there's no way to
6053 // represent anything else.
6054 string_type __dummy_curr_symbol = __curr_symbol_;
6055 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6056 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6057 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6058 __init_pat(__neg_format_, __curr_symbol_, true,
6059 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6060 #else // _LIBCPP_MSVCRT
6061 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6062 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6063 lc->int_p_sign_posn, L' ');
6064 __init_pat(__neg_format_, __curr_symbol_, true,
6065 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6066 lc->int_n_sign_posn, L' ');
6067 #endif // !_LIBCPP_MSVCRT
6070 void __do_nothing(void*) {}
6072 void __throw_runtime_error(const char* msg)
6074 #ifndef _LIBCPP_NO_EXCEPTIONS
6075 throw runtime_error(msg);
6082 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;
6083 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;
6085 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<char>;
6086 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<wchar_t>;
6088 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<char>;
6089 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<wchar_t>;
6091 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<char>;
6092 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<wchar_t>;
6094 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<char>;
6095 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<wchar_t>;
6097 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<char>;
6098 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<wchar_t>;
6100 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<char>;
6101 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<wchar_t>;
6103 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<char>;
6104 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<wchar_t>;
6106 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<char>;
6107 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<wchar_t>;
6109 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, false>;
6110 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, true>;
6111 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, false>;
6112 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, true>;
6114 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, false>;
6115 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, true>;
6116 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, false>;
6117 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, true>;
6119 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<char>;
6120 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<wchar_t>;
6122 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<char>;
6123 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<wchar_t>;
6125 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<char>;
6126 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<wchar_t>;
6128 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<char>;
6129 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<wchar_t>;
6131 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<char>;
6132 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<wchar_t>;
6134 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<char>;
6135 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t>;
6137 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>;
6138 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;
6139 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
6140 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
6142 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __vector_base_common<true>;
6144 _LIBCPP_END_NAMESPACE_STD