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__)
39 #include "include/atomic_support.h"
40 #include "__undef_macros"
42 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
43 // lots of noise in the build log, but no bugs that I know of.
44 #if defined(__clang__)
45 #pragma clang diagnostic ignored "-Wsign-conversion"
48 _LIBCPP_BEGIN_NAMESPACE_STD
50 struct __libcpp_unique_locale {
51 __libcpp_unique_locale(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {}
53 ~__libcpp_unique_locale() {
58 explicit operator bool() const { return __loc_; }
60 locale_t& get() { return __loc_; }
64 __libcpp_unique_locale(__libcpp_unique_locale const&);
65 __libcpp_unique_locale& operator=(__libcpp_unique_locale const&);
70 // In theory this could create a race condition. In practice
71 // the race condition is non-fatal since it will just create
72 // a little resource leak. Better approach would be appreciated.
73 static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
76 #endif // __cloc_defined
82 void operator()(locale::facet* p) {p->__release_shared();}
85 template <class T, class A0>
90 static typename aligned_storage<sizeof(T)>::type buf;
91 auto *obj = ::new (&buf) T(a0);
95 template <class T, class A0, class A1>
100 static typename aligned_storage<sizeof(T)>::type buf;
101 ::new (&buf) T(a0, a1);
102 return *reinterpret_cast<T*>(&buf);
105 template <class T, class A0, class A1, class A2>
108 make(A0 a0, A1 a1, A2 a2)
110 static typename aligned_storage<sizeof(T)>::type buf;
111 auto *obj = ::new (&buf) T(a0, a1, a2);
115 template <typename T, size_t N>
119 countof(const T (&)[N])
124 template <typename T>
128 countof(const T * const begin, const T * const end)
130 return static_cast<size_t>(end - begin);
133 _LIBCPP_NORETURN static void __throw_runtime_error(const string &msg)
135 #ifndef _LIBCPP_NO_EXCEPTIONS
136 throw runtime_error(msg);
146 // Set priority to INT_MIN + 256 + 150
147 # pragma priority ( -2147483242 )
150 const locale::category locale::none;
151 const locale::category locale::collate;
152 const locale::category locale::ctype;
153 const locale::category locale::monetary;
154 const locale::category locale::numeric;
155 const locale::category locale::time;
156 const locale::category locale::messages;
157 const locale::category locale::all;
159 class _LIBCPP_HIDDEN locale::__imp
163 #if defined(_LIBCPP_COMPILER_MSVC)
164 // FIXME: MSVC doesn't support aligned parameters by value.
165 // I can't get the __sso_allocator to work here
166 // for MSVC I think for this reason.
167 vector<facet*> facets_;
169 vector<facet*, __sso_allocator<facet*, N> > facets_;
173 explicit __imp(size_t refs = 0);
174 explicit __imp(const string& name, size_t refs = 0);
176 __imp(const __imp&, const string&, locale::category c);
177 __imp(const __imp& other, const __imp& one, locale::category c);
178 __imp(const __imp&, facet* f, long id);
181 const string& name() const {return name_;}
182 bool has_facet(long id) const
183 {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
184 const locale::facet* use_facet(long id) const;
186 static const locale& make_classic();
187 static locale& make_global();
189 void install(facet* f, long id);
190 template <class F> void install(F* f) {install(f, f->id.__get());}
191 template <class F> void install_from(const __imp& other);
194 locale::__imp::__imp(size_t refs)
200 install(&make<_VSTD::collate<char> >(1u));
201 install(&make<_VSTD::collate<wchar_t> >(1u));
202 install(&make<_VSTD::ctype<char> >(nullptr, false, 1u));
203 install(&make<_VSTD::ctype<wchar_t> >(1u));
204 install(&make<codecvt<char, char, mbstate_t> >(1u));
205 install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
206 install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
207 install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
208 install(&make<numpunct<char> >(1u));
209 install(&make<numpunct<wchar_t> >(1u));
210 install(&make<num_get<char> >(1u));
211 install(&make<num_get<wchar_t> >(1u));
212 install(&make<num_put<char> >(1u));
213 install(&make<num_put<wchar_t> >(1u));
214 install(&make<moneypunct<char, false> >(1u));
215 install(&make<moneypunct<char, true> >(1u));
216 install(&make<moneypunct<wchar_t, false> >(1u));
217 install(&make<moneypunct<wchar_t, true> >(1u));
218 install(&make<money_get<char> >(1u));
219 install(&make<money_get<wchar_t> >(1u));
220 install(&make<money_put<char> >(1u));
221 install(&make<money_put<wchar_t> >(1u));
222 install(&make<time_get<char> >(1u));
223 install(&make<time_get<wchar_t> >(1u));
224 install(&make<time_put<char> >(1u));
225 install(&make<time_put<wchar_t> >(1u));
226 install(&make<_VSTD::messages<char> >(1u));
227 install(&make<_VSTD::messages<wchar_t> >(1u));
230 locale::__imp::__imp(const string& name, size_t refs)
235 #ifndef _LIBCPP_NO_EXCEPTIONS
238 #endif // _LIBCPP_NO_EXCEPTIONS
239 facets_ = locale::classic().__locale_->facets_;
240 for (unsigned i = 0; i < facets_.size(); ++i)
242 facets_[i]->__add_shared();
243 install(new collate_byname<char>(name_));
244 install(new collate_byname<wchar_t>(name_));
245 install(new ctype_byname<char>(name_));
246 install(new ctype_byname<wchar_t>(name_));
247 install(new codecvt_byname<char, char, mbstate_t>(name_));
248 install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
249 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
250 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
251 install(new numpunct_byname<char>(name_));
252 install(new numpunct_byname<wchar_t>(name_));
253 install(new moneypunct_byname<char, false>(name_));
254 install(new moneypunct_byname<char, true>(name_));
255 install(new moneypunct_byname<wchar_t, false>(name_));
256 install(new moneypunct_byname<wchar_t, true>(name_));
257 install(new time_get_byname<char>(name_));
258 install(new time_get_byname<wchar_t>(name_));
259 install(new time_put_byname<char>(name_));
260 install(new time_put_byname<wchar_t>(name_));
261 install(new messages_byname<char>(name_));
262 install(new messages_byname<wchar_t>(name_));
263 #ifndef _LIBCPP_NO_EXCEPTIONS
267 for (unsigned i = 0; i < facets_.size(); ++i)
269 facets_[i]->__release_shared();
272 #endif // _LIBCPP_NO_EXCEPTIONS
275 // NOTE avoid the `base class should be explicitly initialized in the
276 // copy constructor` warning emitted by GCC
277 #if defined(__clang__) || _GNUC_VER >= 406
278 #pragma GCC diagnostic push
279 #pragma GCC diagnostic ignored "-Wextra"
282 locale::__imp::__imp(const __imp& other)
283 : facets_(max<size_t>(N, other.facets_.size())),
286 facets_ = other.facets_;
287 for (unsigned i = 0; i < facets_.size(); ++i)
289 facets_[i]->__add_shared();
292 #if defined(__clang__) || _GNUC_VER >= 406
293 #pragma GCC diagnostic pop
296 locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
300 facets_ = other.facets_;
301 for (unsigned i = 0; i < facets_.size(); ++i)
303 facets_[i]->__add_shared();
304 #ifndef _LIBCPP_NO_EXCEPTIONS
307 #endif // _LIBCPP_NO_EXCEPTIONS
308 if (c & locale::collate)
310 install(new collate_byname<char>(name));
311 install(new collate_byname<wchar_t>(name));
313 if (c & locale::ctype)
315 install(new ctype_byname<char>(name));
316 install(new ctype_byname<wchar_t>(name));
317 install(new codecvt_byname<char, char, mbstate_t>(name));
318 install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
319 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
320 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
322 if (c & locale::monetary)
324 install(new moneypunct_byname<char, false>(name));
325 install(new moneypunct_byname<char, true>(name));
326 install(new moneypunct_byname<wchar_t, false>(name));
327 install(new moneypunct_byname<wchar_t, true>(name));
329 if (c & locale::numeric)
331 install(new numpunct_byname<char>(name));
332 install(new numpunct_byname<wchar_t>(name));
334 if (c & locale::time)
336 install(new time_get_byname<char>(name));
337 install(new time_get_byname<wchar_t>(name));
338 install(new time_put_byname<char>(name));
339 install(new time_put_byname<wchar_t>(name));
341 if (c & locale::messages)
343 install(new messages_byname<char>(name));
344 install(new messages_byname<wchar_t>(name));
346 #ifndef _LIBCPP_NO_EXCEPTIONS
350 for (unsigned i = 0; i < facets_.size(); ++i)
352 facets_[i]->__release_shared();
355 #endif // _LIBCPP_NO_EXCEPTIONS
361 locale::__imp::install_from(const locale::__imp& one)
363 long id = F::id.__get();
364 install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
367 locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
371 facets_ = other.facets_;
372 for (unsigned i = 0; i < facets_.size(); ++i)
374 facets_[i]->__add_shared();
375 #ifndef _LIBCPP_NO_EXCEPTIONS
378 #endif // _LIBCPP_NO_EXCEPTIONS
379 if (c & locale::collate)
381 install_from<_VSTD::collate<char> >(one);
382 install_from<_VSTD::collate<wchar_t> >(one);
384 if (c & locale::ctype)
386 install_from<_VSTD::ctype<char> >(one);
387 install_from<_VSTD::ctype<wchar_t> >(one);
388 install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
389 install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
390 install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
391 install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
393 if (c & locale::monetary)
395 install_from<moneypunct<char, false> >(one);
396 install_from<moneypunct<char, true> >(one);
397 install_from<moneypunct<wchar_t, false> >(one);
398 install_from<moneypunct<wchar_t, true> >(one);
399 install_from<money_get<char> >(one);
400 install_from<money_get<wchar_t> >(one);
401 install_from<money_put<char> >(one);
402 install_from<money_put<wchar_t> >(one);
404 if (c & locale::numeric)
406 install_from<numpunct<char> >(one);
407 install_from<numpunct<wchar_t> >(one);
408 install_from<num_get<char> >(one);
409 install_from<num_get<wchar_t> >(one);
410 install_from<num_put<char> >(one);
411 install_from<num_put<wchar_t> >(one);
413 if (c & locale::time)
415 install_from<time_get<char> >(one);
416 install_from<time_get<wchar_t> >(one);
417 install_from<time_put<char> >(one);
418 install_from<time_put<wchar_t> >(one);
420 if (c & locale::messages)
422 install_from<_VSTD::messages<char> >(one);
423 install_from<_VSTD::messages<wchar_t> >(one);
425 #ifndef _LIBCPP_NO_EXCEPTIONS
429 for (unsigned i = 0; i < facets_.size(); ++i)
431 facets_[i]->__release_shared();
434 #endif // _LIBCPP_NO_EXCEPTIONS
437 locale::__imp::__imp(const __imp& other, facet* f, long id)
438 : facets_(max<size_t>(N, other.facets_.size()+1)),
442 unique_ptr<facet, release> hold(f);
443 facets_ = other.facets_;
444 for (unsigned i = 0; i < other.facets_.size(); ++i)
446 facets_[i]->__add_shared();
447 install(hold.get(), id);
450 locale::__imp::~__imp()
452 for (unsigned i = 0; i < facets_.size(); ++i)
454 facets_[i]->__release_shared();
458 locale::__imp::install(facet* f, long id)
461 unique_ptr<facet, release> hold(f);
462 if (static_cast<size_t>(id) >= facets_.size())
463 facets_.resize(static_cast<size_t>(id+1));
464 if (facets_[static_cast<size_t>(id)])
465 facets_[static_cast<size_t>(id)]->__release_shared();
466 facets_[static_cast<size_t>(id)] = hold.release();
470 locale::__imp::use_facet(long id) const
472 #ifndef _LIBCPP_NO_EXCEPTIONS
475 #endif // _LIBCPP_NO_EXCEPTIONS
476 return facets_[static_cast<size_t>(id)];
482 locale::__imp::make_classic()
484 // only one thread can get in here and it only gets in once
485 static aligned_storage<sizeof(locale)>::type buf;
486 locale* c = reinterpret_cast<locale*>(&buf);
487 c->__locale_ = &make<__imp>(1u);
494 static const locale& c = __imp::make_classic();
499 locale::__imp::make_global()
501 // only one thread can get in here and it only gets in once
502 static aligned_storage<sizeof(locale)>::type buf;
503 auto *obj = ::new (&buf) locale(locale::classic());
510 static locale& g = __imp::make_global();
514 locale::locale() _NOEXCEPT
515 : __locale_(__global().__locale_)
517 __locale_->__add_shared();
520 locale::locale(const locale& l) _NOEXCEPT
521 : __locale_(l.__locale_)
523 __locale_->__add_shared();
528 __locale_->__release_shared();
532 locale::operator=(const locale& other) _NOEXCEPT
534 other.__locale_->__add_shared();
535 __locale_->__release_shared();
536 __locale_ = other.__locale_;
540 locale::locale(const char* name)
541 #ifndef _LIBCPP_NO_EXCEPTIONS
542 : __locale_(name ? new __imp(name)
543 : throw runtime_error("locale constructed with null"))
544 #else // _LIBCPP_NO_EXCEPTIONS
545 : __locale_(new __imp(name))
548 __locale_->__add_shared();
551 locale::locale(const string& name)
552 : __locale_(new __imp(name))
554 __locale_->__add_shared();
557 locale::locale(const locale& other, const char* name, category c)
558 #ifndef _LIBCPP_NO_EXCEPTIONS
559 : __locale_(name ? new __imp(*other.__locale_, name, c)
560 : throw runtime_error("locale constructed with null"))
561 #else // _LIBCPP_NO_EXCEPTIONS
562 : __locale_(new __imp(*other.__locale_, name, c))
565 __locale_->__add_shared();
568 locale::locale(const locale& other, const string& name, category c)
569 : __locale_(new __imp(*other.__locale_, name, c))
571 __locale_->__add_shared();
574 locale::locale(const locale& other, const locale& one, category c)
575 : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
577 __locale_->__add_shared();
583 return __locale_->name();
587 locale::__install_ctor(const locale& other, facet* f, long id)
590 __locale_ = new __imp(*other.__locale_, f, id);
592 __locale_ = other.__locale_;
593 __locale_->__add_shared();
597 locale::global(const locale& loc)
599 locale& g = __global();
603 setlocale(LC_ALL, g.name().c_str());
608 locale::has_facet(id& x) const
610 return __locale_->has_facet(x.__get());
614 locale::use_facet(id& x) const
616 return __locale_->use_facet(x.__get());
620 locale::operator==(const locale& y) const
622 return (__locale_ == y.__locale_)
623 || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
628 locale::facet::~facet()
633 locale::facet::__on_zero_shared() _NOEXCEPT
640 int32_t locale::id::__next_id = 0;
648 void (locale::id::* pmf_)();
650 __fake_bind(void (locale::id::* pmf)(), locale::id* id)
651 : id_(id), pmf_(pmf) {}
653 void operator()() const
664 call_once(__flag_, __fake_bind(&locale::id::__init, this));
671 __id_ = __libcpp_atomic_add(&__next_id, 1);
674 // template <> class collate_byname<char>
676 collate_byname<char>::collate_byname(const char* n, size_t refs)
677 : collate<char>(refs),
678 __l(newlocale(LC_ALL_MASK, n, 0))
681 __throw_runtime_error("collate_byname<char>::collate_byname"
682 " failed to construct for " + string(n));
685 collate_byname<char>::collate_byname(const string& name, size_t refs)
686 : collate<char>(refs),
687 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
690 __throw_runtime_error("collate_byname<char>::collate_byname"
691 " failed to construct for " + name);
694 collate_byname<char>::~collate_byname()
700 collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
701 const char_type* __lo2, const char_type* __hi2) const
703 string_type lhs(__lo1, __hi1);
704 string_type rhs(__lo2, __hi2);
705 int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l);
713 collate_byname<char>::string_type
714 collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
716 const string_type in(lo, hi);
717 string_type out(strxfrm_l(0, in.c_str(), 0, __l), char());
718 strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l);
722 // template <> class collate_byname<wchar_t>
724 collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
725 : collate<wchar_t>(refs),
726 __l(newlocale(LC_ALL_MASK, n, 0))
729 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
730 " failed to construct for " + string(n));
733 collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
734 : collate<wchar_t>(refs),
735 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
738 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
739 " failed to construct for " + name);
742 collate_byname<wchar_t>::~collate_byname()
748 collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
749 const char_type* __lo2, const char_type* __hi2) const
751 string_type lhs(__lo1, __hi1);
752 string_type rhs(__lo2, __hi2);
753 int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l);
761 collate_byname<wchar_t>::string_type
762 collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
764 const string_type in(lo, hi);
765 string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t());
766 wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l);
770 // template <> class ctype<wchar_t>;
772 const ctype_base::mask ctype_base::space;
773 const ctype_base::mask ctype_base::print;
774 const ctype_base::mask ctype_base::cntrl;
775 const ctype_base::mask ctype_base::upper;
776 const ctype_base::mask ctype_base::lower;
777 const ctype_base::mask ctype_base::alpha;
778 const ctype_base::mask ctype_base::digit;
779 const ctype_base::mask ctype_base::punct;
780 const ctype_base::mask ctype_base::xdigit;
781 const ctype_base::mask ctype_base::blank;
782 const ctype_base::mask ctype_base::alnum;
783 const ctype_base::mask ctype_base::graph;
785 locale::id ctype<wchar_t>::id;
787 ctype<wchar_t>::~ctype()
792 ctype<wchar_t>::do_is(mask m, char_type c) const
794 return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
798 ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
800 for (; low != high; ++low, ++vec)
801 *vec = static_cast<mask>(isascii(*low) ?
802 ctype<char>::classic_table()[*low] : 0);
807 ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
809 for (; low != high; ++low)
810 if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
816 ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
818 for (; low != high; ++low)
819 if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
825 ctype<wchar_t>::do_toupper(char_type c) const
827 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
828 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
829 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
831 return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
833 return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;
838 ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
840 for (; low != high; ++low)
841 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
842 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
843 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
845 *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
848 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low;
854 ctype<wchar_t>::do_tolower(char_type c) const
856 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
857 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
858 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
860 return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
862 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;
867 ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
869 for (; low != high; ++low)
870 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
871 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
872 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
874 *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
877 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low;
883 ctype<wchar_t>::do_widen(char c) const
889 ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
891 for (; low != high; ++low, ++dest)
897 ctype<wchar_t>::do_narrow(char_type c, char dfault) const
900 return static_cast<char>(c);
905 ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
907 for (; low != high; ++low, ++dest)
909 *dest = static_cast<char>(*low);
915 // template <> class ctype<char>;
917 locale::id ctype<char>::id;
919 ctype<char>::ctype(const mask* tab, bool del, size_t refs)
920 : locale::facet(refs),
925 __tab_ = classic_table();
928 ctype<char>::~ctype()
930 if (__tab_ && __del_)
935 ctype<char>::do_toupper(char_type c) const
937 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
939 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
940 #elif defined(__NetBSD__)
941 return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
942 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
944 static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
946 return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;
951 ctype<char>::do_toupper(char_type* low, const char_type* high) const
953 for (; low != high; ++low)
954 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
955 *low = isascii(*low) ?
956 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
957 #elif defined(__NetBSD__)
958 *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
959 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
960 *low = isascii(*low) ?
961 static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
963 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low;
969 ctype<char>::do_tolower(char_type c) const
971 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
973 static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
974 #elif defined(__NetBSD__)
975 return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
976 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
978 static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
980 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c;
985 ctype<char>::do_tolower(char_type* low, const char_type* high) const
987 for (; low != high; ++low)
988 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
989 *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
990 #elif defined(__NetBSD__)
991 *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
992 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
993 *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
995 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low;
1001 ctype<char>::do_widen(char c) const
1007 ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
1009 for (; low != high; ++low, ++dest)
1015 ctype<char>::do_narrow(char_type c, char dfault) const
1018 return static_cast<char>(c);
1023 ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1025 for (; low != high; ++low, ++dest)
1033 #if defined(__EMSCRIPTEN__)
1034 extern "C" const unsigned short ** __ctype_b_loc();
1035 extern "C" const int ** __ctype_tolower_loc();
1036 extern "C" const int ** __ctype_toupper_loc();
1039 #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
1040 const ctype<char>::mask*
1041 ctype<char>::classic_table() _NOEXCEPT
1043 static _LIBCPP_CONSTEXPR const ctype<char>::mask builtin_table[table_size] = {
1048 cntrl, cntrl | space | blank,
1049 cntrl | space, cntrl | space,
1050 cntrl | space, cntrl | space,
1060 space | blank | print, punct | print,
1061 punct | print, punct | print,
1062 punct | print, punct | print,
1063 punct | print, punct | print,
1064 punct | print, punct | print,
1065 punct | print, punct | print,
1066 punct | print, punct | print,
1067 punct | print, punct | print,
1068 digit | print | xdigit, digit | print | xdigit,
1069 digit | print | xdigit, digit | print | xdigit,
1070 digit | print | xdigit, digit | print | xdigit,
1071 digit | print | xdigit, digit | print | xdigit,
1072 digit | print | xdigit, digit | print | xdigit,
1073 punct | print, punct | print,
1074 punct | print, punct | print,
1075 punct | print, punct | print,
1076 punct | print, upper | xdigit | print | alpha,
1077 upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1078 upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1079 upper | xdigit | print | alpha, upper | print | alpha,
1080 upper | print | alpha, upper | print | alpha,
1081 upper | print | alpha, upper | print | alpha,
1082 upper | print | alpha, upper | print | alpha,
1083 upper | print | alpha, upper | print | alpha,
1084 upper | print | alpha, upper | print | alpha,
1085 upper | print | alpha, upper | print | alpha,
1086 upper | print | alpha, upper | print | alpha,
1087 upper | print | alpha, upper | print | alpha,
1088 upper | print | alpha, upper | print | alpha,
1089 upper | print | alpha, punct | print,
1090 punct | print, punct | print,
1091 punct | print, punct | print,
1092 punct | print, lower | xdigit | print | alpha,
1093 lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1094 lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1095 lower | xdigit | print | alpha, lower | print | alpha,
1096 lower | print | alpha, lower | print | alpha,
1097 lower | print | alpha, lower | print | alpha,
1098 lower | print | alpha, lower | print | alpha,
1099 lower | print | alpha, lower | print | alpha,
1100 lower | print | alpha, lower | print | alpha,
1101 lower | print | alpha, lower | print | alpha,
1102 lower | print | alpha, lower | print | alpha,
1103 lower | print | alpha, lower | print | alpha,
1104 lower | print | alpha, lower | print | alpha,
1105 lower | print | alpha, punct | print,
1106 punct | print, punct | print,
1107 punct | print, cntrl,
1108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1115 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1117 return builtin_table;
1120 const ctype<char>::mask*
1121 ctype<char>::classic_table() _NOEXCEPT
1123 #if defined(__APPLE__) || defined(__FreeBSD__)
1124 return _DefaultRuneLocale.__runetype;
1125 #elif defined(__NetBSD__)
1126 return _C_ctype_tab_ + 1;
1127 #elif defined(__GLIBC__)
1128 return _LIBCPP_GET_C_LOCALE->__ctype_b;
1130 return __ctype_mask;
1131 #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
1132 return __pctype_func();
1133 #elif defined(__EMSCRIPTEN__)
1134 return *__ctype_b_loc();
1135 #elif defined(_NEWLIB_VERSION)
1136 // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
1139 return (const unsigned int *)__lc_ctype_ptr->obj->mask;
1141 // Platform not supported: abort so the person doing the port knows what to
1143 # warning ctype<char>::classic_table() is not implemented
1144 printf("ctype<char>::classic_table() is not implemented\n");
1151 #if defined(__GLIBC__)
1153 ctype<char>::__classic_lower_table() _NOEXCEPT
1155 return _LIBCPP_GET_C_LOCALE->__ctype_tolower;
1159 ctype<char>::__classic_upper_table() _NOEXCEPT
1161 return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
1165 ctype<char>::__classic_lower_table() _NOEXCEPT
1167 return _C_tolower_tab_ + 1;
1171 ctype<char>::__classic_upper_table() _NOEXCEPT
1173 return _C_toupper_tab_ + 1;
1176 #elif defined(__EMSCRIPTEN__)
1178 ctype<char>::__classic_lower_table() _NOEXCEPT
1180 return *__ctype_tolower_loc();
1184 ctype<char>::__classic_upper_table() _NOEXCEPT
1186 return *__ctype_toupper_loc();
1188 #endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__
1190 // template <> class ctype_byname<char>
1192 ctype_byname<char>::ctype_byname(const char* name, size_t refs)
1193 : ctype<char>(0, false, refs),
1194 __l(newlocale(LC_ALL_MASK, name, 0))
1197 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1198 " failed to construct for " + string(name));
1201 ctype_byname<char>::ctype_byname(const string& name, size_t refs)
1202 : ctype<char>(0, false, refs),
1203 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1206 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1207 " failed to construct for " + name);
1210 ctype_byname<char>::~ctype_byname()
1216 ctype_byname<char>::do_toupper(char_type c) const
1218 return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l));
1222 ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
1224 for (; low != high; ++low)
1225 *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l));
1230 ctype_byname<char>::do_tolower(char_type c) const
1232 return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l));
1236 ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
1238 for (; low != high; ++low)
1239 *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l));
1243 // template <> class ctype_byname<wchar_t>
1245 ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
1246 : ctype<wchar_t>(refs),
1247 __l(newlocale(LC_ALL_MASK, name, 0))
1250 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1251 " failed to construct for " + string(name));
1254 ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
1255 : ctype<wchar_t>(refs),
1256 __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1259 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1260 " failed to construct for " + name);
1263 ctype_byname<wchar_t>::~ctype_byname()
1269 ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1271 #ifdef _LIBCPP_WCTYPE_IS_MASK
1272 return static_cast<bool>(iswctype_l(c, m, __l));
1274 bool result = false;
1275 wint_t ch = static_cast<wint_t>(c);
1276 if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0);
1277 if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0);
1278 if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0);
1279 if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0);
1280 if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0);
1281 if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0);
1282 if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0);
1283 if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0);
1284 if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0);
1285 if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0);
1291 ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1293 for (; low != high; ++low, ++vec)
1296 *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
1300 wint_t ch = static_cast<wint_t>(*low);
1301 if (iswspace_l(ch, __l))
1303 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
1304 if (iswprint_l(ch, __l))
1307 if (iswcntrl_l(ch, __l))
1309 if (iswupper_l(ch, __l))
1311 if (iswlower_l(ch, __l))
1313 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
1314 if (iswalpha_l(ch, __l))
1317 if (iswdigit_l(ch, __l))
1319 if (iswpunct_l(ch, __l))
1321 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
1322 if (iswxdigit_l(ch, __l))
1325 #if !defined(__sun__)
1326 if (iswblank_l(ch, __l))
1335 ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1337 for (; low != high; ++low)
1339 #ifdef _LIBCPP_WCTYPE_IS_MASK
1340 if (iswctype_l(*low, m, __l))
1343 wint_t ch = static_cast<wint_t>(*low);
1344 if ((m & space) == space && iswspace_l(ch, __l)) break;
1345 if ((m & print) == print && iswprint_l(ch, __l)) break;
1346 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break;
1347 if ((m & upper) == upper && iswupper_l(ch, __l)) break;
1348 if ((m & lower) == lower && iswlower_l(ch, __l)) break;
1349 if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break;
1350 if ((m & digit) == digit && iswdigit_l(ch, __l)) break;
1351 if ((m & punct) == punct && iswpunct_l(ch, __l)) break;
1352 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break;
1353 if ((m & blank) == blank && iswblank_l(ch, __l)) break;
1360 ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1362 for (; low != high; ++low)
1364 #ifdef _LIBCPP_WCTYPE_IS_MASK
1365 if (!iswctype_l(*low, m, __l))
1368 wint_t ch = static_cast<wint_t>(*low);
1369 if ((m & space) == space && iswspace_l(ch, __l)) continue;
1370 if ((m & print) == print && iswprint_l(ch, __l)) continue;
1371 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue;
1372 if ((m & upper) == upper && iswupper_l(ch, __l)) continue;
1373 if ((m & lower) == lower && iswlower_l(ch, __l)) continue;
1374 if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue;
1375 if ((m & digit) == digit && iswdigit_l(ch, __l)) continue;
1376 if ((m & punct) == punct && iswpunct_l(ch, __l)) continue;
1377 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue;
1378 if ((m & blank) == blank && iswblank_l(ch, __l)) continue;
1386 ctype_byname<wchar_t>::do_toupper(char_type c) const
1388 return towupper_l(c, __l);
1392 ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1394 for (; low != high; ++low)
1395 *low = towupper_l(*low, __l);
1400 ctype_byname<wchar_t>::do_tolower(char_type c) const
1402 return towlower_l(c, __l);
1406 ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1408 for (; low != high; ++low)
1409 *low = towlower_l(*low, __l);
1414 ctype_byname<wchar_t>::do_widen(char c) const
1416 return __libcpp_btowc_l(c, __l);
1420 ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1422 for (; low != high; ++low, ++dest)
1423 *dest = __libcpp_btowc_l(*low, __l);
1428 ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1430 int r = __libcpp_wctob_l(c, __l);
1431 return r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
1435 ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1437 for (; low != high; ++low, ++dest)
1439 int r = __libcpp_wctob_l(*low, __l);
1440 *dest = r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
1445 // template <> class codecvt<char, char, mbstate_t>
1447 locale::id codecvt<char, char, mbstate_t>::id;
1449 codecvt<char, char, mbstate_t>::~codecvt()
1453 codecvt<char, char, mbstate_t>::result
1454 codecvt<char, char, mbstate_t>::do_out(state_type&,
1455 const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
1456 extern_type* to, extern_type*, extern_type*& to_nxt) const
1463 codecvt<char, char, mbstate_t>::result
1464 codecvt<char, char, mbstate_t>::do_in(state_type&,
1465 const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
1466 intern_type* to, intern_type*, intern_type*& to_nxt) const
1473 codecvt<char, char, mbstate_t>::result
1474 codecvt<char, char, mbstate_t>::do_unshift(state_type&,
1475 extern_type* to, extern_type*, extern_type*& to_nxt) const
1482 codecvt<char, char, mbstate_t>::do_encoding() const _NOEXCEPT
1488 codecvt<char, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
1494 codecvt<char, char, mbstate_t>::do_length(state_type&,
1495 const extern_type* frm, const extern_type* end, size_t mx) const
1497 return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
1501 codecvt<char, char, mbstate_t>::do_max_length() const _NOEXCEPT
1506 // template <> class codecvt<wchar_t, char, mbstate_t>
1508 locale::id codecvt<wchar_t, char, mbstate_t>::id;
1510 codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1511 : locale::facet(refs),
1512 __l(_LIBCPP_GET_C_LOCALE)
1516 codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1517 : locale::facet(refs),
1518 __l(newlocale(LC_ALL_MASK, nm, 0))
1521 __throw_runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1522 " failed to construct for " + string(nm));
1525 codecvt<wchar_t, char, mbstate_t>::~codecvt()
1527 if (__l != _LIBCPP_GET_C_LOCALE)
1531 codecvt<wchar_t, char, mbstate_t>::result
1532 codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
1533 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
1534 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1536 // look for first internal null in frm
1537 const intern_type* fend = frm;
1538 for (; fend != frm_end; ++fend)
1541 // loop over all null-terminated sequences in frm
1543 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1545 // save state in case it is needed to recover to_nxt on error
1546 mbstate_t save_state = st;
1547 size_t n = __libcpp_wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1548 static_cast<size_t>(to_end-to), &st, __l);
1549 if (n == size_t(-1))
1551 // need to recover to_nxt
1552 for (to_nxt = to; frm != frm_nxt; ++frm)
1554 n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l);
1555 if (n == size_t(-1))
1565 if (to_nxt == to_end)
1567 if (fend != frm_end) // set up next null terminated sequence
1569 // Try to write the terminating null
1570 extern_type tmp[MB_LEN_MAX];
1571 n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l);
1572 if (n == size_t(-1)) // on error
1574 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1576 for (extern_type* p = tmp; n; --n) // write it
1579 // look for next null in frm
1580 for (fend = frm_nxt; fend != frm_end; ++fend)
1585 return frm_nxt == frm_end ? ok : partial;
1588 codecvt<wchar_t, char, mbstate_t>::result
1589 codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
1590 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
1591 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1593 // look for first internal null in frm
1594 const extern_type* fend = frm;
1595 for (; fend != frm_end; ++fend)
1598 // loop over all null-terminated sequences in frm
1600 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1602 // save state in case it is needed to recover to_nxt on error
1603 mbstate_t save_state = st;
1604 size_t n = __libcpp_mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1605 static_cast<size_t>(to_end-to), &st, __l);
1606 if (n == size_t(-1))
1608 // need to recover to_nxt
1609 for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1611 n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
1630 return frm_nxt == frm_end ? ok : partial;
1632 if (n == size_t(-1))
1635 if (to_nxt == to_end)
1637 if (fend != frm_end) // set up next null terminated sequence
1639 // Try to write the terminating null
1640 n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1641 if (n != 0) // on error
1645 // look for next null in frm
1646 for (fend = frm_nxt; fend != frm_end; ++fend)
1651 return frm_nxt == frm_end ? ok : partial;
1654 codecvt<wchar_t, char, mbstate_t>::result
1655 codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1656 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1659 extern_type tmp[MB_LEN_MAX];
1660 size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l);
1661 if (n == size_t(-1) || n == 0) // on error
1664 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1666 for (extern_type* p = tmp; n; --n) // write it
1672 codecvt<wchar_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
1674 if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)
1677 // stateless encoding
1678 if (__l == 0 || __libcpp_mb_cur_max_l(__l) == 1) // there are no known constant length encodings
1679 return 1; // which take more than 1 char to form a wchar_t
1684 codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
1690 codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1691 const extern_type* frm, const extern_type* frm_end, size_t mx) const
1694 for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1696 size_t n = __libcpp_mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l);
1716 codecvt<wchar_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
1718 return __l == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l));
1722 // UTF-32 UTF-16 UTF-8 # of code points
1723 // first second first second third fourth
1724 // 000000 - 00007F 0000 - 007F 00 - 7F 127
1725 // 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1726 // 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1727 // 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1728 // 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1729 // 00D800 - 00DFFF invalid
1730 // 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1731 // 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1732 // 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1733 // 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1736 codecvt_base::result
1737 utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1738 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1739 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1743 if (mode & generate_header)
1745 if (to_end-to_nxt < 3)
1746 return codecvt_base::partial;
1747 *to_nxt++ = static_cast<uint8_t>(0xEF);
1748 *to_nxt++ = static_cast<uint8_t>(0xBB);
1749 *to_nxt++ = static_cast<uint8_t>(0xBF);
1751 for (; frm_nxt < frm_end; ++frm_nxt)
1753 uint16_t wc1 = *frm_nxt;
1755 return codecvt_base::error;
1758 if (to_end-to_nxt < 1)
1759 return codecvt_base::partial;
1760 *to_nxt++ = static_cast<uint8_t>(wc1);
1762 else if (wc1 < 0x0800)
1764 if (to_end-to_nxt < 2)
1765 return codecvt_base::partial;
1766 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1767 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1769 else if (wc1 < 0xD800)
1771 if (to_end-to_nxt < 3)
1772 return codecvt_base::partial;
1773 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1774 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1775 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1777 else if (wc1 < 0xDC00)
1779 if (frm_end-frm_nxt < 2)
1780 return codecvt_base::partial;
1781 uint16_t wc2 = frm_nxt[1];
1782 if ((wc2 & 0xFC00) != 0xDC00)
1783 return codecvt_base::error;
1784 if (to_end-to_nxt < 4)
1785 return codecvt_base::partial;
1786 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1787 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1788 return codecvt_base::error;
1790 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1791 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1792 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1793 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1794 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1796 else if (wc1 < 0xE000)
1798 return codecvt_base::error;
1802 if (to_end-to_nxt < 3)
1803 return codecvt_base::partial;
1804 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1805 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1806 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1809 return codecvt_base::ok;
1813 codecvt_base::result
1814 utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1815 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1816 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1820 if (mode & generate_header)
1822 if (to_end-to_nxt < 3)
1823 return codecvt_base::partial;
1824 *to_nxt++ = static_cast<uint8_t>(0xEF);
1825 *to_nxt++ = static_cast<uint8_t>(0xBB);
1826 *to_nxt++ = static_cast<uint8_t>(0xBF);
1828 for (; frm_nxt < frm_end; ++frm_nxt)
1830 uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1832 return codecvt_base::error;
1835 if (to_end-to_nxt < 1)
1836 return codecvt_base::partial;
1837 *to_nxt++ = static_cast<uint8_t>(wc1);
1839 else if (wc1 < 0x0800)
1841 if (to_end-to_nxt < 2)
1842 return codecvt_base::partial;
1843 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1844 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1846 else if (wc1 < 0xD800)
1848 if (to_end-to_nxt < 3)
1849 return codecvt_base::partial;
1850 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1851 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1852 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1854 else if (wc1 < 0xDC00)
1856 if (frm_end-frm_nxt < 2)
1857 return codecvt_base::partial;
1858 uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1859 if ((wc2 & 0xFC00) != 0xDC00)
1860 return codecvt_base::error;
1861 if (to_end-to_nxt < 4)
1862 return codecvt_base::partial;
1863 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1864 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1865 return codecvt_base::error;
1867 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1868 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1869 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1870 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1871 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1873 else if (wc1 < 0xE000)
1875 return codecvt_base::error;
1879 if (to_end-to_nxt < 3)
1880 return codecvt_base::partial;
1881 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1882 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1883 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1886 return codecvt_base::ok;
1890 codecvt_base::result
1891 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1892 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1893 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1897 if (mode & consume_header)
1899 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1903 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1905 uint8_t c1 = *frm_nxt;
1907 return codecvt_base::error;
1910 *to_nxt = static_cast<uint16_t>(c1);
1915 return codecvt_base::error;
1919 if (frm_end-frm_nxt < 2)
1920 return codecvt_base::partial;
1921 uint8_t c2 = frm_nxt[1];
1922 if ((c2 & 0xC0) != 0x80)
1923 return codecvt_base::error;
1924 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1926 return codecvt_base::error;
1932 if (frm_end-frm_nxt < 3)
1933 return codecvt_base::partial;
1934 uint8_t c2 = frm_nxt[1];
1935 uint8_t c3 = frm_nxt[2];
1939 if ((c2 & 0xE0) != 0xA0)
1940 return codecvt_base::error;
1943 if ((c2 & 0xE0) != 0x80)
1944 return codecvt_base::error;
1947 if ((c2 & 0xC0) != 0x80)
1948 return codecvt_base::error;
1951 if ((c3 & 0xC0) != 0x80)
1952 return codecvt_base::error;
1953 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1954 | ((c2 & 0x3F) << 6)
1957 return codecvt_base::error;
1963 if (frm_end-frm_nxt < 4)
1964 return codecvt_base::partial;
1965 uint8_t c2 = frm_nxt[1];
1966 uint8_t c3 = frm_nxt[2];
1967 uint8_t c4 = frm_nxt[3];
1971 if (!(0x90 <= c2 && c2 <= 0xBF))
1972 return codecvt_base::error;
1975 if ((c2 & 0xF0) != 0x80)
1976 return codecvt_base::error;
1979 if ((c2 & 0xC0) != 0x80)
1980 return codecvt_base::error;
1983 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1984 return codecvt_base::error;
1985 if (to_end-to_nxt < 2)
1986 return codecvt_base::partial;
1987 if ((((c1 & 7UL) << 18) +
1988 ((c2 & 0x3FUL) << 12) +
1989 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
1990 return codecvt_base::error;
1991 *to_nxt = static_cast<uint16_t>(
1993 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1994 | ((c2 & 0x0F) << 2)
1995 | ((c3 & 0x30) >> 4));
1996 *++to_nxt = static_cast<uint16_t>(
1998 | ((c3 & 0x0F) << 6)
2004 return codecvt_base::error;
2007 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2011 codecvt_base::result
2012 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2013 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2014 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2018 if (mode & consume_header)
2020 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2024 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2026 uint8_t c1 = *frm_nxt;
2028 return codecvt_base::error;
2031 *to_nxt = static_cast<uint32_t>(c1);
2036 return codecvt_base::error;
2040 if (frm_end-frm_nxt < 2)
2041 return codecvt_base::partial;
2042 uint8_t c2 = frm_nxt[1];
2043 if ((c2 & 0xC0) != 0x80)
2044 return codecvt_base::error;
2045 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2047 return codecvt_base::error;
2048 *to_nxt = static_cast<uint32_t>(t);
2053 if (frm_end-frm_nxt < 3)
2054 return codecvt_base::partial;
2055 uint8_t c2 = frm_nxt[1];
2056 uint8_t c3 = frm_nxt[2];
2060 if ((c2 & 0xE0) != 0xA0)
2061 return codecvt_base::error;
2064 if ((c2 & 0xE0) != 0x80)
2065 return codecvt_base::error;
2068 if ((c2 & 0xC0) != 0x80)
2069 return codecvt_base::error;
2072 if ((c3 & 0xC0) != 0x80)
2073 return codecvt_base::error;
2074 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2075 | ((c2 & 0x3F) << 6)
2078 return codecvt_base::error;
2079 *to_nxt = static_cast<uint32_t>(t);
2084 if (frm_end-frm_nxt < 4)
2085 return codecvt_base::partial;
2086 uint8_t c2 = frm_nxt[1];
2087 uint8_t c3 = frm_nxt[2];
2088 uint8_t c4 = frm_nxt[3];
2092 if (!(0x90 <= c2 && c2 <= 0xBF))
2093 return codecvt_base::error;
2096 if ((c2 & 0xF0) != 0x80)
2097 return codecvt_base::error;
2100 if ((c2 & 0xC0) != 0x80)
2101 return codecvt_base::error;
2104 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2105 return codecvt_base::error;
2106 if (to_end-to_nxt < 2)
2107 return codecvt_base::partial;
2108 if ((((c1 & 7UL) << 18) +
2109 ((c2 & 0x3FUL) << 12) +
2110 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2111 return codecvt_base::error;
2112 *to_nxt = static_cast<uint32_t>(
2114 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2115 | ((c2 & 0x0F) << 2)
2116 | ((c3 & 0x30) >> 4));
2117 *++to_nxt = static_cast<uint32_t>(
2119 | ((c3 & 0x0F) << 6)
2125 return codecvt_base::error;
2128 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2133 utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
2134 size_t mx, unsigned long Maxcode = 0x10FFFF,
2135 codecvt_mode mode = codecvt_mode(0))
2137 const uint8_t* frm_nxt = frm;
2138 if (mode & consume_header)
2140 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2144 for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
2146 uint8_t c1 = *frm_nxt;
2159 if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
2161 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
2168 if (frm_end-frm_nxt < 3)
2170 uint8_t c2 = frm_nxt[1];
2171 uint8_t c3 = frm_nxt[2];
2175 if ((c2 & 0xE0) != 0xA0)
2176 return static_cast<int>(frm_nxt - frm);
2179 if ((c2 & 0xE0) != 0x80)
2180 return static_cast<int>(frm_nxt - frm);
2183 if ((c2 & 0xC0) != 0x80)
2184 return static_cast<int>(frm_nxt - frm);
2187 if ((c3 & 0xC0) != 0x80)
2189 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2195 if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
2197 uint8_t c2 = frm_nxt[1];
2198 uint8_t c3 = frm_nxt[2];
2199 uint8_t c4 = frm_nxt[3];
2203 if (!(0x90 <= c2 && c2 <= 0xBF))
2204 return static_cast<int>(frm_nxt - frm);
2207 if ((c2 & 0xF0) != 0x80)
2208 return static_cast<int>(frm_nxt - frm);
2211 if ((c2 & 0xC0) != 0x80)
2212 return static_cast<int>(frm_nxt - frm);
2215 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2217 if ((((c1 & 7UL) << 18) +
2218 ((c2 & 0x3FUL) << 12) +
2219 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2229 return static_cast<int>(frm_nxt - frm);
2233 codecvt_base::result
2234 ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2235 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2236 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2240 if (mode & generate_header)
2242 if (to_end-to_nxt < 3)
2243 return codecvt_base::partial;
2244 *to_nxt++ = static_cast<uint8_t>(0xEF);
2245 *to_nxt++ = static_cast<uint8_t>(0xBB);
2246 *to_nxt++ = static_cast<uint8_t>(0xBF);
2248 for (; frm_nxt < frm_end; ++frm_nxt)
2250 uint32_t wc = *frm_nxt;
2251 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2252 return codecvt_base::error;
2255 if (to_end-to_nxt < 1)
2256 return codecvt_base::partial;
2257 *to_nxt++ = static_cast<uint8_t>(wc);
2259 else if (wc < 0x000800)
2261 if (to_end-to_nxt < 2)
2262 return codecvt_base::partial;
2263 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2264 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2266 else if (wc < 0x010000)
2268 if (to_end-to_nxt < 3)
2269 return codecvt_base::partial;
2270 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2271 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2272 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2274 else // if (wc < 0x110000)
2276 if (to_end-to_nxt < 4)
2277 return codecvt_base::partial;
2278 *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
2279 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2280 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2281 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
2284 return codecvt_base::ok;
2288 codecvt_base::result
2289 utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2290 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2291 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2295 if (mode & consume_header)
2297 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2301 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2303 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2307 return codecvt_base::error;
2308 *to_nxt = static_cast<uint32_t>(c1);
2313 return codecvt_base::error;
2317 if (frm_end-frm_nxt < 2)
2318 return codecvt_base::partial;
2319 uint8_t c2 = frm_nxt[1];
2320 if ((c2 & 0xC0) != 0x80)
2321 return codecvt_base::error;
2322 uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2325 return codecvt_base::error;
2331 if (frm_end-frm_nxt < 3)
2332 return codecvt_base::partial;
2333 uint8_t c2 = frm_nxt[1];
2334 uint8_t c3 = frm_nxt[2];
2338 if ((c2 & 0xE0) != 0xA0)
2339 return codecvt_base::error;
2342 if ((c2 & 0xE0) != 0x80)
2343 return codecvt_base::error;
2346 if ((c2 & 0xC0) != 0x80)
2347 return codecvt_base::error;
2350 if ((c3 & 0xC0) != 0x80)
2351 return codecvt_base::error;
2352 uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2353 | ((c2 & 0x3F) << 6)
2356 return codecvt_base::error;
2362 if (frm_end-frm_nxt < 4)
2363 return codecvt_base::partial;
2364 uint8_t c2 = frm_nxt[1];
2365 uint8_t c3 = frm_nxt[2];
2366 uint8_t c4 = frm_nxt[3];
2370 if (!(0x90 <= c2 && c2 <= 0xBF))
2371 return codecvt_base::error;
2374 if ((c2 & 0xF0) != 0x80)
2375 return codecvt_base::error;
2378 if ((c2 & 0xC0) != 0x80)
2379 return codecvt_base::error;
2382 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2383 return codecvt_base::error;
2384 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2385 | ((c2 & 0x3F) << 12)
2386 | ((c3 & 0x3F) << 6)
2389 return codecvt_base::error;
2395 return codecvt_base::error;
2398 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2403 utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2404 size_t mx, unsigned long Maxcode = 0x10FFFF,
2405 codecvt_mode mode = codecvt_mode(0))
2407 const uint8_t* frm_nxt = frm;
2408 if (mode & consume_header)
2410 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2414 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2416 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2429 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2431 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2437 if (frm_end-frm_nxt < 3)
2439 uint8_t c2 = frm_nxt[1];
2440 uint8_t c3 = frm_nxt[2];
2444 if ((c2 & 0xE0) != 0xA0)
2445 return static_cast<int>(frm_nxt - frm);
2448 if ((c2 & 0xE0) != 0x80)
2449 return static_cast<int>(frm_nxt - frm);
2452 if ((c2 & 0xC0) != 0x80)
2453 return static_cast<int>(frm_nxt - frm);
2456 if ((c3 & 0xC0) != 0x80)
2458 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2464 if (frm_end-frm_nxt < 4)
2466 uint8_t c2 = frm_nxt[1];
2467 uint8_t c3 = frm_nxt[2];
2468 uint8_t c4 = frm_nxt[3];
2472 if (!(0x90 <= c2 && c2 <= 0xBF))
2473 return static_cast<int>(frm_nxt - frm);
2476 if ((c2 & 0xF0) != 0x80)
2477 return static_cast<int>(frm_nxt - frm);
2480 if ((c2 & 0xC0) != 0x80)
2481 return static_cast<int>(frm_nxt - frm);
2484 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2486 if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
2487 ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode)
2496 return static_cast<int>(frm_nxt - frm);
2500 codecvt_base::result
2501 ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2502 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2503 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2507 if (mode & generate_header)
2509 if (to_end-to_nxt < 3)
2510 return codecvt_base::partial;
2511 *to_nxt++ = static_cast<uint8_t>(0xEF);
2512 *to_nxt++ = static_cast<uint8_t>(0xBB);
2513 *to_nxt++ = static_cast<uint8_t>(0xBF);
2515 for (; frm_nxt < frm_end; ++frm_nxt)
2517 uint16_t wc = *frm_nxt;
2518 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2519 return codecvt_base::error;
2522 if (to_end-to_nxt < 1)
2523 return codecvt_base::partial;
2524 *to_nxt++ = static_cast<uint8_t>(wc);
2526 else if (wc < 0x0800)
2528 if (to_end-to_nxt < 2)
2529 return codecvt_base::partial;
2530 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2531 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2533 else // if (wc <= 0xFFFF)
2535 if (to_end-to_nxt < 3)
2536 return codecvt_base::partial;
2537 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2538 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2539 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2542 return codecvt_base::ok;
2546 codecvt_base::result
2547 utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2548 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2549 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2553 if (mode & consume_header)
2555 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2559 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2561 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2565 return codecvt_base::error;
2566 *to_nxt = static_cast<uint16_t>(c1);
2571 return codecvt_base::error;
2575 if (frm_end-frm_nxt < 2)
2576 return codecvt_base::partial;
2577 uint8_t c2 = frm_nxt[1];
2578 if ((c2 & 0xC0) != 0x80)
2579 return codecvt_base::error;
2580 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2583 return codecvt_base::error;
2589 if (frm_end-frm_nxt < 3)
2590 return codecvt_base::partial;
2591 uint8_t c2 = frm_nxt[1];
2592 uint8_t c3 = frm_nxt[2];
2596 if ((c2 & 0xE0) != 0xA0)
2597 return codecvt_base::error;
2600 if ((c2 & 0xE0) != 0x80)
2601 return codecvt_base::error;
2604 if ((c2 & 0xC0) != 0x80)
2605 return codecvt_base::error;
2608 if ((c3 & 0xC0) != 0x80)
2609 return codecvt_base::error;
2610 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2611 | ((c2 & 0x3F) << 6)
2614 return codecvt_base::error;
2620 return codecvt_base::error;
2623 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2628 utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2629 size_t mx, unsigned long Maxcode = 0x10FFFF,
2630 codecvt_mode mode = codecvt_mode(0))
2632 const uint8_t* frm_nxt = frm;
2633 if (mode & consume_header)
2635 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2639 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2641 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2654 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2656 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2662 if (frm_end-frm_nxt < 3)
2664 uint8_t c2 = frm_nxt[1];
2665 uint8_t c3 = frm_nxt[2];
2669 if ((c2 & 0xE0) != 0xA0)
2670 return static_cast<int>(frm_nxt - frm);
2673 if ((c2 & 0xE0) != 0x80)
2674 return static_cast<int>(frm_nxt - frm);
2677 if ((c2 & 0xC0) != 0x80)
2678 return static_cast<int>(frm_nxt - frm);
2681 if ((c3 & 0xC0) != 0x80)
2683 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2692 return static_cast<int>(frm_nxt - frm);
2696 codecvt_base::result
2697 ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2698 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2699 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2703 if (mode & generate_header)
2705 if (to_end-to_nxt < 2)
2706 return codecvt_base::partial;
2707 *to_nxt++ = static_cast<uint8_t>(0xFE);
2708 *to_nxt++ = static_cast<uint8_t>(0xFF);
2710 for (; frm_nxt < frm_end; ++frm_nxt)
2712 uint32_t wc = *frm_nxt;
2713 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2714 return codecvt_base::error;
2717 if (to_end-to_nxt < 2)
2718 return codecvt_base::partial;
2719 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2720 *to_nxt++ = static_cast<uint8_t>(wc);
2724 if (to_end-to_nxt < 4)
2725 return codecvt_base::partial;
2726 uint16_t t = static_cast<uint16_t>(
2728 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2729 | ((wc & 0x00FC00) >> 10));
2730 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2731 *to_nxt++ = static_cast<uint8_t>(t);
2732 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2733 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2734 *to_nxt++ = static_cast<uint8_t>(t);
2737 return codecvt_base::ok;
2741 codecvt_base::result
2742 utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2743 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2744 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2748 if (mode & consume_header)
2750 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2753 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2755 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2756 if ((c1 & 0xFC00) == 0xDC00)
2757 return codecvt_base::error;
2758 if ((c1 & 0xFC00) != 0xD800)
2761 return codecvt_base::error;
2762 *to_nxt = static_cast<uint32_t>(c1);
2767 if (frm_end-frm_nxt < 4)
2768 return codecvt_base::partial;
2769 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2770 if ((c2 & 0xFC00) != 0xDC00)
2771 return codecvt_base::error;
2772 uint32_t t = static_cast<uint32_t>(
2773 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2774 | ((c1 & 0x003F) << 10)
2777 return codecvt_base::error;
2782 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2787 utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2788 size_t mx, unsigned long Maxcode = 0x10FFFF,
2789 codecvt_mode mode = codecvt_mode(0))
2791 const uint8_t* frm_nxt = frm;
2792 if (mode & consume_header)
2794 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2797 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2799 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2800 if ((c1 & 0xFC00) == 0xDC00)
2802 if ((c1 & 0xFC00) != 0xD800)
2810 if (frm_end-frm_nxt < 4)
2812 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2813 if ((c2 & 0xFC00) != 0xDC00)
2815 uint32_t t = static_cast<uint32_t>(
2816 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2817 | ((c1 & 0x003F) << 10)
2824 return static_cast<int>(frm_nxt - frm);
2828 codecvt_base::result
2829 ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2830 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2831 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2835 if (mode & generate_header)
2837 if (to_end - to_nxt < 2)
2838 return codecvt_base::partial;
2839 *to_nxt++ = static_cast<uint8_t>(0xFF);
2840 *to_nxt++ = static_cast<uint8_t>(0xFE);
2842 for (; frm_nxt < frm_end; ++frm_nxt)
2844 uint32_t wc = *frm_nxt;
2845 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2846 return codecvt_base::error;
2849 if (to_end-to_nxt < 2)
2850 return codecvt_base::partial;
2851 *to_nxt++ = static_cast<uint8_t>(wc);
2852 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2856 if (to_end-to_nxt < 4)
2857 return codecvt_base::partial;
2858 uint16_t t = static_cast<uint16_t>(
2860 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2861 | ((wc & 0x00FC00) >> 10));
2862 *to_nxt++ = static_cast<uint8_t>(t);
2863 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2864 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2865 *to_nxt++ = static_cast<uint8_t>(t);
2866 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2869 return codecvt_base::ok;
2873 codecvt_base::result
2874 utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2875 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2876 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2880 if (mode & consume_header)
2882 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2885 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2887 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2888 if ((c1 & 0xFC00) == 0xDC00)
2889 return codecvt_base::error;
2890 if ((c1 & 0xFC00) != 0xD800)
2893 return codecvt_base::error;
2894 *to_nxt = static_cast<uint32_t>(c1);
2899 if (frm_end-frm_nxt < 4)
2900 return codecvt_base::partial;
2901 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2902 if ((c2 & 0xFC00) != 0xDC00)
2903 return codecvt_base::error;
2904 uint32_t t = static_cast<uint32_t>(
2905 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2906 | ((c1 & 0x003F) << 10)
2909 return codecvt_base::error;
2914 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2919 utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2920 size_t mx, unsigned long Maxcode = 0x10FFFF,
2921 codecvt_mode mode = codecvt_mode(0))
2923 const uint8_t* frm_nxt = frm;
2924 if (mode & consume_header)
2926 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2929 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2931 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2932 if ((c1 & 0xFC00) == 0xDC00)
2934 if ((c1 & 0xFC00) != 0xD800)
2942 if (frm_end-frm_nxt < 4)
2944 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2945 if ((c2 & 0xFC00) != 0xDC00)
2947 uint32_t t = static_cast<uint32_t>(
2948 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2949 | ((c1 & 0x003F) << 10)
2956 return static_cast<int>(frm_nxt - frm);
2960 codecvt_base::result
2961 ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2962 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2963 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2967 if (mode & generate_header)
2969 if (to_end-to_nxt < 2)
2970 return codecvt_base::partial;
2971 *to_nxt++ = static_cast<uint8_t>(0xFE);
2972 *to_nxt++ = static_cast<uint8_t>(0xFF);
2974 for (; frm_nxt < frm_end; ++frm_nxt)
2976 uint16_t wc = *frm_nxt;
2977 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2978 return codecvt_base::error;
2979 if (to_end-to_nxt < 2)
2980 return codecvt_base::partial;
2981 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2982 *to_nxt++ = static_cast<uint8_t>(wc);
2984 return codecvt_base::ok;
2988 codecvt_base::result
2989 utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2990 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2991 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2995 if (mode & consume_header)
2997 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3000 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3002 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
3003 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3004 return codecvt_base::error;
3008 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3013 utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3014 size_t mx, unsigned long Maxcode = 0x10FFFF,
3015 codecvt_mode mode = codecvt_mode(0))
3017 const uint8_t* frm_nxt = frm;
3018 if (mode & consume_header)
3020 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3023 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3025 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
3026 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3030 return static_cast<int>(frm_nxt - frm);
3034 codecvt_base::result
3035 ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3036 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3037 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3041 if (mode & generate_header)
3043 if (to_end-to_nxt < 2)
3044 return codecvt_base::partial;
3045 *to_nxt++ = static_cast<uint8_t>(0xFF);
3046 *to_nxt++ = static_cast<uint8_t>(0xFE);
3048 for (; frm_nxt < frm_end; ++frm_nxt)
3050 uint16_t wc = *frm_nxt;
3051 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3052 return codecvt_base::error;
3053 if (to_end-to_nxt < 2)
3054 return codecvt_base::partial;
3055 *to_nxt++ = static_cast<uint8_t>(wc);
3056 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3058 return codecvt_base::ok;
3062 codecvt_base::result
3063 utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3064 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3065 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3069 if (mode & consume_header)
3071 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3074 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3076 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3077 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3078 return codecvt_base::error;
3082 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3087 utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3088 size_t mx, unsigned long Maxcode = 0x10FFFF,
3089 codecvt_mode mode = codecvt_mode(0))
3091 const uint8_t* frm_nxt = frm;
3093 if (mode & consume_header)
3095 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3098 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3100 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3101 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3105 return static_cast<int>(frm_nxt - frm);
3108 // template <> class codecvt<char16_t, char, mbstate_t>
3110 locale::id codecvt<char16_t, char, mbstate_t>::id;
3112 codecvt<char16_t, char, mbstate_t>::~codecvt()
3116 codecvt<char16_t, char, mbstate_t>::result
3117 codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
3118 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3119 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3121 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3122 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3123 const uint16_t* _frm_nxt = _frm;
3124 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3125 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3126 uint8_t* _to_nxt = _to;
3127 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3128 frm_nxt = frm + (_frm_nxt - _frm);
3129 to_nxt = to + (_to_nxt - _to);
3133 codecvt<char16_t, char, mbstate_t>::result
3134 codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
3135 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3136 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3138 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3139 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3140 const uint8_t* _frm_nxt = _frm;
3141 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3142 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3143 uint16_t* _to_nxt = _to;
3144 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3145 frm_nxt = frm + (_frm_nxt - _frm);
3146 to_nxt = to + (_to_nxt - _to);
3150 codecvt<char16_t, char, mbstate_t>::result
3151 codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
3152 extern_type* to, extern_type*, extern_type*& to_nxt) const
3159 codecvt<char16_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
3165 codecvt<char16_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
3171 codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
3172 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3174 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3175 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3176 return utf8_to_utf16_length(_frm, _frm_end, mx);
3180 codecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
3185 // template <> class codecvt<char32_t, char, mbstate_t>
3187 locale::id codecvt<char32_t, char, mbstate_t>::id;
3189 codecvt<char32_t, char, mbstate_t>::~codecvt()
3193 codecvt<char32_t, char, mbstate_t>::result
3194 codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
3195 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3196 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3198 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3199 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3200 const uint32_t* _frm_nxt = _frm;
3201 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3202 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3203 uint8_t* _to_nxt = _to;
3204 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3205 frm_nxt = frm + (_frm_nxt - _frm);
3206 to_nxt = to + (_to_nxt - _to);
3210 codecvt<char32_t, char, mbstate_t>::result
3211 codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
3212 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3213 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3215 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3216 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3217 const uint8_t* _frm_nxt = _frm;
3218 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3219 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3220 uint32_t* _to_nxt = _to;
3221 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3222 frm_nxt = frm + (_frm_nxt - _frm);
3223 to_nxt = to + (_to_nxt - _to);
3227 codecvt<char32_t, char, mbstate_t>::result
3228 codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3229 extern_type* to, extern_type*, extern_type*& to_nxt) const
3236 codecvt<char32_t, char, mbstate_t>::do_encoding() const _NOEXCEPT
3242 codecvt<char32_t, char, mbstate_t>::do_always_noconv() const _NOEXCEPT
3248 codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3249 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3251 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3252 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3253 return utf8_to_ucs4_length(_frm, _frm_end, mx);
3257 codecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
3262 // __codecvt_utf8<wchar_t>
3264 __codecvt_utf8<wchar_t>::result
3265 __codecvt_utf8<wchar_t>::do_out(state_type&,
3266 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3267 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3269 #if defined(_LIBCPP_SHORT_WCHAR)
3270 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3271 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3272 const uint16_t* _frm_nxt = _frm;
3274 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3275 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3276 const uint32_t* _frm_nxt = _frm;
3278 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3279 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3280 uint8_t* _to_nxt = _to;
3281 #if defined(_LIBCPP_SHORT_WCHAR)
3282 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3285 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3288 frm_nxt = frm + (_frm_nxt - _frm);
3289 to_nxt = to + (_to_nxt - _to);
3293 __codecvt_utf8<wchar_t>::result
3294 __codecvt_utf8<wchar_t>::do_in(state_type&,
3295 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3296 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3298 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3299 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3300 const uint8_t* _frm_nxt = _frm;
3301 #if defined(_LIBCPP_SHORT_WCHAR)
3302 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3303 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3304 uint16_t* _to_nxt = _to;
3305 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3308 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3309 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3310 uint32_t* _to_nxt = _to;
3311 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3314 frm_nxt = frm + (_frm_nxt - _frm);
3315 to_nxt = to + (_to_nxt - _to);
3319 __codecvt_utf8<wchar_t>::result
3320 __codecvt_utf8<wchar_t>::do_unshift(state_type&,
3321 extern_type* to, extern_type*, extern_type*& to_nxt) const
3328 __codecvt_utf8<wchar_t>::do_encoding() const _NOEXCEPT
3334 __codecvt_utf8<wchar_t>::do_always_noconv() const _NOEXCEPT
3340 __codecvt_utf8<wchar_t>::do_length(state_type&,
3341 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3343 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3344 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3345 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3349 __codecvt_utf8<wchar_t>::do_max_length() const _NOEXCEPT
3351 if (_Mode_ & consume_header)
3356 // __codecvt_utf8<char16_t>
3358 __codecvt_utf8<char16_t>::result
3359 __codecvt_utf8<char16_t>::do_out(state_type&,
3360 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3361 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3363 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3364 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3365 const uint16_t* _frm_nxt = _frm;
3366 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3367 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3368 uint8_t* _to_nxt = _to;
3369 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3371 frm_nxt = frm + (_frm_nxt - _frm);
3372 to_nxt = to + (_to_nxt - _to);
3376 __codecvt_utf8<char16_t>::result
3377 __codecvt_utf8<char16_t>::do_in(state_type&,
3378 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3379 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3381 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3382 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3383 const uint8_t* _frm_nxt = _frm;
3384 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3385 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3386 uint16_t* _to_nxt = _to;
3387 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3389 frm_nxt = frm + (_frm_nxt - _frm);
3390 to_nxt = to + (_to_nxt - _to);
3394 __codecvt_utf8<char16_t>::result
3395 __codecvt_utf8<char16_t>::do_unshift(state_type&,
3396 extern_type* to, extern_type*, extern_type*& to_nxt) const
3403 __codecvt_utf8<char16_t>::do_encoding() const _NOEXCEPT
3409 __codecvt_utf8<char16_t>::do_always_noconv() const _NOEXCEPT
3415 __codecvt_utf8<char16_t>::do_length(state_type&,
3416 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3418 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3419 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3420 return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3424 __codecvt_utf8<char16_t>::do_max_length() const _NOEXCEPT
3426 if (_Mode_ & consume_header)
3431 // __codecvt_utf8<char32_t>
3433 __codecvt_utf8<char32_t>::result
3434 __codecvt_utf8<char32_t>::do_out(state_type&,
3435 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3436 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3438 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3439 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3440 const uint32_t* _frm_nxt = _frm;
3441 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3442 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3443 uint8_t* _to_nxt = _to;
3444 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3446 frm_nxt = frm + (_frm_nxt - _frm);
3447 to_nxt = to + (_to_nxt - _to);
3451 __codecvt_utf8<char32_t>::result
3452 __codecvt_utf8<char32_t>::do_in(state_type&,
3453 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3454 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3456 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3457 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3458 const uint8_t* _frm_nxt = _frm;
3459 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3460 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3461 uint32_t* _to_nxt = _to;
3462 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3464 frm_nxt = frm + (_frm_nxt - _frm);
3465 to_nxt = to + (_to_nxt - _to);
3469 __codecvt_utf8<char32_t>::result
3470 __codecvt_utf8<char32_t>::do_unshift(state_type&,
3471 extern_type* to, extern_type*, extern_type*& to_nxt) const
3478 __codecvt_utf8<char32_t>::do_encoding() const _NOEXCEPT
3484 __codecvt_utf8<char32_t>::do_always_noconv() const _NOEXCEPT
3490 __codecvt_utf8<char32_t>::do_length(state_type&,
3491 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3493 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3494 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3495 return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3499 __codecvt_utf8<char32_t>::do_max_length() const _NOEXCEPT
3501 if (_Mode_ & consume_header)
3506 // __codecvt_utf16<wchar_t, false>
3508 __codecvt_utf16<wchar_t, false>::result
3509 __codecvt_utf16<wchar_t, false>::do_out(state_type&,
3510 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3511 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3513 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3514 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3515 const uint32_t* _frm_nxt = _frm;
3516 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3517 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3518 uint8_t* _to_nxt = _to;
3519 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3521 frm_nxt = frm + (_frm_nxt - _frm);
3522 to_nxt = to + (_to_nxt - _to);
3526 __codecvt_utf16<wchar_t, false>::result
3527 __codecvt_utf16<wchar_t, false>::do_in(state_type&,
3528 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3529 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3531 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3532 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3533 const uint8_t* _frm_nxt = _frm;
3534 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3535 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3536 uint32_t* _to_nxt = _to;
3537 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3539 frm_nxt = frm + (_frm_nxt - _frm);
3540 to_nxt = to + (_to_nxt - _to);
3544 __codecvt_utf16<wchar_t, false>::result
3545 __codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3546 extern_type* to, extern_type*, extern_type*& to_nxt) const
3553 __codecvt_utf16<wchar_t, false>::do_encoding() const _NOEXCEPT
3559 __codecvt_utf16<wchar_t, false>::do_always_noconv() const _NOEXCEPT
3565 __codecvt_utf16<wchar_t, false>::do_length(state_type&,
3566 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3568 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3569 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3570 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3574 __codecvt_utf16<wchar_t, false>::do_max_length() const _NOEXCEPT
3576 if (_Mode_ & consume_header)
3581 // __codecvt_utf16<wchar_t, true>
3583 __codecvt_utf16<wchar_t, true>::result
3584 __codecvt_utf16<wchar_t, true>::do_out(state_type&,
3585 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3586 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3588 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3589 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3590 const uint32_t* _frm_nxt = _frm;
3591 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3592 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3593 uint8_t* _to_nxt = _to;
3594 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3596 frm_nxt = frm + (_frm_nxt - _frm);
3597 to_nxt = to + (_to_nxt - _to);
3601 __codecvt_utf16<wchar_t, true>::result
3602 __codecvt_utf16<wchar_t, true>::do_in(state_type&,
3603 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3604 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3606 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3607 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3608 const uint8_t* _frm_nxt = _frm;
3609 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3610 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3611 uint32_t* _to_nxt = _to;
3612 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3614 frm_nxt = frm + (_frm_nxt - _frm);
3615 to_nxt = to + (_to_nxt - _to);
3619 __codecvt_utf16<wchar_t, true>::result
3620 __codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3621 extern_type* to, extern_type*, extern_type*& to_nxt) const
3628 __codecvt_utf16<wchar_t, true>::do_encoding() const _NOEXCEPT
3634 __codecvt_utf16<wchar_t, true>::do_always_noconv() const _NOEXCEPT
3640 __codecvt_utf16<wchar_t, true>::do_length(state_type&,
3641 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3643 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3644 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3645 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3649 __codecvt_utf16<wchar_t, true>::do_max_length() const _NOEXCEPT
3651 if (_Mode_ & consume_header)
3656 // __codecvt_utf16<char16_t, false>
3658 __codecvt_utf16<char16_t, false>::result
3659 __codecvt_utf16<char16_t, false>::do_out(state_type&,
3660 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3661 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3663 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3664 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3665 const uint16_t* _frm_nxt = _frm;
3666 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3667 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3668 uint8_t* _to_nxt = _to;
3669 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3671 frm_nxt = frm + (_frm_nxt - _frm);
3672 to_nxt = to + (_to_nxt - _to);
3676 __codecvt_utf16<char16_t, false>::result
3677 __codecvt_utf16<char16_t, false>::do_in(state_type&,
3678 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3679 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3681 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3682 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3683 const uint8_t* _frm_nxt = _frm;
3684 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3685 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3686 uint16_t* _to_nxt = _to;
3687 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3689 frm_nxt = frm + (_frm_nxt - _frm);
3690 to_nxt = to + (_to_nxt - _to);
3694 __codecvt_utf16<char16_t, false>::result
3695 __codecvt_utf16<char16_t, false>::do_unshift(state_type&,
3696 extern_type* to, extern_type*, extern_type*& to_nxt) const
3703 __codecvt_utf16<char16_t, false>::do_encoding() const _NOEXCEPT
3709 __codecvt_utf16<char16_t, false>::do_always_noconv() const _NOEXCEPT
3715 __codecvt_utf16<char16_t, false>::do_length(state_type&,
3716 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3718 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3719 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3720 return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3724 __codecvt_utf16<char16_t, false>::do_max_length() const _NOEXCEPT
3726 if (_Mode_ & consume_header)
3731 // __codecvt_utf16<char16_t, true>
3733 __codecvt_utf16<char16_t, true>::result
3734 __codecvt_utf16<char16_t, true>::do_out(state_type&,
3735 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3736 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3738 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3739 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3740 const uint16_t* _frm_nxt = _frm;
3741 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3742 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3743 uint8_t* _to_nxt = _to;
3744 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3746 frm_nxt = frm + (_frm_nxt - _frm);
3747 to_nxt = to + (_to_nxt - _to);
3751 __codecvt_utf16<char16_t, true>::result
3752 __codecvt_utf16<char16_t, true>::do_in(state_type&,
3753 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3754 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3756 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3757 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3758 const uint8_t* _frm_nxt = _frm;
3759 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3760 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3761 uint16_t* _to_nxt = _to;
3762 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3764 frm_nxt = frm + (_frm_nxt - _frm);
3765 to_nxt = to + (_to_nxt - _to);
3769 __codecvt_utf16<char16_t, true>::result
3770 __codecvt_utf16<char16_t, true>::do_unshift(state_type&,
3771 extern_type* to, extern_type*, extern_type*& to_nxt) const
3778 __codecvt_utf16<char16_t, true>::do_encoding() const _NOEXCEPT
3784 __codecvt_utf16<char16_t, true>::do_always_noconv() const _NOEXCEPT
3790 __codecvt_utf16<char16_t, true>::do_length(state_type&,
3791 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3793 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3794 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3795 return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3799 __codecvt_utf16<char16_t, true>::do_max_length() const _NOEXCEPT
3801 if (_Mode_ & consume_header)
3806 // __codecvt_utf16<char32_t, false>
3808 __codecvt_utf16<char32_t, false>::result
3809 __codecvt_utf16<char32_t, false>::do_out(state_type&,
3810 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3811 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3813 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3814 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3815 const uint32_t* _frm_nxt = _frm;
3816 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3817 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3818 uint8_t* _to_nxt = _to;
3819 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3821 frm_nxt = frm + (_frm_nxt - _frm);
3822 to_nxt = to + (_to_nxt - _to);
3826 __codecvt_utf16<char32_t, false>::result
3827 __codecvt_utf16<char32_t, false>::do_in(state_type&,
3828 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3829 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3831 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3832 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3833 const uint8_t* _frm_nxt = _frm;
3834 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3835 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3836 uint32_t* _to_nxt = _to;
3837 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3839 frm_nxt = frm + (_frm_nxt - _frm);
3840 to_nxt = to + (_to_nxt - _to);
3844 __codecvt_utf16<char32_t, false>::result
3845 __codecvt_utf16<char32_t, false>::do_unshift(state_type&,
3846 extern_type* to, extern_type*, extern_type*& to_nxt) const
3853 __codecvt_utf16<char32_t, false>::do_encoding() const _NOEXCEPT
3859 __codecvt_utf16<char32_t, false>::do_always_noconv() const _NOEXCEPT
3865 __codecvt_utf16<char32_t, false>::do_length(state_type&,
3866 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3868 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3869 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3870 return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3874 __codecvt_utf16<char32_t, false>::do_max_length() const _NOEXCEPT
3876 if (_Mode_ & consume_header)
3881 // __codecvt_utf16<char32_t, true>
3883 __codecvt_utf16<char32_t, true>::result
3884 __codecvt_utf16<char32_t, true>::do_out(state_type&,
3885 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3886 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3888 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3889 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3890 const uint32_t* _frm_nxt = _frm;
3891 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3892 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3893 uint8_t* _to_nxt = _to;
3894 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3896 frm_nxt = frm + (_frm_nxt - _frm);
3897 to_nxt = to + (_to_nxt - _to);
3901 __codecvt_utf16<char32_t, true>::result
3902 __codecvt_utf16<char32_t, true>::do_in(state_type&,
3903 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3904 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3906 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3907 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3908 const uint8_t* _frm_nxt = _frm;
3909 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3910 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3911 uint32_t* _to_nxt = _to;
3912 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3914 frm_nxt = frm + (_frm_nxt - _frm);
3915 to_nxt = to + (_to_nxt - _to);
3919 __codecvt_utf16<char32_t, true>::result
3920 __codecvt_utf16<char32_t, true>::do_unshift(state_type&,
3921 extern_type* to, extern_type*, extern_type*& to_nxt) const
3928 __codecvt_utf16<char32_t, true>::do_encoding() const _NOEXCEPT
3934 __codecvt_utf16<char32_t, true>::do_always_noconv() const _NOEXCEPT
3940 __codecvt_utf16<char32_t, true>::do_length(state_type&,
3941 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3943 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3944 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3945 return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3949 __codecvt_utf16<char32_t, true>::do_max_length() const _NOEXCEPT
3951 if (_Mode_ & consume_header)
3956 // __codecvt_utf8_utf16<wchar_t>
3958 __codecvt_utf8_utf16<wchar_t>::result
3959 __codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
3960 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3961 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3963 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3964 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3965 const uint32_t* _frm_nxt = _frm;
3966 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3967 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3968 uint8_t* _to_nxt = _to;
3969 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3971 frm_nxt = frm + (_frm_nxt - _frm);
3972 to_nxt = to + (_to_nxt - _to);
3976 __codecvt_utf8_utf16<wchar_t>::result
3977 __codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
3978 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3979 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3981 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3982 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3983 const uint8_t* _frm_nxt = _frm;
3984 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3985 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3986 uint32_t* _to_nxt = _to;
3987 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3989 frm_nxt = frm + (_frm_nxt - _frm);
3990 to_nxt = to + (_to_nxt - _to);
3994 __codecvt_utf8_utf16<wchar_t>::result
3995 __codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
3996 extern_type* to, extern_type*, extern_type*& to_nxt) const
4003 __codecvt_utf8_utf16<wchar_t>::do_encoding() const _NOEXCEPT
4009 __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const _NOEXCEPT
4015 __codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
4016 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4018 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4019 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4020 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4024 __codecvt_utf8_utf16<wchar_t>::do_max_length() const _NOEXCEPT
4026 if (_Mode_ & consume_header)
4031 // __codecvt_utf8_utf16<char16_t>
4033 __codecvt_utf8_utf16<char16_t>::result
4034 __codecvt_utf8_utf16<char16_t>::do_out(state_type&,
4035 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4036 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4038 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4039 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4040 const uint16_t* _frm_nxt = _frm;
4041 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4042 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4043 uint8_t* _to_nxt = _to;
4044 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4046 frm_nxt = frm + (_frm_nxt - _frm);
4047 to_nxt = to + (_to_nxt - _to);
4051 __codecvt_utf8_utf16<char16_t>::result
4052 __codecvt_utf8_utf16<char16_t>::do_in(state_type&,
4053 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4054 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4056 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4057 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4058 const uint8_t* _frm_nxt = _frm;
4059 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4060 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4061 uint16_t* _to_nxt = _to;
4062 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4064 frm_nxt = frm + (_frm_nxt - _frm);
4065 to_nxt = to + (_to_nxt - _to);
4069 __codecvt_utf8_utf16<char16_t>::result
4070 __codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
4071 extern_type* to, extern_type*, extern_type*& to_nxt) const
4078 __codecvt_utf8_utf16<char16_t>::do_encoding() const _NOEXCEPT
4084 __codecvt_utf8_utf16<char16_t>::do_always_noconv() const _NOEXCEPT
4090 __codecvt_utf8_utf16<char16_t>::do_length(state_type&,
4091 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4093 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4094 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4095 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4099 __codecvt_utf8_utf16<char16_t>::do_max_length() const _NOEXCEPT
4101 if (_Mode_ & consume_header)
4106 // __codecvt_utf8_utf16<char32_t>
4108 __codecvt_utf8_utf16<char32_t>::result
4109 __codecvt_utf8_utf16<char32_t>::do_out(state_type&,
4110 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4111 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4113 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4114 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4115 const uint32_t* _frm_nxt = _frm;
4116 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4117 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4118 uint8_t* _to_nxt = _to;
4119 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4121 frm_nxt = frm + (_frm_nxt - _frm);
4122 to_nxt = to + (_to_nxt - _to);
4126 __codecvt_utf8_utf16<char32_t>::result
4127 __codecvt_utf8_utf16<char32_t>::do_in(state_type&,
4128 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4129 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4131 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4132 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4133 const uint8_t* _frm_nxt = _frm;
4134 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4135 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4136 uint32_t* _to_nxt = _to;
4137 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4139 frm_nxt = frm + (_frm_nxt - _frm);
4140 to_nxt = to + (_to_nxt - _to);
4144 __codecvt_utf8_utf16<char32_t>::result
4145 __codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
4146 extern_type* to, extern_type*, extern_type*& to_nxt) const
4153 __codecvt_utf8_utf16<char32_t>::do_encoding() const _NOEXCEPT
4159 __codecvt_utf8_utf16<char32_t>::do_always_noconv() const _NOEXCEPT
4165 __codecvt_utf8_utf16<char32_t>::do_length(state_type&,
4166 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4168 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4169 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4170 return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4174 __codecvt_utf8_utf16<char32_t>::do_max_length() const _NOEXCEPT
4176 if (_Mode_ & consume_header)
4181 // __narrow_to_utf8<16>
4183 __narrow_to_utf8<16>::~__narrow_to_utf8()
4187 // __narrow_to_utf8<32>
4189 __narrow_to_utf8<32>::~__narrow_to_utf8()
4193 // __widen_from_utf8<16>
4195 __widen_from_utf8<16>::~__widen_from_utf8()
4199 // __widen_from_utf8<32>
4201 __widen_from_utf8<32>::~__widen_from_utf8()
4206 static bool checked_string_to_wchar_convert(wchar_t& dest,
4213 size_t ret = __libcpp_mbrtowc_l(&out, ptr, strlen(ptr), &mb, loc);
4214 if (ret == static_cast<size_t>(-1) || ret == static_cast<size_t>(-2)) {
4221 static bool checked_string_to_char_convert(char& dest,
4230 // First convert the MBS into a wide char then attempt to narrow it using
4233 if (!checked_string_to_wchar_convert(wout, ptr, __loc))
4236 if ((res = __libcpp_wctob_l(wout, __loc)) != char_traits<char>::eof()) {
4240 // FIXME: Work around specific multibyte sequences that we can reasonable
4241 // translate into a different single byte.
4243 case L'\u00A0': // non-breaking space
4249 _LIBCPP_UNREACHABLE();
4253 // numpunct<char> && numpunct<wchar_t>
4255 locale::id numpunct< char >::id;
4256 locale::id numpunct<wchar_t>::id;
4258 numpunct<char>::numpunct(size_t refs)
4259 : locale::facet(refs),
4260 __decimal_point_('.'),
4261 __thousands_sep_(',')
4265 numpunct<wchar_t>::numpunct(size_t refs)
4266 : locale::facet(refs),
4267 __decimal_point_(L'.'),
4268 __thousands_sep_(L',')
4272 numpunct<char>::~numpunct()
4276 numpunct<wchar_t>::~numpunct()
4280 char numpunct< char >::do_decimal_point() const {return __decimal_point_;}
4281 wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
4283 char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;}
4284 wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
4286 string numpunct< char >::do_grouping() const {return __grouping_;}
4287 string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
4289 string numpunct< char >::do_truename() const {return "true";}
4290 wstring numpunct<wchar_t>::do_truename() const {return L"true";}
4292 string numpunct< char >::do_falsename() const {return "false";}
4293 wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
4295 // numpunct_byname<char>
4297 numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4298 : numpunct<char>(refs)
4303 numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4304 : numpunct<char>(refs)
4309 numpunct_byname<char>::~numpunct_byname()
4314 numpunct_byname<char>::__init(const char* nm)
4316 if (strcmp(nm, "C") != 0)
4318 __libcpp_unique_locale loc(nm);
4320 __throw_runtime_error("numpunct_byname<char>::numpunct_byname"
4321 " failed to construct for " + string(nm));
4323 lconv* lc = __libcpp_localeconv_l(loc.get());
4324 checked_string_to_char_convert(__decimal_point_, lc->decimal_point,
4326 checked_string_to_char_convert(__thousands_sep_, lc->thousands_sep,
4328 __grouping_ = lc->grouping;
4329 // localization for truename and falsename is not available
4333 // numpunct_byname<wchar_t>
4335 numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4336 : numpunct<wchar_t>(refs)
4341 numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4342 : numpunct<wchar_t>(refs)
4347 numpunct_byname<wchar_t>::~numpunct_byname()
4352 numpunct_byname<wchar_t>::__init(const char* nm)
4354 if (strcmp(nm, "C") != 0)
4356 __libcpp_unique_locale loc(nm);
4358 __throw_runtime_error("numpunct_byname<wchar_t>::numpunct_byname"
4359 " failed to construct for " + string(nm));
4361 lconv* lc = __libcpp_localeconv_l(loc.get());
4362 checked_string_to_wchar_convert(__decimal_point_, lc->decimal_point,
4364 checked_string_to_wchar_convert(__thousands_sep_, lc->thousands_sep,
4366 __grouping_ = lc->grouping;
4367 // localization for truename and falsename is not available
4374 __num_get_base::__get_base(ios_base& iob)
4376 ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4377 if (__basefield == ios_base::oct)
4379 else if (__basefield == ios_base::hex)
4381 else if (__basefield == 0)
4386 const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4389 __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4390 ios_base::iostate& __err)
4392 if (__grouping.size() != 0)
4394 reverse(__g, __g_end);
4395 const char* __ig = __grouping.data();
4396 const char* __eg = __ig + __grouping.size();
4397 for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4399 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4401 if (static_cast<unsigned>(*__ig) != *__r)
4403 __err = ios_base::failbit;
4407 if (__eg - __ig > 1)
4410 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4412 if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
4413 __err = ios_base::failbit;
4419 __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4420 ios_base::fmtflags __flags)
4422 if (__flags & ios_base::showpos)
4424 if (__flags & ios_base::showbase)
4427 *__fmtp++ = *__len++;
4428 if ((__flags & ios_base::basefield) == ios_base::oct)
4430 else if ((__flags & ios_base::basefield) == ios_base::hex)
4432 if (__flags & ios_base::uppercase)
4444 __num_put_base::__format_float(char* __fmtp, const char* __len,
4445 ios_base::fmtflags __flags)
4447 bool specify_precision = true;
4448 if (__flags & ios_base::showpos)
4450 if (__flags & ios_base::showpoint)
4452 ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4453 bool uppercase = (__flags & ios_base::uppercase) != 0;
4454 if (floatfield == (ios_base::fixed | ios_base::scientific))
4455 specify_precision = false;
4462 *__fmtp++ = *__len++;
4463 if (floatfield == ios_base::fixed)
4470 else if (floatfield == ios_base::scientific)
4477 else if (floatfield == (ios_base::fixed | ios_base::scientific))
4491 return specify_precision;
4495 __num_put_base::__identify_padding(char* __nb, char* __ne,
4496 const ios_base& __iob)
4498 switch (__iob.flags() & ios_base::adjustfield)
4500 case ios_base::internal:
4501 if (__nb[0] == '-' || __nb[0] == '+')
4503 if (__ne - __nb >= 2 && __nb[0] == '0'
4504 && (__nb[1] == 'x' || __nb[1] == 'X'))
4507 case ios_base::left:
4509 case ios_base::right:
4522 static string weeks[14];
4523 weeks[0] = "Sunday";
4524 weeks[1] = "Monday";
4525 weeks[2] = "Tuesday";
4526 weeks[3] = "Wednesday";
4527 weeks[4] = "Thursday";
4528 weeks[5] = "Friday";
4529 weeks[6] = "Saturday";
4544 static wstring weeks[14];
4545 weeks[0] = L"Sunday";
4546 weeks[1] = L"Monday";
4547 weeks[2] = L"Tuesday";
4548 weeks[3] = L"Wednesday";
4549 weeks[4] = L"Thursday";
4550 weeks[5] = L"Friday";
4551 weeks[6] = L"Saturday";
4564 __time_get_c_storage<char>::__weeks() const
4566 static const string* weeks = init_weeks();
4572 __time_get_c_storage<wchar_t>::__weeks() const
4574 static const wstring* weeks = init_wweeks();
4582 static string months[24];
4583 months[0] = "January";
4584 months[1] = "February";
4585 months[2] = "March";
4586 months[3] = "April";
4590 months[7] = "August";
4591 months[8] = "September";
4592 months[9] = "October";
4593 months[10] = "November";
4594 months[11] = "December";
4614 static wstring months[24];
4615 months[0] = L"January";
4616 months[1] = L"February";
4617 months[2] = L"March";
4618 months[3] = L"April";
4620 months[5] = L"June";
4621 months[6] = L"July";
4622 months[7] = L"August";
4623 months[8] = L"September";
4624 months[9] = L"October";
4625 months[10] = L"November";
4626 months[11] = L"December";
4627 months[12] = L"Jan";
4628 months[13] = L"Feb";
4629 months[14] = L"Mar";
4630 months[15] = L"Apr";
4631 months[16] = L"May";
4632 months[17] = L"Jun";
4633 months[18] = L"Jul";
4634 months[19] = L"Aug";
4635 months[20] = L"Sep";
4636 months[21] = L"Oct";
4637 months[22] = L"Nov";
4638 months[23] = L"Dec";
4644 __time_get_c_storage<char>::__months() const
4646 static const string* months = init_months();
4652 __time_get_c_storage<wchar_t>::__months() const
4654 static const wstring* months = init_wmonths();
4662 static string am_pm[24];
4672 static wstring am_pm[24];
4680 __time_get_c_storage<char>::__am_pm() const
4682 static const string* am_pm = init_am_pm();
4688 __time_get_c_storage<wchar_t>::__am_pm() const
4690 static const wstring* am_pm = init_wam_pm();
4696 __time_get_c_storage<char>::__x() const
4698 static string s("%m/%d/%y");
4704 __time_get_c_storage<wchar_t>::__x() const
4706 static wstring s(L"%m/%d/%y");
4712 __time_get_c_storage<char>::__X() const
4714 static string s("%H:%M:%S");
4720 __time_get_c_storage<wchar_t>::__X() const
4722 static wstring s(L"%H:%M:%S");
4728 __time_get_c_storage<char>::__c() const
4730 static string s("%a %b %d %H:%M:%S %Y");
4736 __time_get_c_storage<wchar_t>::__c() const
4738 static wstring s(L"%a %b %d %H:%M:%S %Y");
4744 __time_get_c_storage<char>::__r() const
4746 static string s("%I:%M:%S %p");
4752 __time_get_c_storage<wchar_t>::__r() const
4754 static wstring s(L"%I:%M:%S %p");
4760 __time_get::__time_get(const char* nm)
4761 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
4764 __throw_runtime_error("time_get_byname"
4765 " failed to construct for " + string(nm));
4768 __time_get::__time_get(const string& nm)
4769 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
4772 __throw_runtime_error("time_get_byname"
4773 " failed to construct for " + nm);
4776 __time_get::~__time_get()
4780 #if defined(__clang__)
4781 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
4783 #if defined(__GNUG__)
4784 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
4789 __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
4805 size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);
4811 if (ct.is(ctype_base::space, *bb))
4813 result.push_back(' ');
4814 for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
4819 ios_base::iostate err = ios_base::goodbit;
4820 ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
4825 result.push_back('%');
4827 result.push_back('A');
4829 result.push_back('a');
4834 i = __scan_keyword(w, be, this->__months_, this->__months_+24,
4839 result.push_back('%');
4841 result.push_back('B');
4843 result.push_back('b');
4844 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4845 result.back() = 'm';
4849 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4852 i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
4853 ct, err, false) - this->__am_pm_;
4856 result.push_back('%');
4857 result.push_back('p');
4863 if (ct.is(ctype_base::digit, *bb))
4865 switch(__get_up_to_n_digits(bb, be, err, ct, 4))
4868 result.push_back('%');
4869 result.push_back('w');
4872 result.push_back('%');
4873 result.push_back('u');
4876 result.push_back('%');
4877 result.push_back('I');
4880 result.push_back('%');
4881 result.push_back('m');
4884 result.push_back('%');
4885 result.push_back('H');
4888 result.push_back('%');
4889 result.push_back('d');
4892 result.push_back('%');
4893 result.push_back('M');
4896 result.push_back('%');
4897 result.push_back('S');
4900 result.push_back('%');
4901 result.push_back('y');
4904 result.push_back('%');
4905 result.push_back('j');
4908 result.push_back('%');
4909 result.push_back('Y');
4912 for (; w != bb; ++w)
4913 result.push_back(*w);
4920 result.push_back('%');
4921 result.push_back('%');
4925 result.push_back(*bb);
4931 #if defined(__clang__)
4932 #pragma clang diagnostic ignored "-Wmissing-braces"
4937 __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
4953 strftime_l(buf, countof(buf), f, &t, __loc_);
4955 wchar_t* wbb = wbuf;
4957 const char* bb = buf;
4958 size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
4959 if (j == size_t(-1))
4960 __throw_runtime_error("locale not supported");
4961 wchar_t* wbe = wbb + j;
4965 if (ct.is(ctype_base::space, *wbb))
4967 result.push_back(L' ');
4968 for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
4973 ios_base::iostate err = ios_base::goodbit;
4974 ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
4979 result.push_back(L'%');
4981 result.push_back(L'A');
4983 result.push_back(L'a');
4988 i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
4993 result.push_back(L'%');
4995 result.push_back(L'B');
4997 result.push_back(L'b');
4998 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4999 result.back() = L'm';
5003 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
5006 i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
5007 ct, err, false) - this->__am_pm_;
5010 result.push_back(L'%');
5011 result.push_back(L'p');
5017 if (ct.is(ctype_base::digit, *wbb))
5019 switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
5022 result.push_back(L'%');
5023 result.push_back(L'w');
5026 result.push_back(L'%');
5027 result.push_back(L'u');
5030 result.push_back(L'%');
5031 result.push_back(L'I');
5034 result.push_back(L'%');
5035 result.push_back(L'm');
5038 result.push_back(L'%');
5039 result.push_back(L'H');
5042 result.push_back(L'%');
5043 result.push_back(L'd');
5046 result.push_back(L'%');
5047 result.push_back(L'M');
5050 result.push_back(L'%');
5051 result.push_back(L'S');
5054 result.push_back(L'%');
5055 result.push_back(L'y');
5058 result.push_back(L'%');
5059 result.push_back(L'j');
5062 result.push_back(L'%');
5063 result.push_back(L'Y');
5066 for (; w != wbb; ++w)
5067 result.push_back(*w);
5072 if (ct.narrow(*wbb, 0) == '%')
5074 result.push_back(L'%');
5075 result.push_back(L'%');
5079 result.push_back(*wbb);
5087 __time_get_storage<char>::init(const ctype<char>& ct)
5092 for (int i = 0; i < 7; ++i)
5095 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5097 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5098 __weeks_[i+7] = buf;
5101 for (int i = 0; i < 12; ++i)
5104 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5106 strftime_l(buf, countof(buf), "%b", &t, __loc_);
5107 __months_[i+12] = buf;
5111 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5114 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5116 __c_ = __analyze('c', ct);
5117 __r_ = __analyze('r', ct);
5118 __x_ = __analyze('x', ct);
5119 __X_ = __analyze('X', ct);
5124 __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
5132 for (int i = 0; i < 7; ++i)
5135 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5137 const char* bb = buf;
5138 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5139 if (j == size_t(-1))
5140 __throw_runtime_error("locale not supported");
5142 __weeks_[i].assign(wbuf, wbe);
5143 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5146 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5147 if (j == size_t(-1))
5148 __throw_runtime_error("locale not supported");
5150 __weeks_[i+7].assign(wbuf, wbe);
5153 for (int i = 0; i < 12; ++i)
5156 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5158 const char* bb = buf;
5159 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5160 if (j == size_t(-1))
5161 __throw_runtime_error("locale not supported");
5163 __months_[i].assign(wbuf, wbe);
5164 strftime_l(buf, countof(buf), "%b", &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 __months_[i+12].assign(wbuf, wbe);
5175 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5177 const char* bb = buf;
5178 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5179 if (j == size_t(-1))
5180 __throw_runtime_error("locale not supported");
5182 __am_pm_[0].assign(wbuf, wbe);
5184 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5187 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5188 if (j == size_t(-1))
5189 __throw_runtime_error("locale not supported");
5191 __am_pm_[1].assign(wbuf, wbe);
5192 __c_ = __analyze('c', ct);
5193 __r_ = __analyze('r', ct);
5194 __x_ = __analyze('x', ct);
5195 __X_ = __analyze('X', ct);
5198 template <class CharT>
5199 struct _LIBCPP_HIDDEN __time_get_temp
5200 : public ctype_byname<CharT>
5202 explicit __time_get_temp(const char* nm)
5203 : ctype_byname<CharT>(nm, 1) {}
5204 explicit __time_get_temp(const string& nm)
5205 : ctype_byname<CharT>(nm, 1) {}
5209 __time_get_storage<char>::__time_get_storage(const char* __nm)
5212 const __time_get_temp<char> ct(__nm);
5217 __time_get_storage<char>::__time_get_storage(const string& __nm)
5220 const __time_get_temp<char> ct(__nm);
5225 __time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5228 const __time_get_temp<wchar_t> ct(__nm);
5233 __time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5236 const __time_get_temp<wchar_t> ct(__nm);
5241 time_base::dateorder
5242 __time_get_storage<char>::__do_date_order() const
5245 for (i = 0; i < __x_.size(); ++i)
5253 for (++i; i < __x_.size(); ++i)
5256 if (i == __x_.size())
5262 for (++i; i < __x_.size(); ++i)
5265 if (i == __x_.size())
5269 return time_base::ymd;
5272 for (++i; i < __x_.size(); ++i)
5275 if (i == __x_.size())
5279 return time_base::ydm;
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::mdy;
5304 for (++i; i < __x_.size(); ++i)
5307 if (i == __x_.size())
5312 for (++i; i < __x_.size(); ++i)
5315 if (i == __x_.size())
5318 if (__x_[i] == 'y' || __x_[i] == 'Y')
5319 return time_base::dmy;
5324 return time_base::no_order;
5328 time_base::dateorder
5329 __time_get_storage<wchar_t>::__do_date_order() const
5332 for (i = 0; i < __x_.size(); ++i)
5333 if (__x_[i] == L'%')
5340 for (++i; i < __x_.size(); ++i)
5341 if (__x_[i] == L'%')
5343 if (i == __x_.size())
5349 for (++i; i < __x_.size(); ++i)
5350 if (__x_[i] == L'%')
5352 if (i == __x_.size())
5355 if (__x_[i] == L'd')
5356 return time_base::ymd;
5359 for (++i; i < __x_.size(); ++i)
5360 if (__x_[i] == L'%')
5362 if (i == __x_.size())
5365 if (__x_[i] == L'm')
5366 return time_base::ydm;
5371 for (++i; i < __x_.size(); ++i)
5372 if (__x_[i] == L'%')
5374 if (i == __x_.size())
5377 if (__x_[i] == L'd')
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::mdy;
5391 for (++i; i < __x_.size(); ++i)
5392 if (__x_[i] == L'%')
5394 if (i == __x_.size())
5397 if (__x_[i] == L'm')
5399 for (++i; i < __x_.size(); ++i)
5400 if (__x_[i] == L'%')
5402 if (i == __x_.size())
5405 if (__x_[i] == L'y' || __x_[i] == L'Y')
5406 return time_base::dmy;
5411 return time_base::no_order;
5416 __time_put::__time_put(const char* nm)
5417 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5420 __throw_runtime_error("time_put_byname"
5421 " failed to construct for " + string(nm));
5424 __time_put::__time_put(const string& nm)
5425 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5428 __throw_runtime_error("time_put_byname"
5429 " failed to construct for " + nm);
5432 __time_put::~__time_put()
5434 if (__loc_ != _LIBCPP_GET_C_LOCALE)
5439 __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5440 char __fmt, char __mod) const
5442 char fmt[] = {'%', __fmt, __mod, 0};
5444 swap(fmt[1], fmt[2]);
5445 size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
5450 __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5451 char __fmt, char __mod) const
5454 char* __ne = __nar + 100;
5455 __do_put(__nar, __ne, __tm, __fmt, __mod);
5457 const char* __nb = __nar;
5458 size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
5459 if (j == size_t(-1))
5460 __throw_runtime_error("locale not supported");
5464 // moneypunct_byname
5466 template <class charT>
5469 __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
5470 bool intl, char cs_precedes, char sep_by_space, char sign_posn,
5473 const char sign = static_cast<char>(money_base::sign);
5474 const char space = static_cast<char>(money_base::space);
5475 const char none = static_cast<char>(money_base::none);
5476 const char symbol = static_cast<char>(money_base::symbol);
5477 const char value = static_cast<char>(money_base::value);
5478 const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
5480 // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5481 // function'. "Space between sign and symbol or value" means that
5482 // if the sign is adjacent to the symbol, there's a space between
5483 // them, and otherwise there's a space between the sign and value.
5485 // C11's localeconv specifies that the fourth character of an
5486 // international curr_symbol is used to separate the sign and
5487 // value when sep_by_space says to do so. C++ can't represent
5488 // that, so we just use a space. When sep_by_space says to
5489 // separate the symbol and value-or-sign with a space, we rearrange the
5490 // curr_symbol to put its spacing character on the correct side of
5493 // We also need to avoid adding an extra space between the sign
5494 // and value when the currency symbol is suppressed (by not
5495 // setting showbase). We match glibc's strfmon by interpreting
5496 // sep_by_space==1 as "omit the space when the currency symbol is
5499 // Users who want to get this right should use ICU instead.
5501 switch (cs_precedes)
5503 case 0: // value before curr_symbol
5504 if (symbol_contains_sep) {
5505 // Move the separator to before the symbol, to place it
5506 // between the value and symbol.
5507 rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,
5508 __curr_symbol_.end());
5512 case 0: // Parentheses surround the quantity and currency symbol.
5513 pat.field[0] = sign;
5514 pat.field[1] = value;
5515 pat.field[2] = none; // Any space appears in the symbol.
5516 pat.field[3] = symbol;
5517 switch (sep_by_space)
5519 case 0: // No space separates the currency symbol and value.
5520 // This case may have changed between C99 and C11;
5521 // assume the currency symbol matches the intention.
5522 case 2: // Space between sign and currency or value.
5523 // The "sign" is two parentheses, so no space here either.
5525 case 1: // Space between currency-and-sign or currency and value.
5526 if (!symbol_contains_sep) {
5527 // We insert the space into the symbol instead of
5528 // setting pat.field[2]=space so that when
5529 // showbase is not set, the space goes away too.
5530 __curr_symbol_.insert(0, 1, space_char);
5537 case 1: // The sign string precedes the quantity and currency symbol.
5538 pat.field[0] = sign;
5539 pat.field[3] = symbol;
5540 switch (sep_by_space)
5542 case 0: // No space separates the currency symbol and value.
5543 pat.field[1] = value;
5544 pat.field[2] = none;
5546 case 1: // Space between currency-and-sign or currency and value.
5547 pat.field[1] = value;
5548 pat.field[2] = none;
5549 if (!symbol_contains_sep) {
5550 // We insert the space into the symbol instead of
5551 // setting pat.field[2]=space so that when
5552 // showbase is not set, the space goes away too.
5553 __curr_symbol_.insert(0, 1, space_char);
5556 case 2: // Space between sign and currency or value.
5557 pat.field[1] = space;
5558 pat.field[2] = value;
5559 if (symbol_contains_sep) {
5560 // Remove the separator from the symbol, since it
5561 // has already appeared after the sign.
5562 __curr_symbol_.erase(__curr_symbol_.begin());
5569 case 2: // The sign string succeeds the quantity and currency symbol.
5570 pat.field[0] = value;
5571 pat.field[3] = sign;
5572 switch (sep_by_space)
5574 case 0: // No space separates the currency symbol and value.
5575 pat.field[1] = none;
5576 pat.field[2] = symbol;
5578 case 1: // Space between currency-and-sign or currency and value.
5579 if (!symbol_contains_sep) {
5580 // We insert the space into the symbol instead of
5581 // setting pat.field[1]=space so that when
5582 // showbase is not set, the space goes away too.
5583 __curr_symbol_.insert(0, 1, space_char);
5585 pat.field[1] = none;
5586 pat.field[2] = symbol;
5588 case 2: // Space between sign and currency or value.
5589 pat.field[1] = symbol;
5590 pat.field[2] = space;
5591 if (symbol_contains_sep) {
5592 // Remove the separator from the symbol, since it
5593 // should not be removed if showbase is absent.
5594 __curr_symbol_.erase(__curr_symbol_.begin());
5601 case 3: // The sign string immediately precedes the currency symbol.
5602 pat.field[0] = value;
5603 pat.field[3] = symbol;
5604 switch (sep_by_space)
5606 case 0: // No space separates the currency symbol and value.
5607 pat.field[1] = none;
5608 pat.field[2] = sign;
5610 case 1: // Space between currency-and-sign or currency and value.
5611 pat.field[1] = space;
5612 pat.field[2] = sign;
5613 if (symbol_contains_sep) {
5614 // Remove the separator from the symbol, since it
5615 // has already appeared before the sign.
5616 __curr_symbol_.erase(__curr_symbol_.begin());
5619 case 2: // Space between sign and currency or value.
5620 pat.field[1] = sign;
5621 pat.field[2] = none;
5622 if (!symbol_contains_sep) {
5623 // We insert the space into the symbol instead of
5624 // setting pat.field[2]=space so that when
5625 // showbase is not set, the space goes away too.
5626 __curr_symbol_.insert(0, 1, space_char);
5633 case 4: // The sign string immediately succeeds the currency symbol.
5634 pat.field[0] = value;
5635 pat.field[3] = sign;
5636 switch (sep_by_space)
5638 case 0: // No space separates the currency symbol and value.
5639 pat.field[1] = none;
5640 pat.field[2] = symbol;
5642 case 1: // Space between currency-and-sign or currency and value.
5643 pat.field[1] = none;
5644 pat.field[2] = symbol;
5645 if (!symbol_contains_sep) {
5646 // We insert the space into the symbol instead of
5647 // setting pat.field[1]=space so that when
5648 // showbase is not set, the space goes away too.
5649 __curr_symbol_.insert(0, 1, space_char);
5652 case 2: // Space between sign and currency or value.
5653 pat.field[1] = symbol;
5654 pat.field[2] = space;
5655 if (symbol_contains_sep) {
5656 // Remove the separator from the symbol, since it
5657 // should not disappear when showbase is absent.
5658 __curr_symbol_.erase(__curr_symbol_.begin());
5669 case 1: // curr_symbol before value
5672 case 0: // Parentheses surround the quantity and currency symbol.
5673 pat.field[0] = sign;
5674 pat.field[1] = symbol;
5675 pat.field[2] = none; // Any space appears in the symbol.
5676 pat.field[3] = value;
5677 switch (sep_by_space)
5679 case 0: // No space separates the currency symbol and value.
5680 // This case may have changed between C99 and C11;
5681 // assume the currency symbol matches the intention.
5682 case 2: // Space between sign and currency or value.
5683 // The "sign" is two parentheses, so no space here either.
5685 case 1: // Space between currency-and-sign or currency and value.
5686 if (!symbol_contains_sep) {
5687 // We insert the space into the symbol instead of
5688 // setting pat.field[2]=space so that when
5689 // showbase is not set, the space goes away too.
5690 __curr_symbol_.insert(0, 1, space_char);
5697 case 1: // The sign string precedes the quantity and currency symbol.
5698 pat.field[0] = sign;
5699 pat.field[3] = value;
5700 switch (sep_by_space)
5702 case 0: // No space separates the currency symbol and value.
5703 pat.field[1] = symbol;
5704 pat.field[2] = none;
5706 case 1: // Space between currency-and-sign or currency and value.
5707 pat.field[1] = symbol;
5708 pat.field[2] = none;
5709 if (!symbol_contains_sep) {
5710 // We insert the space into the symbol instead of
5711 // setting pat.field[2]=space so that when
5712 // showbase is not set, the space goes away too.
5713 __curr_symbol_.push_back(space_char);
5716 case 2: // Space between sign and currency or value.
5717 pat.field[1] = space;
5718 pat.field[2] = symbol;
5719 if (symbol_contains_sep) {
5720 // Remove the separator from the symbol, since it
5721 // has already appeared after the sign.
5722 __curr_symbol_.pop_back();
5729 case 2: // The sign string succeeds the quantity and currency symbol.
5730 pat.field[0] = symbol;
5731 pat.field[3] = sign;
5732 switch (sep_by_space)
5734 case 0: // No space separates the currency symbol and value.
5735 pat.field[1] = none;
5736 pat.field[2] = value;
5738 case 1: // Space between currency-and-sign or currency and value.
5739 pat.field[1] = none;
5740 pat.field[2] = value;
5741 if (!symbol_contains_sep) {
5742 // We insert the space into the symbol instead of
5743 // setting pat.field[1]=space so that when
5744 // showbase is not set, the space goes away too.
5745 __curr_symbol_.push_back(space_char);
5748 case 2: // Space between sign and currency or value.
5749 pat.field[1] = value;
5750 pat.field[2] = space;
5751 if (symbol_contains_sep) {
5752 // Remove the separator from the symbol, since it
5753 // will appear before the sign.
5754 __curr_symbol_.pop_back();
5761 case 3: // The sign string immediately precedes the currency symbol.
5762 pat.field[0] = sign;
5763 pat.field[3] = value;
5764 switch (sep_by_space)
5766 case 0: // No space separates the currency symbol and value.
5767 pat.field[1] = symbol;
5768 pat.field[2] = none;
5770 case 1: // Space between currency-and-sign or currency and value.
5771 pat.field[1] = symbol;
5772 pat.field[2] = none;
5773 if (!symbol_contains_sep) {
5774 // We insert the space into the symbol instead of
5775 // setting pat.field[2]=space so that when
5776 // showbase is not set, the space goes away too.
5777 __curr_symbol_.push_back(space_char);
5780 case 2: // Space between sign and currency or value.
5781 pat.field[1] = space;
5782 pat.field[2] = symbol;
5783 if (symbol_contains_sep) {
5784 // Remove the separator from the symbol, since it
5785 // has already appeared after the sign.
5786 __curr_symbol_.pop_back();
5793 case 4: // The sign string immediately succeeds the currency symbol.
5794 pat.field[0] = symbol;
5795 pat.field[3] = value;
5796 switch (sep_by_space)
5798 case 0: // No space separates the currency symbol and value.
5799 pat.field[1] = sign;
5800 pat.field[2] = none;
5802 case 1: // Space between currency-and-sign or currency and value.
5803 pat.field[1] = sign;
5804 pat.field[2] = space;
5805 if (symbol_contains_sep) {
5806 // Remove the separator from the symbol, since it
5807 // should not disappear when showbase is absent.
5808 __curr_symbol_.pop_back();
5811 case 2: // Space between sign and currency or value.
5812 pat.field[1] = none;
5813 pat.field[2] = sign;
5814 if (!symbol_contains_sep) {
5815 // We insert the space into the symbol instead of
5816 // setting pat.field[1]=space so that when
5817 // showbase is not set, the space goes away too.
5818 __curr_symbol_.push_back(space_char);
5832 pat.field[0] = symbol;
5833 pat.field[1] = sign;
5834 pat.field[2] = none;
5835 pat.field[3] = value;
5840 moneypunct_byname<char, false>::init(const char* nm)
5842 typedef moneypunct<char, false> base;
5843 __libcpp_unique_locale loc(nm);
5845 __throw_runtime_error("moneypunct_byname"
5846 " failed to construct for " + string(nm));
5848 lconv* lc = __libcpp_localeconv_l(loc.get());
5849 if (!checked_string_to_char_convert(__decimal_point_,
5850 lc->mon_decimal_point,
5852 __decimal_point_ = base::do_decimal_point();
5853 if (!checked_string_to_char_convert(__thousands_sep_,
5854 lc->mon_thousands_sep,
5856 __thousands_sep_ = base::do_thousands_sep();
5858 __grouping_ = lc->mon_grouping;
5859 __curr_symbol_ = lc->currency_symbol;
5860 if (lc->frac_digits != CHAR_MAX)
5861 __frac_digits_ = lc->frac_digits;
5863 __frac_digits_ = base::do_frac_digits();
5864 if (lc->p_sign_posn == 0)
5865 __positive_sign_ = "()";
5867 __positive_sign_ = lc->positive_sign;
5868 if (lc->n_sign_posn == 0)
5869 __negative_sign_ = "()";
5871 __negative_sign_ = lc->negative_sign;
5872 // Assume the positive and negative formats will want spaces in
5873 // the same places in curr_symbol since there's no way to
5874 // represent anything else.
5875 string_type __dummy_curr_symbol = __curr_symbol_;
5876 __init_pat(__pos_format_, __dummy_curr_symbol, false,
5877 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5878 __init_pat(__neg_format_, __curr_symbol_, false,
5879 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5884 moneypunct_byname<char, true>::init(const char* nm)
5886 typedef moneypunct<char, true> base;
5887 __libcpp_unique_locale loc(nm);
5889 __throw_runtime_error("moneypunct_byname"
5890 " failed to construct for " + string(nm));
5892 lconv* lc = __libcpp_localeconv_l(loc.get());
5893 if (!checked_string_to_char_convert(__decimal_point_,
5894 lc->mon_decimal_point,
5896 __decimal_point_ = base::do_decimal_point();
5897 if (!checked_string_to_char_convert(__thousands_sep_,
5898 lc->mon_thousands_sep,
5900 __thousands_sep_ = base::do_thousands_sep();
5901 __grouping_ = lc->mon_grouping;
5902 __curr_symbol_ = lc->int_curr_symbol;
5903 if (lc->int_frac_digits != CHAR_MAX)
5904 __frac_digits_ = lc->int_frac_digits;
5906 __frac_digits_ = base::do_frac_digits();
5907 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5908 if (lc->p_sign_posn == 0)
5909 #else // _LIBCPP_MSVCRT
5910 if (lc->int_p_sign_posn == 0)
5911 #endif // !_LIBCPP_MSVCRT
5912 __positive_sign_ = "()";
5914 __positive_sign_ = lc->positive_sign;
5915 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5916 if(lc->n_sign_posn == 0)
5917 #else // _LIBCPP_MSVCRT
5918 if (lc->int_n_sign_posn == 0)
5919 #endif // !_LIBCPP_MSVCRT
5920 __negative_sign_ = "()";
5922 __negative_sign_ = lc->negative_sign;
5923 // Assume the positive and negative formats will want spaces in
5924 // the same places in curr_symbol since there's no way to
5925 // represent anything else.
5926 string_type __dummy_curr_symbol = __curr_symbol_;
5927 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5928 __init_pat(__pos_format_, __dummy_curr_symbol, true,
5929 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5930 __init_pat(__neg_format_, __curr_symbol_, true,
5931 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5932 #else // _LIBCPP_MSVCRT
5933 __init_pat(__pos_format_, __dummy_curr_symbol, true,
5934 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
5935 lc->int_p_sign_posn, ' ');
5936 __init_pat(__neg_format_, __curr_symbol_, true,
5937 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
5938 lc->int_n_sign_posn, ' ');
5939 #endif // !_LIBCPP_MSVCRT
5944 moneypunct_byname<wchar_t, false>::init(const char* nm)
5946 typedef moneypunct<wchar_t, false> base;
5947 __libcpp_unique_locale loc(nm);
5949 __throw_runtime_error("moneypunct_byname"
5950 " failed to construct for " + string(nm));
5951 lconv* lc = __libcpp_localeconv_l(loc.get());
5952 if (!checked_string_to_wchar_convert(__decimal_point_,
5953 lc->mon_decimal_point,
5955 __decimal_point_ = base::do_decimal_point();
5956 if (!checked_string_to_wchar_convert(__thousands_sep_,
5957 lc->mon_thousands_sep,
5959 __thousands_sep_ = base::do_thousands_sep();
5960 __grouping_ = lc->mon_grouping;
5963 const char* bb = lc->currency_symbol;
5964 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5965 if (j == size_t(-1))
5966 __throw_runtime_error("locale not supported");
5967 wchar_t* wbe = wbuf + j;
5968 __curr_symbol_.assign(wbuf, wbe);
5969 if (lc->frac_digits != CHAR_MAX)
5970 __frac_digits_ = lc->frac_digits;
5972 __frac_digits_ = base::do_frac_digits();
5973 if (lc->p_sign_posn == 0)
5974 __positive_sign_ = L"()";
5978 bb = lc->positive_sign;
5979 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5980 if (j == size_t(-1))
5981 __throw_runtime_error("locale not supported");
5983 __positive_sign_.assign(wbuf, wbe);
5985 if (lc->n_sign_posn == 0)
5986 __negative_sign_ = L"()";
5990 bb = lc->negative_sign;
5991 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5992 if (j == size_t(-1))
5993 __throw_runtime_error("locale not supported");
5995 __negative_sign_.assign(wbuf, wbe);
5997 // Assume the positive and negative formats will want spaces in
5998 // the same places in curr_symbol since there's no way to
5999 // represent anything else.
6000 string_type __dummy_curr_symbol = __curr_symbol_;
6001 __init_pat(__pos_format_, __dummy_curr_symbol, false,
6002 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6003 __init_pat(__neg_format_, __curr_symbol_, false,
6004 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6009 moneypunct_byname<wchar_t, true>::init(const char* nm)
6011 typedef moneypunct<wchar_t, true> base;
6012 __libcpp_unique_locale loc(nm);
6014 __throw_runtime_error("moneypunct_byname"
6015 " failed to construct for " + string(nm));
6017 lconv* lc = __libcpp_localeconv_l(loc.get());
6018 if (!checked_string_to_wchar_convert(__decimal_point_,
6019 lc->mon_decimal_point,
6021 __decimal_point_ = base::do_decimal_point();
6022 if (!checked_string_to_wchar_convert(__thousands_sep_,
6023 lc->mon_thousands_sep,
6025 __thousands_sep_ = base::do_thousands_sep();
6026 __grouping_ = lc->mon_grouping;
6029 const char* bb = lc->int_curr_symbol;
6030 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6031 if (j == size_t(-1))
6032 __throw_runtime_error("locale not supported");
6033 wchar_t* wbe = wbuf + j;
6034 __curr_symbol_.assign(wbuf, wbe);
6035 if (lc->int_frac_digits != CHAR_MAX)
6036 __frac_digits_ = lc->int_frac_digits;
6038 __frac_digits_ = base::do_frac_digits();
6039 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6040 if (lc->p_sign_posn == 0)
6041 #else // _LIBCPP_MSVCRT
6042 if (lc->int_p_sign_posn == 0)
6043 #endif // !_LIBCPP_MSVCRT
6044 __positive_sign_ = L"()";
6048 bb = lc->positive_sign;
6049 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6050 if (j == size_t(-1))
6051 __throw_runtime_error("locale not supported");
6053 __positive_sign_.assign(wbuf, wbe);
6055 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6056 if (lc->n_sign_posn == 0)
6057 #else // _LIBCPP_MSVCRT
6058 if (lc->int_n_sign_posn == 0)
6059 #endif // !_LIBCPP_MSVCRT
6060 __negative_sign_ = L"()";
6064 bb = lc->negative_sign;
6065 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6066 if (j == size_t(-1))
6067 __throw_runtime_error("locale not supported");
6069 __negative_sign_.assign(wbuf, wbe);
6071 // Assume the positive and negative formats will want spaces in
6072 // the same places in curr_symbol since there's no way to
6073 // represent anything else.
6074 string_type __dummy_curr_symbol = __curr_symbol_;
6075 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6076 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6077 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6078 __init_pat(__neg_format_, __curr_symbol_, true,
6079 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6080 #else // _LIBCPP_MSVCRT
6081 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6082 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6083 lc->int_p_sign_posn, L' ');
6084 __init_pat(__neg_format_, __curr_symbol_, true,
6085 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6086 lc->int_n_sign_posn, L' ');
6087 #endif // !_LIBCPP_MSVCRT
6090 void __do_nothing(void*) {}
6092 void __throw_runtime_error(const char* msg)
6094 #ifndef _LIBCPP_NO_EXCEPTIONS
6095 throw runtime_error(msg);
6102 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;
6103 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;
6105 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<char>;
6106 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<wchar_t>;
6108 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<char>;
6109 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<wchar_t>;
6111 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<char>;
6112 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<wchar_t>;
6114 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<char>;
6115 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<wchar_t>;
6117 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<char>;
6118 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<wchar_t>;
6120 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<char>;
6121 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<wchar_t>;
6123 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<char>;
6124 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<wchar_t>;
6126 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<char>;
6127 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<wchar_t>;
6129 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, false>;
6130 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, true>;
6131 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, false>;
6132 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, true>;
6134 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, false>;
6135 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, true>;
6136 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, false>;
6137 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, true>;
6139 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<char>;
6140 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<wchar_t>;
6142 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<char>;
6143 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<wchar_t>;
6145 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<char>;
6146 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<wchar_t>;
6148 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<char>;
6149 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<wchar_t>;
6151 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<char>;
6152 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<wchar_t>;
6154 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<char>;
6155 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t>;
6157 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>;
6158 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;
6159 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
6160 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
6162 _LIBCPP_END_NAMESPACE_STD