1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include <__utility/unreachable.h>
10 #include <__verbose_abort>
19 #include <type_traits>
23 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
28 # include <sys/localedef.h> // for __lc_ctype_ptr
31 #if defined(_LIBCPP_MSVCRT)
32 # define _CTYPE_DISABLE_MACROS
35 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
36 # include "__support/win32/locale_win32.h"
37 #elif !defined(__BIONIC__) && !defined(__NuttX__)
38 # include <langinfo.h>
41 #include "include/atomic_support.h"
42 #include "include/sso_allocator.h"
44 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
45 // lots of noise in the build log, but no bugs that I know of.
46 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wsign-conversion")
49 #include <__undef_macros>
51 _LIBCPP_BEGIN_NAMESPACE_STD
53 struct __libcpp_unique_locale {
54 __libcpp_unique_locale(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {}
56 ~__libcpp_unique_locale() {
61 explicit operator bool() const { return __loc_; }
63 locale_t& get() { return __loc_; }
67 __libcpp_unique_locale(__libcpp_unique_locale const&);
68 __libcpp_unique_locale& operator=(__libcpp_unique_locale const&);
73 // In theory this could create a race condition. In practice
74 // the race condition is non-fatal since it will just create
75 // a little resource leak. Better approach would be appreciated.
76 static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
79 #endif // __cloc_defined
85 void operator()(locale::facet* p) {p->__release_shared();}
88 template <class T, class ...Args>
91 static typename aligned_storage<sizeof(T)>::type buf;
92 auto *obj = ::new (&buf) T(args...);
96 template <typename T, size_t N>
100 countof(const T (&)[N])
105 template <typename T>
109 countof(const T * const begin, const T * const end)
111 return static_cast<size_t>(end - begin);
114 _LIBCPP_NORETURN static void __throw_runtime_error(const string &msg)
116 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
117 throw runtime_error(msg);
119 _LIBCPP_VERBOSE_ABORT("runtime_error was thrown in -fno-exceptions mode with message \"%s\"", msg.c_str());
126 build_name(const string& other, const string& one, locale::category c) {
127 if (other == "*" || one == "*")
129 if (c == locale::none || other == one)
132 // FIXME: Handle the more complicated cases, such as when the locale has
133 // different names for different categories.
137 const locale::category locale::none;
138 const locale::category locale::collate;
139 const locale::category locale::ctype;
140 const locale::category locale::monetary;
141 const locale::category locale::numeric;
142 const locale::category locale::time;
143 const locale::category locale::messages;
144 const locale::category locale::all;
146 class _LIBCPP_HIDDEN locale::__imp
150 vector<facet*, __sso_allocator<facet*, N> > facets_;
153 explicit __imp(size_t refs = 0);
154 explicit __imp(const string& name, size_t refs = 0);
156 __imp(const __imp&, const string&, locale::category c);
157 __imp(const __imp& other, const __imp& one, locale::category c);
158 __imp(const __imp&, facet* f, long id);
161 const string& name() const {return name_;}
162 bool has_facet(long id) const
163 {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
164 const locale::facet* use_facet(long id) const;
166 static const locale& make_classic();
167 static locale& make_global();
169 void install(facet* f, long id);
170 template <class F> void install(F* f) {install(f, f->id.__get());}
171 template <class F> void install_from(const __imp& other);
174 locale::__imp::__imp(size_t refs)
180 install(&make<_VSTD::collate<char> >(1u));
181 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
182 install(&make<_VSTD::collate<wchar_t> >(1u));
184 install(&make<_VSTD::ctype<char> >(nullptr, false, 1u));
185 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
186 install(&make<_VSTD::ctype<wchar_t> >(1u));
188 install(&make<codecvt<char, char, mbstate_t> >(1u));
189 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
190 install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
192 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
193 install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
194 install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
195 _LIBCPP_SUPPRESS_DEPRECATED_POP
196 #ifndef _LIBCPP_HAS_NO_CHAR8_T
197 install(&make<codecvt<char16_t, char8_t, mbstate_t> >(1u));
198 install(&make<codecvt<char32_t, char8_t, mbstate_t> >(1u));
200 install(&make<numpunct<char> >(1u));
201 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
202 install(&make<numpunct<wchar_t> >(1u));
204 install(&make<num_get<char> >(1u));
205 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
206 install(&make<num_get<wchar_t> >(1u));
208 install(&make<num_put<char> >(1u));
209 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
210 install(&make<num_put<wchar_t> >(1u));
212 install(&make<moneypunct<char, false> >(1u));
213 install(&make<moneypunct<char, true> >(1u));
214 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
215 install(&make<moneypunct<wchar_t, false> >(1u));
216 install(&make<moneypunct<wchar_t, true> >(1u));
218 install(&make<money_get<char> >(1u));
219 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
220 install(&make<money_get<wchar_t> >(1u));
222 install(&make<money_put<char> >(1u));
223 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
224 install(&make<money_put<wchar_t> >(1u));
226 install(&make<time_get<char> >(1u));
227 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
228 install(&make<time_get<wchar_t> >(1u));
230 install(&make<time_put<char> >(1u));
231 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
232 install(&make<time_put<wchar_t> >(1u));
234 install(&make<_VSTD::messages<char> >(1u));
235 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
236 install(&make<_VSTD::messages<wchar_t> >(1u));
240 locale::__imp::__imp(const string& name, size_t refs)
245 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
248 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
249 facets_ = locale::classic().__locale_->facets_;
250 for (unsigned i = 0; i < facets_.size(); ++i)
252 facets_[i]->__add_shared();
253 install(new collate_byname<char>(name_));
254 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
255 install(new collate_byname<wchar_t>(name_));
257 install(new ctype_byname<char>(name_));
258 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
259 install(new ctype_byname<wchar_t>(name_));
261 install(new codecvt_byname<char, char, mbstate_t>(name_));
262 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
263 install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
265 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
266 install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
267 install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
268 _LIBCPP_SUPPRESS_DEPRECATED_POP
269 #ifndef _LIBCPP_HAS_NO_CHAR8_T
270 install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name_));
271 install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name_));
273 install(new numpunct_byname<char>(name_));
274 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
275 install(new numpunct_byname<wchar_t>(name_));
277 install(new moneypunct_byname<char, false>(name_));
278 install(new moneypunct_byname<char, true>(name_));
279 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
280 install(new moneypunct_byname<wchar_t, false>(name_));
281 install(new moneypunct_byname<wchar_t, true>(name_));
283 install(new time_get_byname<char>(name_));
284 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
285 install(new time_get_byname<wchar_t>(name_));
287 install(new time_put_byname<char>(name_));
288 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
289 install(new time_put_byname<wchar_t>(name_));
291 install(new messages_byname<char>(name_));
292 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
293 install(new messages_byname<wchar_t>(name_));
295 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
299 for (unsigned i = 0; i < facets_.size(); ++i)
301 facets_[i]->__release_shared();
304 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
307 locale::__imp::__imp(const __imp& other)
308 : facets_(max<size_t>(N, other.facets_.size())),
311 facets_ = other.facets_;
312 for (unsigned i = 0; i < facets_.size(); ++i)
314 facets_[i]->__add_shared();
317 locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
318 : facets_(N), name_(build_name(other.name_, name, c))
320 facets_ = other.facets_;
321 for (unsigned i = 0; i < facets_.size(); ++i)
323 facets_[i]->__add_shared();
324 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
327 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
328 if (c & locale::collate)
330 install(new collate_byname<char>(name));
331 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
332 install(new collate_byname<wchar_t>(name));
335 if (c & locale::ctype)
337 install(new ctype_byname<char>(name));
338 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
339 install(new ctype_byname<wchar_t>(name));
341 install(new codecvt_byname<char, char, mbstate_t>(name));
342 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
343 install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
345 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
346 install(new codecvt_byname<char16_t, char, mbstate_t>(name));
347 install(new codecvt_byname<char32_t, char, mbstate_t>(name));
348 _LIBCPP_SUPPRESS_DEPRECATED_POP
349 #ifndef _LIBCPP_HAS_NO_CHAR8_T
350 install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name));
351 install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name));
354 if (c & locale::monetary)
356 install(new moneypunct_byname<char, false>(name));
357 install(new moneypunct_byname<char, true>(name));
358 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
359 install(new moneypunct_byname<wchar_t, false>(name));
360 install(new moneypunct_byname<wchar_t, true>(name));
363 if (c & locale::numeric)
365 install(new numpunct_byname<char>(name));
366 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
367 install(new numpunct_byname<wchar_t>(name));
370 if (c & locale::time)
372 install(new time_get_byname<char>(name));
373 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
374 install(new time_get_byname<wchar_t>(name));
376 install(new time_put_byname<char>(name));
377 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
378 install(new time_put_byname<wchar_t>(name));
381 if (c & locale::messages)
383 install(new messages_byname<char>(name));
384 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
385 install(new messages_byname<wchar_t>(name));
388 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
392 for (unsigned i = 0; i < facets_.size(); ++i)
394 facets_[i]->__release_shared();
397 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
403 locale::__imp::install_from(const locale::__imp& one)
405 long id = F::id.__get();
406 install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
409 locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
410 : facets_(N), name_(build_name(other.name_, one.name_, c))
412 facets_ = other.facets_;
413 for (unsigned i = 0; i < facets_.size(); ++i)
415 facets_[i]->__add_shared();
416 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
419 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
420 if (c & locale::collate)
422 install_from<_VSTD::collate<char> >(one);
423 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
424 install_from<_VSTD::collate<wchar_t> >(one);
427 if (c & locale::ctype)
429 install_from<_VSTD::ctype<char> >(one);
430 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
431 install_from<_VSTD::ctype<wchar_t> >(one);
433 install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
434 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
435 install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
436 install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
437 _LIBCPP_SUPPRESS_DEPRECATED_POP
438 #ifndef _LIBCPP_HAS_NO_CHAR8_T
439 install_from<_VSTD::codecvt<char16_t, char8_t, mbstate_t> >(one);
440 install_from<_VSTD::codecvt<char32_t, char8_t, mbstate_t> >(one);
442 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
443 install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
446 if (c & locale::monetary)
448 install_from<moneypunct<char, false> >(one);
449 install_from<moneypunct<char, true> >(one);
450 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
451 install_from<moneypunct<wchar_t, false> >(one);
452 install_from<moneypunct<wchar_t, true> >(one);
454 install_from<money_get<char> >(one);
455 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
456 install_from<money_get<wchar_t> >(one);
458 install_from<money_put<char> >(one);
459 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
460 install_from<money_put<wchar_t> >(one);
463 if (c & locale::numeric)
465 install_from<numpunct<char> >(one);
466 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
467 install_from<numpunct<wchar_t> >(one);
469 install_from<num_get<char> >(one);
470 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
471 install_from<num_get<wchar_t> >(one);
473 install_from<num_put<char> >(one);
474 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
475 install_from<num_put<wchar_t> >(one);
478 if (c & locale::time)
480 install_from<time_get<char> >(one);
481 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
482 install_from<time_get<wchar_t> >(one);
484 install_from<time_put<char> >(one);
485 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
486 install_from<time_put<wchar_t> >(one);
489 if (c & locale::messages)
491 install_from<_VSTD::messages<char> >(one);
492 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
493 install_from<_VSTD::messages<wchar_t> >(one);
496 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
500 for (unsigned i = 0; i < facets_.size(); ++i)
502 facets_[i]->__release_shared();
505 #endif // _LIBCPP_HAS_NO_EXCEPTIONS
508 locale::__imp::__imp(const __imp& other, facet* f, long id)
509 : facets_(max<size_t>(N, other.facets_.size()+1)),
513 unique_ptr<facet, release> hold(f);
514 facets_ = other.facets_;
515 for (unsigned i = 0; i < other.facets_.size(); ++i)
517 facets_[i]->__add_shared();
518 install(hold.get(), id);
521 locale::__imp::~__imp()
523 for (unsigned i = 0; i < facets_.size(); ++i)
525 facets_[i]->__release_shared();
529 locale::__imp::install(facet* f, long id)
532 unique_ptr<facet, release> hold(f);
533 if (static_cast<size_t>(id) >= facets_.size())
534 facets_.resize(static_cast<size_t>(id+1));
535 if (facets_[static_cast<size_t>(id)])
536 facets_[static_cast<size_t>(id)]->__release_shared();
537 facets_[static_cast<size_t>(id)] = hold.release();
541 locale::__imp::use_facet(long id) const
545 return facets_[static_cast<size_t>(id)];
551 locale::__imp::make_classic()
553 // only one thread can get in here and it only gets in once
554 static aligned_storage<sizeof(locale)>::type buf;
555 locale* c = reinterpret_cast<locale*>(&buf);
556 c->__locale_ = &make<__imp>(1u);
563 static const locale& c = __imp::make_classic();
568 locale::__imp::make_global()
570 // only one thread can get in here and it only gets in once
571 static aligned_storage<sizeof(locale)>::type buf;
572 auto *obj = ::new (&buf) locale(locale::classic());
579 static locale& g = __imp::make_global();
583 locale::locale() noexcept
584 : __locale_(__global().__locale_)
586 __locale_->__add_shared();
589 locale::locale(const locale& l) noexcept
590 : __locale_(l.__locale_)
592 __locale_->__add_shared();
597 __locale_->__release_shared();
601 locale::operator=(const locale& other) noexcept
603 other.__locale_->__add_shared();
604 __locale_->__release_shared();
605 __locale_ = other.__locale_;
609 locale::locale(const char* name)
610 : __locale_(name ? new __imp(name)
611 : (__throw_runtime_error("locale constructed with null"), nullptr))
613 __locale_->__add_shared();
616 locale::locale(const string& name)
617 : __locale_(new __imp(name))
619 __locale_->__add_shared();
622 locale::locale(const locale& other, const char* name, category c)
623 : __locale_(name ? new __imp(*other.__locale_, name, c)
624 : (__throw_runtime_error("locale constructed with null"), nullptr))
626 __locale_->__add_shared();
629 locale::locale(const locale& other, const string& name, category c)
630 : __locale_(new __imp(*other.__locale_, name, c))
632 __locale_->__add_shared();
635 locale::locale(const locale& other, const locale& one, category c)
636 : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
638 __locale_->__add_shared();
644 return __locale_->name();
648 locale::__install_ctor(const locale& other, facet* f, long id)
651 __locale_ = new __imp(*other.__locale_, f, id);
653 __locale_ = other.__locale_;
654 __locale_->__add_shared();
658 locale::global(const locale& loc)
660 locale& g = __global();
664 setlocale(LC_ALL, g.name().c_str());
669 locale::has_facet(id& x) const
671 return __locale_->has_facet(x.__get());
675 locale::use_facet(id& x) const
677 return __locale_->use_facet(x.__get());
681 locale::operator==(const locale& y) const
683 return (__locale_ == y.__locale_)
684 || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
689 locale::facet::~facet()
694 locale::facet::__on_zero_shared() noexcept
701 int32_t locale::id::__next_id = 0;
709 void (locale::id::* pmf_)();
711 __fake_bind(void (locale::id::* pmf)(), locale::id* id)
712 : id_(id), pmf_(pmf) {}
714 void operator()() const
725 call_once(__flag_, __fake_bind(&locale::id::__init, this));
732 __id_ = __libcpp_atomic_add(&__next_id, 1);
735 // template <> class collate_byname<char>
737 collate_byname<char>::collate_byname(const char* n, size_t refs)
738 : collate<char>(refs),
739 __l_(newlocale(LC_ALL_MASK, n, 0))
742 __throw_runtime_error("collate_byname<char>::collate_byname"
743 " failed to construct for " + string(n));
746 collate_byname<char>::collate_byname(const string& name, size_t refs)
747 : collate<char>(refs),
748 __l_(newlocale(LC_ALL_MASK, name.c_str(), 0))
751 __throw_runtime_error("collate_byname<char>::collate_byname"
752 " failed to construct for " + name);
755 collate_byname<char>::~collate_byname()
761 collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
762 const char_type* __lo2, const char_type* __hi2) const
764 string_type lhs(__lo1, __hi1);
765 string_type rhs(__lo2, __hi2);
766 int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l_);
774 collate_byname<char>::string_type
775 collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
777 const string_type in(lo, hi);
778 string_type out(strxfrm_l(0, in.c_str(), 0, __l_), char());
779 strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l_);
783 // template <> class collate_byname<wchar_t>
785 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
786 collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
787 : collate<wchar_t>(refs),
788 __l_(newlocale(LC_ALL_MASK, n, 0))
791 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
792 " failed to construct for " + string(n));
795 collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
796 : collate<wchar_t>(refs),
797 __l_(newlocale(LC_ALL_MASK, name.c_str(), 0))
800 __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
801 " failed to construct for " + name);
804 collate_byname<wchar_t>::~collate_byname()
810 collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
811 const char_type* __lo2, const char_type* __hi2) const
813 string_type lhs(__lo1, __hi1);
814 string_type rhs(__lo2, __hi2);
815 int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l_);
823 collate_byname<wchar_t>::string_type
824 collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
826 const string_type in(lo, hi);
827 string_type out(wcsxfrm_l(0, in.c_str(), 0, __l_), wchar_t());
828 wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l_);
831 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
833 const ctype_base::mask ctype_base::space;
834 const ctype_base::mask ctype_base::print;
835 const ctype_base::mask ctype_base::cntrl;
836 const ctype_base::mask ctype_base::upper;
837 const ctype_base::mask ctype_base::lower;
838 const ctype_base::mask ctype_base::alpha;
839 const ctype_base::mask ctype_base::digit;
840 const ctype_base::mask ctype_base::punct;
841 const ctype_base::mask ctype_base::xdigit;
842 const ctype_base::mask ctype_base::blank;
843 const ctype_base::mask ctype_base::alnum;
844 const ctype_base::mask ctype_base::graph;
846 // template <> class ctype<wchar_t>;
848 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
849 locale::id ctype<wchar_t>::id;
851 ctype<wchar_t>::~ctype()
856 ctype<wchar_t>::do_is(mask m, char_type c) const
858 return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
862 ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
864 for (; low != high; ++low, ++vec)
865 *vec = static_cast<mask>(isascii(*low) ?
866 ctype<char>::classic_table()[*low] : 0);
871 ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
873 for (; low != high; ++low)
874 if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
880 ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
882 for (; low != high; ++low)
883 if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
889 ctype<wchar_t>::do_toupper(char_type c) const
891 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
892 return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
893 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
894 defined(__NetBSD__) || defined(__MVS__)
895 return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
897 return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;
902 ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
904 for (; low != high; ++low)
905 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
906 *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
907 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
908 defined(__NetBSD__) || defined(__MVS__)
909 *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
912 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low;
918 ctype<wchar_t>::do_tolower(char_type c) const
920 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
921 return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
922 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
923 defined(__NetBSD__) || defined(__MVS__)
924 return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
926 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;
931 ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
933 for (; low != high; ++low)
934 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
935 *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
936 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
937 defined(__NetBSD__) || defined(__MVS__)
938 *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
941 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low;
947 ctype<wchar_t>::do_widen(char c) const
953 ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
955 for (; low != high; ++low, ++dest)
961 ctype<wchar_t>::do_narrow(char_type c, char dfault) const
964 return static_cast<char>(c);
969 ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
971 for (; low != high; ++low, ++dest)
973 *dest = static_cast<char>(*low);
978 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
980 // template <> class ctype<char>;
982 locale::id ctype<char>::id;
984 const size_t ctype<char>::table_size;
986 ctype<char>::ctype(const mask* tab, bool del, size_t refs)
987 : locale::facet(refs),
992 __tab_ = classic_table();
995 ctype<char>::~ctype()
997 if (__tab_ && __del_)
1002 ctype<char>::do_toupper(char_type c) const
1004 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1006 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
1007 #elif defined(__NetBSD__)
1008 return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
1009 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1011 static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
1013 return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;
1018 ctype<char>::do_toupper(char_type* low, const char_type* high) const
1020 for (; low != high; ++low)
1021 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1022 *low = isascii(*low) ?
1023 static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
1024 #elif defined(__NetBSD__)
1025 *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
1026 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1027 *low = isascii(*low) ?
1028 static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
1030 *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low;
1036 ctype<char>::do_tolower(char_type c) const
1038 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1040 static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
1041 #elif defined(__NetBSD__)
1042 return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
1043 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1045 static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
1047 return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c;
1052 ctype<char>::do_tolower(char_type* low, const char_type* high) const
1054 for (; low != high; ++low)
1055 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
1056 *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
1057 #elif defined(__NetBSD__)
1058 *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
1059 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__MVS__)
1060 *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
1062 *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low;
1068 ctype<char>::do_widen(char c) const
1074 ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
1076 for (; low != high; ++low, ++dest)
1082 ctype<char>::do_narrow(char_type c, char dfault) const
1085 return static_cast<char>(c);
1090 ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1092 for (; low != high; ++low, ++dest)
1100 #if defined(__EMSCRIPTEN__)
1101 extern "C" const unsigned short ** __ctype_b_loc();
1102 extern "C" const int ** __ctype_tolower_loc();
1103 extern "C" const int ** __ctype_toupper_loc();
1106 #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
1107 const ctype<char>::mask*
1108 ctype<char>::classic_table() noexcept
1110 static _LIBCPP_CONSTEXPR const ctype<char>::mask builtin_table[table_size] = {
1115 cntrl, cntrl | space | blank,
1116 cntrl | space, cntrl | space,
1117 cntrl | space, cntrl | space,
1127 space | blank | print, punct | print,
1128 punct | print, punct | print,
1129 punct | print, punct | print,
1130 punct | print, punct | print,
1131 punct | print, punct | print,
1132 punct | print, punct | print,
1133 punct | print, punct | print,
1134 punct | print, punct | print,
1135 digit | print | xdigit, digit | print | xdigit,
1136 digit | print | xdigit, digit | print | xdigit,
1137 digit | print | xdigit, digit | print | xdigit,
1138 digit | print | xdigit, digit | print | xdigit,
1139 digit | print | xdigit, digit | print | xdigit,
1140 punct | print, punct | print,
1141 punct | print, punct | print,
1142 punct | print, punct | print,
1143 punct | print, upper | xdigit | print | alpha,
1144 upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1145 upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1146 upper | xdigit | print | alpha, upper | print | alpha,
1147 upper | print | alpha, upper | print | alpha,
1148 upper | print | alpha, upper | print | alpha,
1149 upper | print | alpha, upper | print | alpha,
1150 upper | print | alpha, upper | print | alpha,
1151 upper | print | alpha, upper | print | alpha,
1152 upper | print | alpha, upper | print | alpha,
1153 upper | print | alpha, upper | print | alpha,
1154 upper | print | alpha, upper | print | alpha,
1155 upper | print | alpha, upper | print | alpha,
1156 upper | print | alpha, punct | print,
1157 punct | print, punct | print,
1158 punct | print, punct | print,
1159 punct | print, lower | xdigit | print | alpha,
1160 lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1161 lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1162 lower | xdigit | print | alpha, lower | print | alpha,
1163 lower | print | alpha, lower | print | alpha,
1164 lower | print | alpha, lower | print | alpha,
1165 lower | print | alpha, lower | print | alpha,
1166 lower | print | alpha, lower | print | alpha,
1167 lower | print | alpha, lower | print | alpha,
1168 lower | print | alpha, lower | print | alpha,
1169 lower | print | alpha, lower | print | alpha,
1170 lower | print | alpha, lower | print | alpha,
1171 lower | print | alpha, lower | print | alpha,
1172 lower | print | alpha, punct | print,
1173 punct | print, punct | print,
1174 punct | print, cntrl,
1175 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1176 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1177 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1178 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1179 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1180 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1181 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1182 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1184 return builtin_table;
1187 const ctype<char>::mask*
1188 ctype<char>::classic_table() noexcept
1190 #if defined(__APPLE__) || defined(__FreeBSD__)
1191 return _DefaultRuneLocale.__runetype;
1192 #elif defined(__NetBSD__)
1193 return _C_ctype_tab_ + 1;
1194 #elif defined(__GLIBC__)
1195 return _LIBCPP_GET_C_LOCALE->__ctype_b;
1196 #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
1197 return __pctype_func();
1198 #elif defined(__EMSCRIPTEN__)
1199 return *__ctype_b_loc();
1200 #elif defined(_NEWLIB_VERSION)
1201 // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
1204 return (const unsigned int *)__lc_ctype_ptr->obj->mask;
1205 #elif defined(__MVS__)
1206 # if defined(__NATIVE_ASCII_F)
1207 return const_cast<const ctype<char>::mask*> (__OBJ_DATA(__lc_ctype_a)->mask);
1209 return const_cast<const ctype<char>::mask*> (__ctypec);
1212 // Platform not supported: abort so the person doing the port knows what to
1214 # warning ctype<char>::classic_table() is not implemented
1215 printf("ctype<char>::classic_table() is not implemented\n");
1222 #if defined(__GLIBC__)
1224 ctype<char>::__classic_lower_table() noexcept
1226 return _LIBCPP_GET_C_LOCALE->__ctype_tolower;
1230 ctype<char>::__classic_upper_table() noexcept
1232 return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
1234 #elif defined(__NetBSD__)
1236 ctype<char>::__classic_lower_table() noexcept
1238 return _C_tolower_tab_ + 1;
1242 ctype<char>::__classic_upper_table() noexcept
1244 return _C_toupper_tab_ + 1;
1247 #elif defined(__EMSCRIPTEN__)
1249 ctype<char>::__classic_lower_table() noexcept
1251 return *__ctype_tolower_loc();
1255 ctype<char>::__classic_upper_table() noexcept
1257 return *__ctype_toupper_loc();
1259 #elif defined(__MVS__)
1260 const unsigned short*
1261 ctype<char>::__classic_lower_table() _NOEXCEPT
1263 # if defined(__NATIVE_ASCII_F)
1264 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a)->lower);
1266 return const_cast<const unsigned short*>(__ctype + __TOLOWER_INDEX);
1269 const unsigned short *
1270 ctype<char>::__classic_upper_table() _NOEXCEPT
1272 # if defined(__NATIVE_ASCII_F)
1273 return const_cast<const unsigned short*>(__OBJ_DATA(__lc_ctype_a)->upper);
1275 return const_cast<const unsigned short*>(__ctype + __TOUPPER_INDEX);
1278 #endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ || __MVS__
1280 // template <> class ctype_byname<char>
1282 ctype_byname<char>::ctype_byname(const char* name, size_t refs)
1283 : ctype<char>(0, false, refs),
1284 __l_(newlocale(LC_ALL_MASK, name, 0))
1287 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1288 " failed to construct for " + string(name));
1291 ctype_byname<char>::ctype_byname(const string& name, size_t refs)
1292 : ctype<char>(0, false, refs),
1293 __l_(newlocale(LC_ALL_MASK, name.c_str(), 0))
1296 __throw_runtime_error("ctype_byname<char>::ctype_byname"
1297 " failed to construct for " + name);
1300 ctype_byname<char>::~ctype_byname()
1306 ctype_byname<char>::do_toupper(char_type c) const
1308 return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l_));
1312 ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
1314 for (; low != high; ++low)
1315 *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l_));
1320 ctype_byname<char>::do_tolower(char_type c) const
1322 return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l_));
1326 ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
1328 for (; low != high; ++low)
1329 *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l_));
1333 // template <> class ctype_byname<wchar_t>
1335 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1336 ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
1337 : ctype<wchar_t>(refs),
1338 __l_(newlocale(LC_ALL_MASK, name, 0))
1341 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1342 " failed to construct for " + string(name));
1345 ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
1346 : ctype<wchar_t>(refs),
1347 __l_(newlocale(LC_ALL_MASK, name.c_str(), 0))
1350 __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1351 " failed to construct for " + name);
1354 ctype_byname<wchar_t>::~ctype_byname()
1360 ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1362 #ifdef _LIBCPP_WCTYPE_IS_MASK
1363 return static_cast<bool>(iswctype_l(c, m, __l_));
1365 bool result = false;
1366 wint_t ch = static_cast<wint_t>(c);
1367 if ((m & space) == space) result |= (iswspace_l(ch, __l_) != 0);
1368 if ((m & print) == print) result |= (iswprint_l(ch, __l_) != 0);
1369 if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l_) != 0);
1370 if ((m & upper) == upper) result |= (iswupper_l(ch, __l_) != 0);
1371 if ((m & lower) == lower) result |= (iswlower_l(ch, __l_) != 0);
1372 if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l_) != 0);
1373 if ((m & digit) == digit) result |= (iswdigit_l(ch, __l_) != 0);
1374 if ((m & punct) == punct) result |= (iswpunct_l(ch, __l_) != 0);
1375 if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l_) != 0);
1376 if ((m & blank) == blank) result |= (iswblank_l(ch, __l_) != 0);
1382 ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1384 for (; low != high; ++low, ++vec)
1387 *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
1391 wint_t ch = static_cast<wint_t>(*low);
1392 if (iswspace_l(ch, __l_))
1394 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
1395 if (iswprint_l(ch, __l_))
1398 if (iswcntrl_l(ch, __l_))
1400 if (iswupper_l(ch, __l_))
1402 if (iswlower_l(ch, __l_))
1404 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
1405 if (iswalpha_l(ch, __l_))
1408 if (iswdigit_l(ch, __l_))
1410 if (iswpunct_l(ch, __l_))
1412 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
1413 if (iswxdigit_l(ch, __l_))
1416 if (iswblank_l(ch, __l_))
1424 ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1426 for (; low != high; ++low)
1428 #ifdef _LIBCPP_WCTYPE_IS_MASK
1429 if (iswctype_l(*low, m, __l_))
1432 wint_t ch = static_cast<wint_t>(*low);
1433 if ((m & space) == space && iswspace_l(ch, __l_)) break;
1434 if ((m & print) == print && iswprint_l(ch, __l_)) break;
1435 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l_)) break;
1436 if ((m & upper) == upper && iswupper_l(ch, __l_)) break;
1437 if ((m & lower) == lower && iswlower_l(ch, __l_)) break;
1438 if ((m & alpha) == alpha && iswalpha_l(ch, __l_)) break;
1439 if ((m & digit) == digit && iswdigit_l(ch, __l_)) break;
1440 if ((m & punct) == punct && iswpunct_l(ch, __l_)) break;
1441 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l_)) break;
1442 if ((m & blank) == blank && iswblank_l(ch, __l_)) break;
1449 ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1451 for (; low != high; ++low)
1453 #ifdef _LIBCPP_WCTYPE_IS_MASK
1454 if (!iswctype_l(*low, m, __l_))
1457 wint_t ch = static_cast<wint_t>(*low);
1458 if ((m & space) == space && iswspace_l(ch, __l_)) continue;
1459 if ((m & print) == print && iswprint_l(ch, __l_)) continue;
1460 if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l_)) continue;
1461 if ((m & upper) == upper && iswupper_l(ch, __l_)) continue;
1462 if ((m & lower) == lower && iswlower_l(ch, __l_)) continue;
1463 if ((m & alpha) == alpha && iswalpha_l(ch, __l_)) continue;
1464 if ((m & digit) == digit && iswdigit_l(ch, __l_)) continue;
1465 if ((m & punct) == punct && iswpunct_l(ch, __l_)) continue;
1466 if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l_)) continue;
1467 if ((m & blank) == blank && iswblank_l(ch, __l_)) continue;
1475 ctype_byname<wchar_t>::do_toupper(char_type c) const
1477 return towupper_l(c, __l_);
1481 ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1483 for (; low != high; ++low)
1484 *low = towupper_l(*low, __l_);
1489 ctype_byname<wchar_t>::do_tolower(char_type c) const
1491 return towlower_l(c, __l_);
1495 ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1497 for (; low != high; ++low)
1498 *low = towlower_l(*low, __l_);
1503 ctype_byname<wchar_t>::do_widen(char c) const
1505 return __libcpp_btowc_l(c, __l_);
1509 ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1511 for (; low != high; ++low, ++dest)
1512 *dest = __libcpp_btowc_l(*low, __l_);
1517 ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1519 int r = __libcpp_wctob_l(c, __l_);
1520 return (r != EOF) ? static_cast<char>(r) : dfault;
1524 ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1526 for (; low != high; ++low, ++dest)
1528 int r = __libcpp_wctob_l(*low, __l_);
1529 *dest = (r != EOF) ? static_cast<char>(r) : dfault;
1533 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1535 // template <> class codecvt<char, char, mbstate_t>
1537 locale::id codecvt<char, char, mbstate_t>::id;
1539 codecvt<char, char, mbstate_t>::~codecvt()
1543 codecvt<char, char, mbstate_t>::result
1544 codecvt<char, char, mbstate_t>::do_out(state_type&,
1545 const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
1546 extern_type* to, extern_type*, extern_type*& to_nxt) const
1553 codecvt<char, char, mbstate_t>::result
1554 codecvt<char, char, mbstate_t>::do_in(state_type&,
1555 const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
1556 intern_type* to, intern_type*, intern_type*& to_nxt) const
1563 codecvt<char, char, mbstate_t>::result
1564 codecvt<char, char, mbstate_t>::do_unshift(state_type&,
1565 extern_type* to, extern_type*, extern_type*& to_nxt) const
1572 codecvt<char, char, mbstate_t>::do_encoding() const noexcept
1578 codecvt<char, char, mbstate_t>::do_always_noconv() const noexcept
1584 codecvt<char, char, mbstate_t>::do_length(state_type&,
1585 const extern_type* frm, const extern_type* end, size_t mx) const
1587 return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
1591 codecvt<char, char, mbstate_t>::do_max_length() const noexcept
1596 // template <> class codecvt<wchar_t, char, mbstate_t>
1598 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
1599 locale::id codecvt<wchar_t, char, mbstate_t>::id;
1601 codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1602 : locale::facet(refs),
1603 __l_(_LIBCPP_GET_C_LOCALE)
1607 codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1608 : locale::facet(refs),
1609 __l_(newlocale(LC_ALL_MASK, nm, 0))
1612 __throw_runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1613 " failed to construct for " + string(nm));
1616 codecvt<wchar_t, char, mbstate_t>::~codecvt()
1618 if (__l_ != _LIBCPP_GET_C_LOCALE)
1622 codecvt<wchar_t, char, mbstate_t>::result
1623 codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
1624 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
1625 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1627 // look for first internal null in frm
1628 const intern_type* fend = frm;
1629 for (; fend != frm_end; ++fend)
1632 // loop over all null-terminated sequences in frm
1634 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1636 // save state in case it is needed to recover to_nxt on error
1637 mbstate_t save_state = st;
1638 size_t n = __libcpp_wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1639 static_cast<size_t>(to_end-to), &st, __l_);
1640 if (n == size_t(-1))
1642 // need to recover to_nxt
1643 for (to_nxt = to; frm != frm_nxt; ++frm)
1645 n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l_);
1646 if (n == size_t(-1))
1656 if (to_nxt == to_end)
1658 if (fend != frm_end) // set up next null terminated sequence
1660 // Try to write the terminating null
1661 extern_type tmp[MB_LEN_MAX];
1662 n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l_);
1663 if (n == size_t(-1)) // on error
1665 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1667 for (extern_type* p = tmp; n; --n) // write it
1670 // look for next null in frm
1671 for (fend = frm_nxt; fend != frm_end; ++fend)
1676 return frm_nxt == frm_end ? ok : partial;
1679 codecvt<wchar_t, char, mbstate_t>::result
1680 codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
1681 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
1682 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1684 // look for first internal null in frm
1685 const extern_type* fend = frm;
1686 for (; fend != frm_end; ++fend)
1689 // loop over all null-terminated sequences in frm
1691 for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1693 // save state in case it is needed to recover to_nxt on error
1694 mbstate_t save_state = st;
1695 size_t n = __libcpp_mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1696 static_cast<size_t>(to_end-to), &st, __l_);
1697 if (n == size_t(-1))
1699 // need to recover to_nxt
1700 for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1702 n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
1721 return frm_nxt == frm_end ? ok : partial;
1723 if (n == size_t(-1))
1726 if (to_nxt == to_end)
1728 if (fend != frm_end) // set up next null terminated sequence
1730 // Try to write the terminating null
1731 n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l_);
1732 if (n != 0) // on error
1736 // look for next null in frm
1737 for (fend = frm_nxt; fend != frm_end; ++fend)
1742 return frm_nxt == frm_end ? ok : partial;
1745 codecvt<wchar_t, char, mbstate_t>::result
1746 codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1747 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1750 extern_type tmp[MB_LEN_MAX];
1751 size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l_);
1752 if (n == size_t(-1) || n == 0) // on error
1755 if (n > static_cast<size_t>(to_end-to_nxt)) // is there room?
1757 for (extern_type* p = tmp; n; --n) // write it
1763 codecvt<wchar_t, char, mbstate_t>::do_encoding() const noexcept
1765 if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l_) != 0)
1768 // stateless encoding
1769 if (__l_ == 0 || __libcpp_mb_cur_max_l(__l_) == 1) // there are no known constant length encodings
1770 return 1; // which take more than 1 char to form a wchar_t
1775 codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const noexcept
1781 codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1782 const extern_type* frm, const extern_type* frm_end, size_t mx) const
1785 for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1787 size_t n = __libcpp_mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l_);
1807 codecvt<wchar_t, char, mbstate_t>::do_max_length() const noexcept
1809 return __l_ == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l_));
1811 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
1814 // UTF-32 UTF-16 UTF-8 # of code points
1815 // first second first second third fourth
1816 // 000000 - 00007F 0000 - 007F 00 - 7F 127
1817 // 000080 - 0007FF 0080 - 07FF C2 - DF, 80 - BF 1920
1818 // 000800 - 000FFF 0800 - 0FFF E0 - E0, A0 - BF, 80 - BF 2048
1819 // 001000 - 00CFFF 1000 - CFFF E1 - EC, 80 - BF, 80 - BF 49152
1820 // 00D000 - 00D7FF D000 - D7FF ED - ED, 80 - 9F, 80 - BF 2048
1821 // 00D800 - 00DFFF invalid
1822 // 00E000 - 00FFFF E000 - FFFF EE - EF, 80 - BF, 80 - BF 8192
1823 // 010000 - 03FFFF D800 - D8BF, DC00 - DFFF F0 - F0, 90 - BF, 80 - BF, 80 - BF 196608
1824 // 040000 - 0FFFFF D8C0 - DBBF, DC00 - DFFF F1 - F3, 80 - BF, 80 - BF, 80 - BF 786432
1825 // 100000 - 10FFFF DBC0 - DBFF, DC00 - DFFF F4 - F4, 80 - 8F, 80 - BF, 80 - BF 65536
1827 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1829 codecvt_base::result
1830 utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1831 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1832 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1836 if (mode & generate_header)
1838 if (to_end-to_nxt < 3)
1839 return codecvt_base::partial;
1840 *to_nxt++ = static_cast<uint8_t>(0xEF);
1841 *to_nxt++ = static_cast<uint8_t>(0xBB);
1842 *to_nxt++ = static_cast<uint8_t>(0xBF);
1844 for (; frm_nxt < frm_end; ++frm_nxt)
1846 uint16_t wc1 = *frm_nxt;
1848 return codecvt_base::error;
1851 if (to_end-to_nxt < 1)
1852 return codecvt_base::partial;
1853 *to_nxt++ = static_cast<uint8_t>(wc1);
1855 else if (wc1 < 0x0800)
1857 if (to_end-to_nxt < 2)
1858 return codecvt_base::partial;
1859 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1860 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1862 else if (wc1 < 0xD800)
1864 if (to_end-to_nxt < 3)
1865 return codecvt_base::partial;
1866 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1867 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1868 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1870 else if (wc1 < 0xDC00)
1872 if (frm_end-frm_nxt < 2)
1873 return codecvt_base::partial;
1874 uint16_t wc2 = frm_nxt[1];
1875 if ((wc2 & 0xFC00) != 0xDC00)
1876 return codecvt_base::error;
1877 if (to_end-to_nxt < 4)
1878 return codecvt_base::partial;
1879 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1880 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1881 return codecvt_base::error;
1883 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1884 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1885 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1886 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1887 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1889 else if (wc1 < 0xE000)
1891 return codecvt_base::error;
1895 if (to_end-to_nxt < 3)
1896 return codecvt_base::partial;
1897 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1898 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1899 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1902 return codecvt_base::ok;
1906 codecvt_base::result
1907 utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1908 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1909 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1913 if (mode & generate_header)
1915 if (to_end-to_nxt < 3)
1916 return codecvt_base::partial;
1917 *to_nxt++ = static_cast<uint8_t>(0xEF);
1918 *to_nxt++ = static_cast<uint8_t>(0xBB);
1919 *to_nxt++ = static_cast<uint8_t>(0xBF);
1921 for (; frm_nxt < frm_end; ++frm_nxt)
1923 uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1925 return codecvt_base::error;
1928 if (to_end-to_nxt < 1)
1929 return codecvt_base::partial;
1930 *to_nxt++ = static_cast<uint8_t>(wc1);
1932 else if (wc1 < 0x0800)
1934 if (to_end-to_nxt < 2)
1935 return codecvt_base::partial;
1936 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1937 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1939 else if (wc1 < 0xD800)
1941 if (to_end-to_nxt < 3)
1942 return codecvt_base::partial;
1943 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1944 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1945 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1947 else if (wc1 < 0xDC00)
1949 if (frm_end-frm_nxt < 2)
1950 return codecvt_base::partial;
1951 uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1952 if ((wc2 & 0xFC00) != 0xDC00)
1953 return codecvt_base::error;
1954 if (to_end-to_nxt < 4)
1955 return codecvt_base::partial;
1956 if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1957 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1958 return codecvt_base::error;
1960 uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1961 *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1962 *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4) | ((wc1 & 0x003C) >> 2));
1963 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1964 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc2 & 0x003F));
1966 else if (wc1 < 0xE000)
1968 return codecvt_base::error;
1972 if (to_end-to_nxt < 3)
1973 return codecvt_base::partial;
1974 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc1 >> 12));
1975 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1976 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x003F));
1979 return codecvt_base::ok;
1983 codecvt_base::result
1984 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1985 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1986 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1990 if (mode & consume_header)
1992 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1996 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1998 uint8_t c1 = *frm_nxt;
2000 return codecvt_base::error;
2003 *to_nxt = static_cast<uint16_t>(c1);
2008 return codecvt_base::error;
2012 if (frm_end-frm_nxt < 2)
2013 return codecvt_base::partial;
2014 uint8_t c2 = frm_nxt[1];
2015 if ((c2 & 0xC0) != 0x80)
2016 return codecvt_base::error;
2017 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2019 return codecvt_base::error;
2025 if (frm_end-frm_nxt < 3)
2026 return codecvt_base::partial;
2027 uint8_t c2 = frm_nxt[1];
2028 uint8_t c3 = frm_nxt[2];
2032 if ((c2 & 0xE0) != 0xA0)
2033 return codecvt_base::error;
2036 if ((c2 & 0xE0) != 0x80)
2037 return codecvt_base::error;
2040 if ((c2 & 0xC0) != 0x80)
2041 return codecvt_base::error;
2044 if ((c3 & 0xC0) != 0x80)
2045 return codecvt_base::error;
2046 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2047 | ((c2 & 0x3F) << 6)
2050 return codecvt_base::error;
2056 if (frm_end-frm_nxt < 4)
2057 return codecvt_base::partial;
2058 uint8_t c2 = frm_nxt[1];
2059 uint8_t c3 = frm_nxt[2];
2060 uint8_t c4 = frm_nxt[3];
2064 if (!(0x90 <= c2 && c2 <= 0xBF))
2065 return codecvt_base::error;
2068 if ((c2 & 0xF0) != 0x80)
2069 return codecvt_base::error;
2072 if ((c2 & 0xC0) != 0x80)
2073 return codecvt_base::error;
2076 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2077 return codecvt_base::error;
2078 if (to_end-to_nxt < 2)
2079 return codecvt_base::partial;
2080 if ((((c1 & 7UL) << 18) +
2081 ((c2 & 0x3FUL) << 12) +
2082 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2083 return codecvt_base::error;
2084 *to_nxt = static_cast<uint16_t>(
2086 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2087 | ((c2 & 0x0F) << 2)
2088 | ((c3 & 0x30) >> 4));
2089 *++to_nxt = static_cast<uint16_t>(
2091 | ((c3 & 0x0F) << 6)
2097 return codecvt_base::error;
2100 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2104 codecvt_base::result
2105 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2106 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2107 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2111 if (mode & consume_header)
2113 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2117 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2119 uint8_t c1 = *frm_nxt;
2121 return codecvt_base::error;
2124 *to_nxt = static_cast<uint32_t>(c1);
2129 return codecvt_base::error;
2133 if (frm_end-frm_nxt < 2)
2134 return codecvt_base::partial;
2135 uint8_t c2 = frm_nxt[1];
2136 if ((c2 & 0xC0) != 0x80)
2137 return codecvt_base::error;
2138 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2140 return codecvt_base::error;
2141 *to_nxt = static_cast<uint32_t>(t);
2146 if (frm_end-frm_nxt < 3)
2147 return codecvt_base::partial;
2148 uint8_t c2 = frm_nxt[1];
2149 uint8_t c3 = frm_nxt[2];
2153 if ((c2 & 0xE0) != 0xA0)
2154 return codecvt_base::error;
2157 if ((c2 & 0xE0) != 0x80)
2158 return codecvt_base::error;
2161 if ((c2 & 0xC0) != 0x80)
2162 return codecvt_base::error;
2165 if ((c3 & 0xC0) != 0x80)
2166 return codecvt_base::error;
2167 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2168 | ((c2 & 0x3F) << 6)
2171 return codecvt_base::error;
2172 *to_nxt = static_cast<uint32_t>(t);
2177 if (frm_end-frm_nxt < 4)
2178 return codecvt_base::partial;
2179 uint8_t c2 = frm_nxt[1];
2180 uint8_t c3 = frm_nxt[2];
2181 uint8_t c4 = frm_nxt[3];
2185 if (!(0x90 <= c2 && c2 <= 0xBF))
2186 return codecvt_base::error;
2189 if ((c2 & 0xF0) != 0x80)
2190 return codecvt_base::error;
2193 if ((c2 & 0xC0) != 0x80)
2194 return codecvt_base::error;
2197 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2198 return codecvt_base::error;
2199 if (to_end-to_nxt < 2)
2200 return codecvt_base::partial;
2201 if ((((c1 & 7UL) << 18) +
2202 ((c2 & 0x3FUL) << 12) +
2203 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2204 return codecvt_base::error;
2205 *to_nxt = static_cast<uint32_t>(
2207 | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2208 | ((c2 & 0x0F) << 2)
2209 | ((c3 & 0x30) >> 4));
2210 *++to_nxt = static_cast<uint32_t>(
2212 | ((c3 & 0x0F) << 6)
2218 return codecvt_base::error;
2221 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2226 utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
2227 size_t mx, unsigned long Maxcode = 0x10FFFF,
2228 codecvt_mode mode = codecvt_mode(0))
2230 const uint8_t* frm_nxt = frm;
2231 if (mode & consume_header)
2233 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2237 for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
2239 uint8_t c1 = *frm_nxt;
2252 if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
2254 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
2261 if (frm_end-frm_nxt < 3)
2263 uint8_t c2 = frm_nxt[1];
2264 uint8_t c3 = frm_nxt[2];
2268 if ((c2 & 0xE0) != 0xA0)
2269 return static_cast<int>(frm_nxt - frm);
2272 if ((c2 & 0xE0) != 0x80)
2273 return static_cast<int>(frm_nxt - frm);
2276 if ((c2 & 0xC0) != 0x80)
2277 return static_cast<int>(frm_nxt - frm);
2280 if ((c3 & 0xC0) != 0x80)
2282 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2288 if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
2290 uint8_t c2 = frm_nxt[1];
2291 uint8_t c3 = frm_nxt[2];
2292 uint8_t c4 = frm_nxt[3];
2296 if (!(0x90 <= c2 && c2 <= 0xBF))
2297 return static_cast<int>(frm_nxt - frm);
2300 if ((c2 & 0xF0) != 0x80)
2301 return static_cast<int>(frm_nxt - frm);
2304 if ((c2 & 0xC0) != 0x80)
2305 return static_cast<int>(frm_nxt - frm);
2308 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2310 if ((((c1 & 7UL) << 18) +
2311 ((c2 & 0x3FUL) << 12) +
2312 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2322 return static_cast<int>(frm_nxt - frm);
2326 codecvt_base::result
2327 ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2328 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2329 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2333 if (mode & generate_header)
2335 if (to_end-to_nxt < 3)
2336 return codecvt_base::partial;
2337 *to_nxt++ = static_cast<uint8_t>(0xEF);
2338 *to_nxt++ = static_cast<uint8_t>(0xBB);
2339 *to_nxt++ = static_cast<uint8_t>(0xBF);
2341 for (; frm_nxt < frm_end; ++frm_nxt)
2343 uint32_t wc = *frm_nxt;
2344 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2345 return codecvt_base::error;
2348 if (to_end-to_nxt < 1)
2349 return codecvt_base::partial;
2350 *to_nxt++ = static_cast<uint8_t>(wc);
2352 else if (wc < 0x000800)
2354 if (to_end-to_nxt < 2)
2355 return codecvt_base::partial;
2356 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2357 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2359 else if (wc < 0x010000)
2361 if (to_end-to_nxt < 3)
2362 return codecvt_base::partial;
2363 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2364 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2365 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2367 else // if (wc < 0x110000)
2369 if (to_end-to_nxt < 4)
2370 return codecvt_base::partial;
2371 *to_nxt++ = static_cast<uint8_t>(0xF0 | (wc >> 18));
2372 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2373 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2374 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x00003F));
2377 return codecvt_base::ok;
2381 codecvt_base::result
2382 utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2383 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2384 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2388 if (mode & consume_header)
2390 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2394 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2396 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2400 return codecvt_base::error;
2401 *to_nxt = static_cast<uint32_t>(c1);
2406 return codecvt_base::error;
2410 if (frm_end-frm_nxt < 2)
2411 return codecvt_base::partial;
2412 uint8_t c2 = frm_nxt[1];
2413 if ((c2 & 0xC0) != 0x80)
2414 return codecvt_base::error;
2415 uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2418 return codecvt_base::error;
2424 if (frm_end-frm_nxt < 3)
2425 return codecvt_base::partial;
2426 uint8_t c2 = frm_nxt[1];
2427 uint8_t c3 = frm_nxt[2];
2431 if ((c2 & 0xE0) != 0xA0)
2432 return codecvt_base::error;
2435 if ((c2 & 0xE0) != 0x80)
2436 return codecvt_base::error;
2439 if ((c2 & 0xC0) != 0x80)
2440 return codecvt_base::error;
2443 if ((c3 & 0xC0) != 0x80)
2444 return codecvt_base::error;
2445 uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2446 | ((c2 & 0x3F) << 6)
2449 return codecvt_base::error;
2455 if (frm_end-frm_nxt < 4)
2456 return codecvt_base::partial;
2457 uint8_t c2 = frm_nxt[1];
2458 uint8_t c3 = frm_nxt[2];
2459 uint8_t c4 = frm_nxt[3];
2463 if (!(0x90 <= c2 && c2 <= 0xBF))
2464 return codecvt_base::error;
2467 if ((c2 & 0xF0) != 0x80)
2468 return codecvt_base::error;
2471 if ((c2 & 0xC0) != 0x80)
2472 return codecvt_base::error;
2475 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2476 return codecvt_base::error;
2477 uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2478 | ((c2 & 0x3F) << 12)
2479 | ((c3 & 0x3F) << 6)
2482 return codecvt_base::error;
2488 return codecvt_base::error;
2491 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2496 utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2497 size_t mx, unsigned long Maxcode = 0x10FFFF,
2498 codecvt_mode mode = codecvt_mode(0))
2500 const uint8_t* frm_nxt = frm;
2501 if (mode & consume_header)
2503 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2507 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2509 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2522 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2524 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2530 if (frm_end-frm_nxt < 3)
2532 uint8_t c2 = frm_nxt[1];
2533 uint8_t c3 = frm_nxt[2];
2537 if ((c2 & 0xE0) != 0xA0)
2538 return static_cast<int>(frm_nxt - frm);
2541 if ((c2 & 0xE0) != 0x80)
2542 return static_cast<int>(frm_nxt - frm);
2545 if ((c2 & 0xC0) != 0x80)
2546 return static_cast<int>(frm_nxt - frm);
2549 if ((c3 & 0xC0) != 0x80)
2551 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2557 if (frm_end-frm_nxt < 4)
2559 uint8_t c2 = frm_nxt[1];
2560 uint8_t c3 = frm_nxt[2];
2561 uint8_t c4 = frm_nxt[3];
2565 if (!(0x90 <= c2 && c2 <= 0xBF))
2566 return static_cast<int>(frm_nxt - frm);
2569 if ((c2 & 0xF0) != 0x80)
2570 return static_cast<int>(frm_nxt - frm);
2573 if ((c2 & 0xC0) != 0x80)
2574 return static_cast<int>(frm_nxt - frm);
2577 if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2579 if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
2580 ((c3 & 0x3Fu) << 6) | (c4 & 0x3Fu)) > Maxcode)
2589 return static_cast<int>(frm_nxt - frm);
2593 codecvt_base::result
2594 ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2595 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2596 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2600 if (mode & generate_header)
2602 if (to_end-to_nxt < 3)
2603 return codecvt_base::partial;
2604 *to_nxt++ = static_cast<uint8_t>(0xEF);
2605 *to_nxt++ = static_cast<uint8_t>(0xBB);
2606 *to_nxt++ = static_cast<uint8_t>(0xBF);
2608 for (; frm_nxt < frm_end; ++frm_nxt)
2610 uint16_t wc = *frm_nxt;
2611 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2612 return codecvt_base::error;
2615 if (to_end-to_nxt < 1)
2616 return codecvt_base::partial;
2617 *to_nxt++ = static_cast<uint8_t>(wc);
2619 else if (wc < 0x0800)
2621 if (to_end-to_nxt < 2)
2622 return codecvt_base::partial;
2623 *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2624 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2626 else // if (wc <= 0xFFFF)
2628 if (to_end-to_nxt < 3)
2629 return codecvt_base::partial;
2630 *to_nxt++ = static_cast<uint8_t>(0xE0 | (wc >> 12));
2631 *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2632 *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x003F));
2635 return codecvt_base::ok;
2639 codecvt_base::result
2640 utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2641 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2642 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2646 if (mode & consume_header)
2648 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2652 for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2654 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2658 return codecvt_base::error;
2659 *to_nxt = static_cast<uint16_t>(c1);
2664 return codecvt_base::error;
2668 if (frm_end-frm_nxt < 2)
2669 return codecvt_base::partial;
2670 uint8_t c2 = frm_nxt[1];
2671 if ((c2 & 0xC0) != 0x80)
2672 return codecvt_base::error;
2673 uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2676 return codecvt_base::error;
2682 if (frm_end-frm_nxt < 3)
2683 return codecvt_base::partial;
2684 uint8_t c2 = frm_nxt[1];
2685 uint8_t c3 = frm_nxt[2];
2689 if ((c2 & 0xE0) != 0xA0)
2690 return codecvt_base::error;
2693 if ((c2 & 0xE0) != 0x80)
2694 return codecvt_base::error;
2697 if ((c2 & 0xC0) != 0x80)
2698 return codecvt_base::error;
2701 if ((c3 & 0xC0) != 0x80)
2702 return codecvt_base::error;
2703 uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2704 | ((c2 & 0x3F) << 6)
2707 return codecvt_base::error;
2713 return codecvt_base::error;
2716 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2721 utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2722 size_t mx, unsigned long Maxcode = 0x10FFFF,
2723 codecvt_mode mode = codecvt_mode(0))
2725 const uint8_t* frm_nxt = frm;
2726 if (mode & consume_header)
2728 if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2732 for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2734 uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2747 if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2749 if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2755 if (frm_end-frm_nxt < 3)
2757 uint8_t c2 = frm_nxt[1];
2758 uint8_t c3 = frm_nxt[2];
2762 if ((c2 & 0xE0) != 0xA0)
2763 return static_cast<int>(frm_nxt - frm);
2766 if ((c2 & 0xE0) != 0x80)
2767 return static_cast<int>(frm_nxt - frm);
2770 if ((c2 & 0xC0) != 0x80)
2771 return static_cast<int>(frm_nxt - frm);
2774 if ((c3 & 0xC0) != 0x80)
2776 if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2785 return static_cast<int>(frm_nxt - frm);
2789 codecvt_base::result
2790 ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2791 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2792 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2796 if (mode & generate_header)
2798 if (to_end-to_nxt < 2)
2799 return codecvt_base::partial;
2800 *to_nxt++ = static_cast<uint8_t>(0xFE);
2801 *to_nxt++ = static_cast<uint8_t>(0xFF);
2803 for (; frm_nxt < frm_end; ++frm_nxt)
2805 uint32_t wc = *frm_nxt;
2806 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2807 return codecvt_base::error;
2810 if (to_end-to_nxt < 2)
2811 return codecvt_base::partial;
2812 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2813 *to_nxt++ = static_cast<uint8_t>(wc);
2817 if (to_end-to_nxt < 4)
2818 return codecvt_base::partial;
2819 uint16_t t = static_cast<uint16_t>(
2821 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2822 | ((wc & 0x00FC00) >> 10));
2823 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2824 *to_nxt++ = static_cast<uint8_t>(t);
2825 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2826 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2827 *to_nxt++ = static_cast<uint8_t>(t);
2830 return codecvt_base::ok;
2834 codecvt_base::result
2835 utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2836 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2837 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2841 if (mode & consume_header)
2843 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2846 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2848 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2849 if ((c1 & 0xFC00) == 0xDC00)
2850 return codecvt_base::error;
2851 if ((c1 & 0xFC00) != 0xD800)
2854 return codecvt_base::error;
2855 *to_nxt = static_cast<uint32_t>(c1);
2860 if (frm_end-frm_nxt < 4)
2861 return codecvt_base::partial;
2862 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2863 if ((c2 & 0xFC00) != 0xDC00)
2864 return codecvt_base::error;
2865 uint32_t t = static_cast<uint32_t>(
2866 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2867 | ((c1 & 0x003F) << 10)
2870 return codecvt_base::error;
2875 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2880 utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2881 size_t mx, unsigned long Maxcode = 0x10FFFF,
2882 codecvt_mode mode = codecvt_mode(0))
2884 const uint8_t* frm_nxt = frm;
2885 if (mode & consume_header)
2887 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2890 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2892 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2893 if ((c1 & 0xFC00) == 0xDC00)
2895 if ((c1 & 0xFC00) != 0xD800)
2903 if (frm_end-frm_nxt < 4)
2905 uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2906 if ((c2 & 0xFC00) != 0xDC00)
2908 uint32_t t = static_cast<uint32_t>(
2909 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2910 | ((c1 & 0x003F) << 10)
2917 return static_cast<int>(frm_nxt - frm);
2921 codecvt_base::result
2922 ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2923 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2924 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2928 if (mode & generate_header)
2930 if (to_end - to_nxt < 2)
2931 return codecvt_base::partial;
2932 *to_nxt++ = static_cast<uint8_t>(0xFF);
2933 *to_nxt++ = static_cast<uint8_t>(0xFE);
2935 for (; frm_nxt < frm_end; ++frm_nxt)
2937 uint32_t wc = *frm_nxt;
2938 if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2939 return codecvt_base::error;
2942 if (to_end-to_nxt < 2)
2943 return codecvt_base::partial;
2944 *to_nxt++ = static_cast<uint8_t>(wc);
2945 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2949 if (to_end-to_nxt < 4)
2950 return codecvt_base::partial;
2951 uint16_t t = static_cast<uint16_t>(
2953 | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2954 | ((wc & 0x00FC00) >> 10));
2955 *to_nxt++ = static_cast<uint8_t>(t);
2956 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2957 t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2958 *to_nxt++ = static_cast<uint8_t>(t);
2959 *to_nxt++ = static_cast<uint8_t>(t >> 8);
2962 return codecvt_base::ok;
2966 codecvt_base::result
2967 utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2968 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2969 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2973 if (mode & consume_header)
2975 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2978 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2980 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2981 if ((c1 & 0xFC00) == 0xDC00)
2982 return codecvt_base::error;
2983 if ((c1 & 0xFC00) != 0xD800)
2986 return codecvt_base::error;
2987 *to_nxt = static_cast<uint32_t>(c1);
2992 if (frm_end-frm_nxt < 4)
2993 return codecvt_base::partial;
2994 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2995 if ((c2 & 0xFC00) != 0xDC00)
2996 return codecvt_base::error;
2997 uint32_t t = static_cast<uint32_t>(
2998 ((((c1 & 0x03C0) >> 6) + 1) << 16)
2999 | ((c1 & 0x003F) << 10)
3002 return codecvt_base::error;
3007 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3012 utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
3013 size_t mx, unsigned long Maxcode = 0x10FFFF,
3014 codecvt_mode mode = codecvt_mode(0))
3016 const uint8_t* frm_nxt = frm;
3017 if (mode & consume_header)
3019 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3022 for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
3024 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3025 if ((c1 & 0xFC00) == 0xDC00)
3027 if ((c1 & 0xFC00) != 0xD800)
3035 if (frm_end-frm_nxt < 4)
3037 uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
3038 if ((c2 & 0xFC00) != 0xDC00)
3040 uint32_t t = static_cast<uint32_t>(
3041 ((((c1 & 0x03C0) >> 6) + 1) << 16)
3042 | ((c1 & 0x003F) << 10)
3049 return static_cast<int>(frm_nxt - frm);
3053 codecvt_base::result
3054 ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3055 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3056 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3060 if (mode & generate_header)
3062 if (to_end-to_nxt < 2)
3063 return codecvt_base::partial;
3064 *to_nxt++ = static_cast<uint8_t>(0xFE);
3065 *to_nxt++ = static_cast<uint8_t>(0xFF);
3067 for (; frm_nxt < frm_end; ++frm_nxt)
3069 uint16_t wc = *frm_nxt;
3070 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3071 return codecvt_base::error;
3072 if (to_end-to_nxt < 2)
3073 return codecvt_base::partial;
3074 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3075 *to_nxt++ = static_cast<uint8_t>(wc);
3077 return codecvt_base::ok;
3081 codecvt_base::result
3082 utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3083 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3084 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3088 if (mode & consume_header)
3090 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3093 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3095 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
3096 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3097 return codecvt_base::error;
3101 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3106 utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3107 size_t mx, unsigned long Maxcode = 0x10FFFF,
3108 codecvt_mode mode = codecvt_mode(0))
3110 const uint8_t* frm_nxt = frm;
3111 if (mode & consume_header)
3113 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3116 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3118 uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
3119 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3123 return static_cast<int>(frm_nxt - frm);
3127 codecvt_base::result
3128 ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3129 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3130 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3134 if (mode & generate_header)
3136 if (to_end-to_nxt < 2)
3137 return codecvt_base::partial;
3138 *to_nxt++ = static_cast<uint8_t>(0xFF);
3139 *to_nxt++ = static_cast<uint8_t>(0xFE);
3141 for (; frm_nxt < frm_end; ++frm_nxt)
3143 uint16_t wc = *frm_nxt;
3144 if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3145 return codecvt_base::error;
3146 if (to_end-to_nxt < 2)
3147 return codecvt_base::partial;
3148 *to_nxt++ = static_cast<uint8_t>(wc);
3149 *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3151 return codecvt_base::ok;
3155 codecvt_base::result
3156 utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3157 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3158 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3162 if (mode & consume_header)
3164 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3167 for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3169 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3170 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3171 return codecvt_base::error;
3175 return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3180 utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3181 size_t mx, unsigned long Maxcode = 0x10FFFF,
3182 codecvt_mode mode = codecvt_mode(0))
3184 const uint8_t* frm_nxt = frm;
3186 if (mode & consume_header)
3188 if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3191 for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3193 uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3194 if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3198 return static_cast<int>(frm_nxt - frm);
3201 _LIBCPP_SUPPRESS_DEPRECATED_POP
3203 // template <> class codecvt<char16_t, char, mbstate_t>
3205 locale::id codecvt<char16_t, char, mbstate_t>::id;
3207 codecvt<char16_t, char, mbstate_t>::~codecvt()
3211 codecvt<char16_t, char, mbstate_t>::result
3212 codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
3213 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3214 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3216 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3217 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3218 const uint16_t* _frm_nxt = _frm;
3219 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3220 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3221 uint8_t* _to_nxt = _to;
3222 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3223 frm_nxt = frm + (_frm_nxt - _frm);
3224 to_nxt = to + (_to_nxt - _to);
3228 codecvt<char16_t, char, mbstate_t>::result
3229 codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
3230 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3231 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3233 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3234 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3235 const uint8_t* _frm_nxt = _frm;
3236 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3237 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3238 uint16_t* _to_nxt = _to;
3239 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3240 frm_nxt = frm + (_frm_nxt - _frm);
3241 to_nxt = to + (_to_nxt - _to);
3245 codecvt<char16_t, char, mbstate_t>::result
3246 codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
3247 extern_type* to, extern_type*, extern_type*& to_nxt) const
3254 codecvt<char16_t, char, mbstate_t>::do_encoding() const noexcept
3260 codecvt<char16_t, char, mbstate_t>::do_always_noconv() const noexcept
3266 codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
3267 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3269 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3270 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3271 return utf8_to_utf16_length(_frm, _frm_end, mx);
3275 codecvt<char16_t, char, mbstate_t>::do_max_length() const noexcept
3280 #ifndef _LIBCPP_HAS_NO_CHAR8_T
3282 // template <> class codecvt<char16_t, char8_t, mbstate_t>
3284 locale::id codecvt<char16_t, char8_t, mbstate_t>::id;
3286 codecvt<char16_t, char8_t, mbstate_t>::~codecvt()
3290 codecvt<char16_t, char8_t, mbstate_t>::result
3291 codecvt<char16_t, char8_t, mbstate_t>::do_out(state_type&,
3292 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3293 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3295 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3296 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3297 const uint16_t* _frm_nxt = _frm;
3298 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3299 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3300 uint8_t* _to_nxt = _to;
3301 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3302 frm_nxt = frm + (_frm_nxt - _frm);
3303 to_nxt = to + (_to_nxt - _to);
3307 codecvt<char16_t, char8_t, mbstate_t>::result
3308 codecvt<char16_t, char8_t, mbstate_t>::do_in(state_type&,
3309 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3310 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3312 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3313 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3314 const uint8_t* _frm_nxt = _frm;
3315 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3316 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3317 uint16_t* _to_nxt = _to;
3318 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3319 frm_nxt = frm + (_frm_nxt - _frm);
3320 to_nxt = to + (_to_nxt - _to);
3324 codecvt<char16_t, char8_t, mbstate_t>::result
3325 codecvt<char16_t, char8_t, mbstate_t>::do_unshift(state_type&,
3326 extern_type* to, extern_type*, extern_type*& to_nxt) const
3333 codecvt<char16_t, char8_t, mbstate_t>::do_encoding() const noexcept
3339 codecvt<char16_t, char8_t, mbstate_t>::do_always_noconv() const noexcept
3345 codecvt<char16_t, char8_t, mbstate_t>::do_length(state_type&,
3346 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3348 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3349 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3350 return utf8_to_utf16_length(_frm, _frm_end, mx);
3354 codecvt<char16_t, char8_t, mbstate_t>::do_max_length() const noexcept
3361 // template <> class codecvt<char32_t, char, mbstate_t>
3363 locale::id codecvt<char32_t, char, mbstate_t>::id;
3365 codecvt<char32_t, char, mbstate_t>::~codecvt()
3369 codecvt<char32_t, char, mbstate_t>::result
3370 codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
3371 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3372 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3374 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3375 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3376 const uint32_t* _frm_nxt = _frm;
3377 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3378 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3379 uint8_t* _to_nxt = _to;
3380 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3381 frm_nxt = frm + (_frm_nxt - _frm);
3382 to_nxt = to + (_to_nxt - _to);
3386 codecvt<char32_t, char, mbstate_t>::result
3387 codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
3388 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3389 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3391 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3392 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3393 const uint8_t* _frm_nxt = _frm;
3394 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3395 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3396 uint32_t* _to_nxt = _to;
3397 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3398 frm_nxt = frm + (_frm_nxt - _frm);
3399 to_nxt = to + (_to_nxt - _to);
3403 codecvt<char32_t, char, mbstate_t>::result
3404 codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3405 extern_type* to, extern_type*, extern_type*& to_nxt) const
3412 codecvt<char32_t, char, mbstate_t>::do_encoding() const noexcept
3418 codecvt<char32_t, char, mbstate_t>::do_always_noconv() const noexcept
3424 codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3425 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3427 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3428 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3429 return utf8_to_ucs4_length(_frm, _frm_end, mx);
3433 codecvt<char32_t, char, mbstate_t>::do_max_length() const noexcept
3438 #ifndef _LIBCPP_HAS_NO_CHAR8_T
3440 // template <> class codecvt<char32_t, char8_t, mbstate_t>
3442 locale::id codecvt<char32_t, char8_t, mbstate_t>::id;
3444 codecvt<char32_t, char8_t, mbstate_t>::~codecvt()
3448 codecvt<char32_t, char8_t, mbstate_t>::result
3449 codecvt<char32_t, char8_t, mbstate_t>::do_out(state_type&,
3450 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3451 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3453 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3454 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3455 const uint32_t* _frm_nxt = _frm;
3456 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3457 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3458 uint8_t* _to_nxt = _to;
3459 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3460 frm_nxt = frm + (_frm_nxt - _frm);
3461 to_nxt = to + (_to_nxt - _to);
3465 codecvt<char32_t, char8_t, mbstate_t>::result
3466 codecvt<char32_t, char8_t, mbstate_t>::do_in(state_type&,
3467 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3468 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3470 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3471 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3472 const uint8_t* _frm_nxt = _frm;
3473 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3474 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3475 uint32_t* _to_nxt = _to;
3476 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3477 frm_nxt = frm + (_frm_nxt - _frm);
3478 to_nxt = to + (_to_nxt - _to);
3482 codecvt<char32_t, char8_t, mbstate_t>::result
3483 codecvt<char32_t, char8_t, mbstate_t>::do_unshift(state_type&,
3484 extern_type* to, extern_type*, extern_type*& to_nxt) const
3491 codecvt<char32_t, char8_t, mbstate_t>::do_encoding() const noexcept
3497 codecvt<char32_t, char8_t, mbstate_t>::do_always_noconv() const noexcept
3503 codecvt<char32_t, char8_t, mbstate_t>::do_length(state_type&,
3504 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3506 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3507 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3508 return utf8_to_ucs4_length(_frm, _frm_end, mx);
3512 codecvt<char32_t, char8_t, mbstate_t>::do_max_length() const noexcept
3519 // __codecvt_utf8<wchar_t>
3521 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3522 __codecvt_utf8<wchar_t>::result
3523 __codecvt_utf8<wchar_t>::do_out(state_type&,
3524 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3525 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3527 #if defined(_LIBCPP_SHORT_WCHAR)
3528 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3529 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3530 const uint16_t* _frm_nxt = _frm;
3532 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3533 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3534 const uint32_t* _frm_nxt = _frm;
3536 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3537 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3538 uint8_t* _to_nxt = _to;
3539 #if defined(_LIBCPP_SHORT_WCHAR)
3540 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3541 __maxcode_, __mode_);
3543 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3544 __maxcode_, __mode_);
3546 frm_nxt = frm + (_frm_nxt - _frm);
3547 to_nxt = to + (_to_nxt - _to);
3551 __codecvt_utf8<wchar_t>::result
3552 __codecvt_utf8<wchar_t>::do_in(state_type&,
3553 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3554 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3556 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3557 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3558 const uint8_t* _frm_nxt = _frm;
3559 #if defined(_LIBCPP_SHORT_WCHAR)
3560 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3561 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3562 uint16_t* _to_nxt = _to;
3563 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3564 __maxcode_, __mode_);
3566 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3567 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3568 uint32_t* _to_nxt = _to;
3569 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3570 __maxcode_, __mode_);
3572 frm_nxt = frm + (_frm_nxt - _frm);
3573 to_nxt = to + (_to_nxt - _to);
3577 __codecvt_utf8<wchar_t>::result
3578 __codecvt_utf8<wchar_t>::do_unshift(state_type&,
3579 extern_type* to, extern_type*, extern_type*& to_nxt) const
3586 __codecvt_utf8<wchar_t>::do_encoding() const noexcept
3592 __codecvt_utf8<wchar_t>::do_always_noconv() const noexcept
3598 __codecvt_utf8<wchar_t>::do_length(state_type&,
3599 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3601 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3602 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3603 #if defined(_LIBCPP_SHORT_WCHAR)
3604 return utf8_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3606 return utf8_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3610 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3612 __codecvt_utf8<wchar_t>::do_max_length() const noexcept
3614 #if defined(_LIBCPP_SHORT_WCHAR)
3615 if (__mode_ & consume_header)
3619 if (__mode_ & consume_header)
3624 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3626 // __codecvt_utf8<char16_t>
3628 __codecvt_utf8<char16_t>::result
3629 __codecvt_utf8<char16_t>::do_out(state_type&,
3630 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3631 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3633 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3634 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3635 const uint16_t* _frm_nxt = _frm;
3636 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3637 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3638 uint8_t* _to_nxt = _to;
3639 result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3640 __maxcode_, __mode_);
3641 frm_nxt = frm + (_frm_nxt - _frm);
3642 to_nxt = to + (_to_nxt - _to);
3646 __codecvt_utf8<char16_t>::result
3647 __codecvt_utf8<char16_t>::do_in(state_type&,
3648 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3649 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3651 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3652 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3653 const uint8_t* _frm_nxt = _frm;
3654 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3655 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3656 uint16_t* _to_nxt = _to;
3657 result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3658 __maxcode_, __mode_);
3659 frm_nxt = frm + (_frm_nxt - _frm);
3660 to_nxt = to + (_to_nxt - _to);
3664 __codecvt_utf8<char16_t>::result
3665 __codecvt_utf8<char16_t>::do_unshift(state_type&,
3666 extern_type* to, extern_type*, extern_type*& to_nxt) const
3673 __codecvt_utf8<char16_t>::do_encoding() const noexcept
3679 __codecvt_utf8<char16_t>::do_always_noconv() const noexcept
3685 __codecvt_utf8<char16_t>::do_length(state_type&,
3686 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3688 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3689 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3690 return utf8_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3693 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3695 __codecvt_utf8<char16_t>::do_max_length() const noexcept
3697 if (__mode_ & consume_header)
3701 _LIBCPP_SUPPRESS_DEPRECATED_POP
3703 // __codecvt_utf8<char32_t>
3705 __codecvt_utf8<char32_t>::result
3706 __codecvt_utf8<char32_t>::do_out(state_type&,
3707 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3708 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3710 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3711 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3712 const uint32_t* _frm_nxt = _frm;
3713 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3714 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3715 uint8_t* _to_nxt = _to;
3716 result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3717 __maxcode_, __mode_);
3718 frm_nxt = frm + (_frm_nxt - _frm);
3719 to_nxt = to + (_to_nxt - _to);
3723 __codecvt_utf8<char32_t>::result
3724 __codecvt_utf8<char32_t>::do_in(state_type&,
3725 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3726 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3728 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3729 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3730 const uint8_t* _frm_nxt = _frm;
3731 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3732 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3733 uint32_t* _to_nxt = _to;
3734 result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3735 __maxcode_, __mode_);
3736 frm_nxt = frm + (_frm_nxt - _frm);
3737 to_nxt = to + (_to_nxt - _to);
3741 __codecvt_utf8<char32_t>::result
3742 __codecvt_utf8<char32_t>::do_unshift(state_type&,
3743 extern_type* to, extern_type*, extern_type*& to_nxt) const
3750 __codecvt_utf8<char32_t>::do_encoding() const noexcept
3756 __codecvt_utf8<char32_t>::do_always_noconv() const noexcept
3762 __codecvt_utf8<char32_t>::do_length(state_type&,
3763 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3765 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3766 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3767 return utf8_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3770 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
3772 __codecvt_utf8<char32_t>::do_max_length() const noexcept
3774 if (__mode_ & consume_header)
3778 _LIBCPP_SUPPRESS_DEPRECATED_POP
3780 // __codecvt_utf16<wchar_t, false>
3782 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
3783 __codecvt_utf16<wchar_t, false>::result
3784 __codecvt_utf16<wchar_t, false>::do_out(state_type&,
3785 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3786 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3788 #if defined(_LIBCPP_SHORT_WCHAR)
3789 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3790 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3791 const uint16_t* _frm_nxt = _frm;
3793 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3794 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3795 const uint32_t* _frm_nxt = _frm;
3797 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3798 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3799 uint8_t* _to_nxt = _to;
3800 #if defined(_LIBCPP_SHORT_WCHAR)
3801 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3802 __maxcode_, __mode_);
3804 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3805 __maxcode_, __mode_);
3807 frm_nxt = frm + (_frm_nxt - _frm);
3808 to_nxt = to + (_to_nxt - _to);
3812 __codecvt_utf16<wchar_t, false>::result
3813 __codecvt_utf16<wchar_t, false>::do_in(state_type&,
3814 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3815 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3817 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3818 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3819 const uint8_t* _frm_nxt = _frm;
3820 #if defined(_LIBCPP_SHORT_WCHAR)
3821 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3822 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3823 uint16_t* _to_nxt = _to;
3824 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3825 __maxcode_, __mode_);
3827 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3828 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3829 uint32_t* _to_nxt = _to;
3830 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3831 __maxcode_, __mode_);
3833 frm_nxt = frm + (_frm_nxt - _frm);
3834 to_nxt = to + (_to_nxt - _to);
3838 __codecvt_utf16<wchar_t, false>::result
3839 __codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3840 extern_type* to, extern_type*, extern_type*& to_nxt) const
3847 __codecvt_utf16<wchar_t, false>::do_encoding() const noexcept
3853 __codecvt_utf16<wchar_t, false>::do_always_noconv() const noexcept
3859 __codecvt_utf16<wchar_t, false>::do_length(state_type&,
3860 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3862 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3863 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3864 #if defined(_LIBCPP_SHORT_WCHAR)
3865 return utf16be_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3867 return utf16be_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3872 __codecvt_utf16<wchar_t, false>::do_max_length() const noexcept
3874 #if defined(_LIBCPP_SHORT_WCHAR)
3875 if (__mode_ & consume_header)
3879 if (__mode_ & consume_header)
3885 // __codecvt_utf16<wchar_t, true>
3887 __codecvt_utf16<wchar_t, true>::result
3888 __codecvt_utf16<wchar_t, true>::do_out(state_type&,
3889 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3890 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3892 #if defined(_LIBCPP_SHORT_WCHAR)
3893 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3894 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3895 const uint16_t* _frm_nxt = _frm;
3897 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3898 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3899 const uint32_t* _frm_nxt = _frm;
3901 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3902 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3903 uint8_t* _to_nxt = _to;
3904 #if defined(_LIBCPP_SHORT_WCHAR)
3905 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3906 __maxcode_, __mode_);
3908 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3909 __maxcode_, __mode_);
3911 frm_nxt = frm + (_frm_nxt - _frm);
3912 to_nxt = to + (_to_nxt - _to);
3916 __codecvt_utf16<wchar_t, true>::result
3917 __codecvt_utf16<wchar_t, true>::do_in(state_type&,
3918 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3919 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3921 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3922 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3923 const uint8_t* _frm_nxt = _frm;
3924 #if defined(_LIBCPP_SHORT_WCHAR)
3925 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3926 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3927 uint16_t* _to_nxt = _to;
3928 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3929 __maxcode_, __mode_);
3931 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3932 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3933 uint32_t* _to_nxt = _to;
3934 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3935 __maxcode_, __mode_);
3937 frm_nxt = frm + (_frm_nxt - _frm);
3938 to_nxt = to + (_to_nxt - _to);
3942 __codecvt_utf16<wchar_t, true>::result
3943 __codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3944 extern_type* to, extern_type*, extern_type*& to_nxt) const
3951 __codecvt_utf16<wchar_t, true>::do_encoding() const noexcept
3957 __codecvt_utf16<wchar_t, true>::do_always_noconv() const noexcept
3963 __codecvt_utf16<wchar_t, true>::do_length(state_type&,
3964 const extern_type* frm, const extern_type* frm_end, size_t mx) const
3966 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3967 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3968 #if defined(_LIBCPP_SHORT_WCHAR)
3969 return utf16le_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3971 return utf16le_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
3976 __codecvt_utf16<wchar_t, true>::do_max_length() const noexcept
3978 #if defined(_LIBCPP_SHORT_WCHAR)
3979 if (__mode_ & consume_header)
3983 if (__mode_ & consume_header)
3988 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
3990 // __codecvt_utf16<char16_t, false>
3992 __codecvt_utf16<char16_t, false>::result
3993 __codecvt_utf16<char16_t, false>::do_out(state_type&,
3994 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3995 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3997 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3998 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3999 const uint16_t* _frm_nxt = _frm;
4000 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4001 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4002 uint8_t* _to_nxt = _to;
4003 result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4004 __maxcode_, __mode_);
4005 frm_nxt = frm + (_frm_nxt - _frm);
4006 to_nxt = to + (_to_nxt - _to);
4010 __codecvt_utf16<char16_t, false>::result
4011 __codecvt_utf16<char16_t, false>::do_in(state_type&,
4012 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4013 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4015 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4016 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4017 const uint8_t* _frm_nxt = _frm;
4018 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4019 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4020 uint16_t* _to_nxt = _to;
4021 result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4022 __maxcode_, __mode_);
4023 frm_nxt = frm + (_frm_nxt - _frm);
4024 to_nxt = to + (_to_nxt - _to);
4028 __codecvt_utf16<char16_t, false>::result
4029 __codecvt_utf16<char16_t, false>::do_unshift(state_type&,
4030 extern_type* to, extern_type*, extern_type*& to_nxt) const
4037 __codecvt_utf16<char16_t, false>::do_encoding() const noexcept
4043 __codecvt_utf16<char16_t, false>::do_always_noconv() const noexcept
4049 __codecvt_utf16<char16_t, false>::do_length(state_type&,
4050 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4052 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4053 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4054 return utf16be_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
4057 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4059 __codecvt_utf16<char16_t, false>::do_max_length() const noexcept
4061 if (__mode_ & consume_header)
4065 _LIBCPP_SUPPRESS_DEPRECATED_POP
4067 // __codecvt_utf16<char16_t, true>
4069 __codecvt_utf16<char16_t, true>::result
4070 __codecvt_utf16<char16_t, true>::do_out(state_type&,
4071 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4072 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4074 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4075 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4076 const uint16_t* _frm_nxt = _frm;
4077 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4078 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4079 uint8_t* _to_nxt = _to;
4080 result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4081 __maxcode_, __mode_);
4082 frm_nxt = frm + (_frm_nxt - _frm);
4083 to_nxt = to + (_to_nxt - _to);
4087 __codecvt_utf16<char16_t, true>::result
4088 __codecvt_utf16<char16_t, true>::do_in(state_type&,
4089 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4090 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4092 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4093 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4094 const uint8_t* _frm_nxt = _frm;
4095 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4096 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4097 uint16_t* _to_nxt = _to;
4098 result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4099 __maxcode_, __mode_);
4100 frm_nxt = frm + (_frm_nxt - _frm);
4101 to_nxt = to + (_to_nxt - _to);
4105 __codecvt_utf16<char16_t, true>::result
4106 __codecvt_utf16<char16_t, true>::do_unshift(state_type&,
4107 extern_type* to, extern_type*, extern_type*& to_nxt) const
4114 __codecvt_utf16<char16_t, true>::do_encoding() const noexcept
4120 __codecvt_utf16<char16_t, true>::do_always_noconv() const noexcept
4126 __codecvt_utf16<char16_t, true>::do_length(state_type&,
4127 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4129 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4130 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4131 return utf16le_to_ucs2_length(_frm, _frm_end, mx, __maxcode_, __mode_);
4134 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4136 __codecvt_utf16<char16_t, true>::do_max_length() const noexcept
4138 if (__mode_ & consume_header)
4142 _LIBCPP_SUPPRESS_DEPRECATED_POP
4144 // __codecvt_utf16<char32_t, false>
4146 __codecvt_utf16<char32_t, false>::result
4147 __codecvt_utf16<char32_t, false>::do_out(state_type&,
4148 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4149 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4151 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4152 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4153 const uint32_t* _frm_nxt = _frm;
4154 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4155 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4156 uint8_t* _to_nxt = _to;
4157 result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4158 __maxcode_, __mode_);
4159 frm_nxt = frm + (_frm_nxt - _frm);
4160 to_nxt = to + (_to_nxt - _to);
4164 __codecvt_utf16<char32_t, false>::result
4165 __codecvt_utf16<char32_t, false>::do_in(state_type&,
4166 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4167 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4169 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4170 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4171 const uint8_t* _frm_nxt = _frm;
4172 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4173 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4174 uint32_t* _to_nxt = _to;
4175 result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4176 __maxcode_, __mode_);
4177 frm_nxt = frm + (_frm_nxt - _frm);
4178 to_nxt = to + (_to_nxt - _to);
4182 __codecvt_utf16<char32_t, false>::result
4183 __codecvt_utf16<char32_t, false>::do_unshift(state_type&,
4184 extern_type* to, extern_type*, extern_type*& to_nxt) const
4191 __codecvt_utf16<char32_t, false>::do_encoding() const noexcept
4197 __codecvt_utf16<char32_t, false>::do_always_noconv() const noexcept
4203 __codecvt_utf16<char32_t, false>::do_length(state_type&,
4204 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4206 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4207 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4208 return utf16be_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
4211 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4213 __codecvt_utf16<char32_t, false>::do_max_length() const noexcept
4215 if (__mode_ & consume_header)
4219 _LIBCPP_SUPPRESS_DEPRECATED_POP
4221 // __codecvt_utf16<char32_t, true>
4223 __codecvt_utf16<char32_t, true>::result
4224 __codecvt_utf16<char32_t, true>::do_out(state_type&,
4225 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4226 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4228 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4229 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4230 const uint32_t* _frm_nxt = _frm;
4231 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4232 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4233 uint8_t* _to_nxt = _to;
4234 result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4235 __maxcode_, __mode_);
4236 frm_nxt = frm + (_frm_nxt - _frm);
4237 to_nxt = to + (_to_nxt - _to);
4241 __codecvt_utf16<char32_t, true>::result
4242 __codecvt_utf16<char32_t, true>::do_in(state_type&,
4243 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4244 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4246 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4247 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4248 const uint8_t* _frm_nxt = _frm;
4249 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4250 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4251 uint32_t* _to_nxt = _to;
4252 result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4253 __maxcode_, __mode_);
4254 frm_nxt = frm + (_frm_nxt - _frm);
4255 to_nxt = to + (_to_nxt - _to);
4259 __codecvt_utf16<char32_t, true>::result
4260 __codecvt_utf16<char32_t, true>::do_unshift(state_type&,
4261 extern_type* to, extern_type*, extern_type*& to_nxt) const
4268 __codecvt_utf16<char32_t, true>::do_encoding() const noexcept
4274 __codecvt_utf16<char32_t, true>::do_always_noconv() const noexcept
4280 __codecvt_utf16<char32_t, true>::do_length(state_type&,
4281 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4283 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4284 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4285 return utf16le_to_ucs4_length(_frm, _frm_end, mx, __maxcode_, __mode_);
4288 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4290 __codecvt_utf16<char32_t, true>::do_max_length() const noexcept
4292 if (__mode_ & consume_header)
4296 _LIBCPP_SUPPRESS_DEPRECATED_POP
4298 // __codecvt_utf8_utf16<wchar_t>
4300 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4301 __codecvt_utf8_utf16<wchar_t>::result
4302 __codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
4303 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4304 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4306 #if defined(_LIBCPP_SHORT_WCHAR)
4307 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4308 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4309 const uint16_t* _frm_nxt = _frm;
4311 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4312 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4313 const uint32_t* _frm_nxt = _frm;
4315 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4316 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4317 uint8_t* _to_nxt = _to;
4318 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4319 __maxcode_, __mode_);
4320 frm_nxt = frm + (_frm_nxt - _frm);
4321 to_nxt = to + (_to_nxt - _to);
4325 __codecvt_utf8_utf16<wchar_t>::result
4326 __codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
4327 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4328 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4330 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4331 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4332 const uint8_t* _frm_nxt = _frm;
4333 #if defined(_LIBCPP_SHORT_WCHAR)
4334 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4335 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4336 uint16_t* _to_nxt = _to;
4338 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4339 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4340 uint32_t* _to_nxt = _to;
4342 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4343 __maxcode_, __mode_);
4344 frm_nxt = frm + (_frm_nxt - _frm);
4345 to_nxt = to + (_to_nxt - _to);
4349 __codecvt_utf8_utf16<wchar_t>::result
4350 __codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
4351 extern_type* to, extern_type*, extern_type*& to_nxt) const
4358 __codecvt_utf8_utf16<wchar_t>::do_encoding() const noexcept
4364 __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const noexcept
4370 __codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
4371 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4373 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4374 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4375 return utf8_to_utf16_length(_frm, _frm_end, mx, __maxcode_, __mode_);
4379 __codecvt_utf8_utf16<wchar_t>::do_max_length() const noexcept
4381 if (__mode_ & consume_header)
4385 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4387 // __codecvt_utf8_utf16<char16_t>
4389 __codecvt_utf8_utf16<char16_t>::result
4390 __codecvt_utf8_utf16<char16_t>::do_out(state_type&,
4391 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4392 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4394 const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4395 const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4396 const uint16_t* _frm_nxt = _frm;
4397 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4398 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4399 uint8_t* _to_nxt = _to;
4400 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4401 __maxcode_, __mode_);
4402 frm_nxt = frm + (_frm_nxt - _frm);
4403 to_nxt = to + (_to_nxt - _to);
4407 __codecvt_utf8_utf16<char16_t>::result
4408 __codecvt_utf8_utf16<char16_t>::do_in(state_type&,
4409 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4410 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4412 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4413 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4414 const uint8_t* _frm_nxt = _frm;
4415 uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4416 uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4417 uint16_t* _to_nxt = _to;
4418 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4419 __maxcode_, __mode_);
4420 frm_nxt = frm + (_frm_nxt - _frm);
4421 to_nxt = to + (_to_nxt - _to);
4425 __codecvt_utf8_utf16<char16_t>::result
4426 __codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
4427 extern_type* to, extern_type*, extern_type*& to_nxt) const
4434 __codecvt_utf8_utf16<char16_t>::do_encoding() const noexcept
4440 __codecvt_utf8_utf16<char16_t>::do_always_noconv() const noexcept
4446 __codecvt_utf8_utf16<char16_t>::do_length(state_type&,
4447 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4449 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4450 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4451 return utf8_to_utf16_length(_frm, _frm_end, mx, __maxcode_, __mode_);
4454 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4456 __codecvt_utf8_utf16<char16_t>::do_max_length() const noexcept
4458 if (__mode_ & consume_header)
4462 _LIBCPP_SUPPRESS_DEPRECATED_POP
4464 // __codecvt_utf8_utf16<char32_t>
4466 __codecvt_utf8_utf16<char32_t>::result
4467 __codecvt_utf8_utf16<char32_t>::do_out(state_type&,
4468 const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4469 extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4471 const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4472 const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4473 const uint32_t* _frm_nxt = _frm;
4474 uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4475 uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4476 uint8_t* _to_nxt = _to;
4477 result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4478 __maxcode_, __mode_);
4479 frm_nxt = frm + (_frm_nxt - _frm);
4480 to_nxt = to + (_to_nxt - _to);
4484 __codecvt_utf8_utf16<char32_t>::result
4485 __codecvt_utf8_utf16<char32_t>::do_in(state_type&,
4486 const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4487 intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4489 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4490 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4491 const uint8_t* _frm_nxt = _frm;
4492 uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4493 uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4494 uint32_t* _to_nxt = _to;
4495 result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4496 __maxcode_, __mode_);
4497 frm_nxt = frm + (_frm_nxt - _frm);
4498 to_nxt = to + (_to_nxt - _to);
4502 __codecvt_utf8_utf16<char32_t>::result
4503 __codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
4504 extern_type* to, extern_type*, extern_type*& to_nxt) const
4511 __codecvt_utf8_utf16<char32_t>::do_encoding() const noexcept
4517 __codecvt_utf8_utf16<char32_t>::do_always_noconv() const noexcept
4523 __codecvt_utf8_utf16<char32_t>::do_length(state_type&,
4524 const extern_type* frm, const extern_type* frm_end, size_t mx) const
4526 const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4527 const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4528 return utf8_to_utf16_length(_frm, _frm_end, mx, __maxcode_, __mode_);
4531 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
4533 __codecvt_utf8_utf16<char32_t>::do_max_length() const noexcept
4535 if (__mode_ & consume_header)
4539 _LIBCPP_SUPPRESS_DEPRECATED_POP
4541 // __narrow_to_utf8<16>
4543 __narrow_to_utf8<16>::~__narrow_to_utf8()
4547 // __narrow_to_utf8<32>
4549 __narrow_to_utf8<32>::~__narrow_to_utf8()
4553 // __widen_from_utf8<16>
4555 __widen_from_utf8<16>::~__widen_from_utf8()
4559 // __widen_from_utf8<32>
4561 __widen_from_utf8<32>::~__widen_from_utf8()
4565 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4566 static bool checked_string_to_wchar_convert(wchar_t& dest,
4573 size_t ret = __libcpp_mbrtowc_l(&out, ptr, strlen(ptr), &mb, loc);
4574 if (ret == static_cast<size_t>(-1) || ret == static_cast<size_t>(-2)) {
4580 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4582 #ifdef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4583 static bool is_narrow_non_breaking_space(const char* ptr) {
4584 // https://www.fileformat.info/info/unicode/char/202f/index.htm
4585 return ptr[0] == '\xe2' && ptr[1] == '\x80' && ptr[2] == '\xaf';
4588 static bool is_non_breaking_space(const char* ptr) {
4589 // https://www.fileformat.info/info/unicode/char/0a/index.htm
4590 return ptr[0] == '\xc2' && ptr[1] == '\xa0';
4592 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4594 static bool checked_string_to_char_convert(char& dest,
4604 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4605 // First convert the MBS into a wide char then attempt to narrow it using
4608 if (!checked_string_to_wchar_convert(wout, ptr, __loc))
4611 if ((res = __libcpp_wctob_l(wout, __loc)) != char_traits<char>::eof()) {
4615 // FIXME: Work around specific multibyte sequences that we can reasonably
4616 // translate into a different single byte.
4618 case L'\u202F': // narrow non-breaking space
4619 case L'\u00A0': // non-breaking space
4625 #else // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4626 // FIXME: Work around specific multibyte sequences that we can reasonably
4627 // translate into a different single byte.
4628 if (is_narrow_non_breaking_space(ptr) || is_non_breaking_space(ptr)) {
4634 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4635 __libcpp_unreachable();
4639 // numpunct<char> && numpunct<wchar_t>
4641 locale::id numpunct< char >::id;
4642 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4643 locale::id numpunct<wchar_t>::id;
4646 numpunct<char>::numpunct(size_t refs)
4647 : locale::facet(refs),
4648 __decimal_point_('.'),
4649 __thousands_sep_(',')
4653 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4654 numpunct<wchar_t>::numpunct(size_t refs)
4655 : locale::facet(refs),
4656 __decimal_point_(L'.'),
4657 __thousands_sep_(L',')
4662 numpunct<char>::~numpunct()
4666 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4667 numpunct<wchar_t>::~numpunct()
4672 char numpunct< char >::do_decimal_point() const {return __decimal_point_;}
4673 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4674 wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
4677 char numpunct< char >::do_thousands_sep() const {return __thousands_sep_;}
4678 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4679 wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
4682 string numpunct< char >::do_grouping() const {return __grouping_;}
4683 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4684 string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
4687 string numpunct< char >::do_truename() const {return "true";}
4688 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4689 wstring numpunct<wchar_t>::do_truename() const {return L"true";}
4692 string numpunct< char >::do_falsename() const {return "false";}
4693 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4694 wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
4697 // numpunct_byname<char>
4699 numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4700 : numpunct<char>(refs)
4705 numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4706 : numpunct<char>(refs)
4711 numpunct_byname<char>::~numpunct_byname()
4716 numpunct_byname<char>::__init(const char* nm)
4718 typedef numpunct<char> base;
4719 if (strcmp(nm, "C") != 0)
4721 __libcpp_unique_locale loc(nm);
4723 __throw_runtime_error("numpunct_byname<char>::numpunct_byname"
4724 " failed to construct for " + string(nm));
4726 lconv* lc = __libcpp_localeconv_l(loc.get());
4727 if (!checked_string_to_char_convert(__decimal_point_, lc->decimal_point,
4729 __decimal_point_ = base::do_decimal_point();
4730 if (!checked_string_to_char_convert(__thousands_sep_, lc->thousands_sep,
4732 __thousands_sep_ = base::do_thousands_sep();
4733 __grouping_ = lc->grouping;
4734 // localization for truename and falsename is not available
4738 // numpunct_byname<wchar_t>
4740 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4741 numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4742 : numpunct<wchar_t>(refs)
4747 numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4748 : numpunct<wchar_t>(refs)
4753 numpunct_byname<wchar_t>::~numpunct_byname()
4758 numpunct_byname<wchar_t>::__init(const char* nm)
4760 if (strcmp(nm, "C") != 0)
4762 __libcpp_unique_locale loc(nm);
4764 __throw_runtime_error("numpunct_byname<wchar_t>::numpunct_byname"
4765 " failed to construct for " + string(nm));
4767 lconv* lc = __libcpp_localeconv_l(loc.get());
4768 checked_string_to_wchar_convert(__decimal_point_, lc->decimal_point,
4770 checked_string_to_wchar_convert(__thousands_sep_, lc->thousands_sep,
4772 __grouping_ = lc->grouping;
4773 // localization for truename and falsename is not available
4776 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
4781 __num_get_base::__get_base(ios_base& iob)
4783 ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4784 if (__basefield == ios_base::oct)
4786 else if (__basefield == ios_base::hex)
4788 else if (__basefield == 0)
4793 const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4796 __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4797 ios_base::iostate& __err)
4799 // if the grouping pattern is empty _or_ there are no grouping bits, then do nothing
4800 // we always have at least a single entry in [__g, __g_end); the end of the input sequence
4801 if (__grouping.size() != 0 && __g_end - __g > 1)
4803 reverse(__g, __g_end);
4804 const char* __ig = __grouping.data();
4805 const char* __eg = __ig + __grouping.size();
4806 for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4808 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4810 if (static_cast<unsigned>(*__ig) != *__r)
4812 __err = ios_base::failbit;
4816 if (__eg - __ig > 1)
4819 if (0 < *__ig && *__ig < numeric_limits<char>::max())
4821 if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
4822 __err = ios_base::failbit;
4828 __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4829 ios_base::fmtflags __flags)
4831 if ((__flags & ios_base::showpos) &&
4832 (__flags & ios_base::basefield) != ios_base::oct &&
4833 (__flags & ios_base::basefield) != ios_base::hex &&
4836 if (__flags & ios_base::showbase)
4839 *__fmtp++ = *__len++;
4840 if ((__flags & ios_base::basefield) == ios_base::oct)
4842 else if ((__flags & ios_base::basefield) == ios_base::hex)
4844 if (__flags & ios_base::uppercase)
4856 __num_put_base::__format_float(char* __fmtp, const char* __len,
4857 ios_base::fmtflags __flags)
4859 bool specify_precision = true;
4860 if (__flags & ios_base::showpos)
4862 if (__flags & ios_base::showpoint)
4864 ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4865 bool uppercase = (__flags & ios_base::uppercase) != 0;
4866 if (floatfield == (ios_base::fixed | ios_base::scientific))
4867 specify_precision = false;
4874 *__fmtp++ = *__len++;
4875 if (floatfield == ios_base::fixed)
4882 else if (floatfield == ios_base::scientific)
4889 else if (floatfield == (ios_base::fixed | ios_base::scientific))
4903 return specify_precision;
4907 __num_put_base::__identify_padding(char* __nb, char* __ne,
4908 const ios_base& __iob)
4910 switch (__iob.flags() & ios_base::adjustfield)
4912 case ios_base::internal:
4913 if (__nb[0] == '-' || __nb[0] == '+')
4915 if (__ne - __nb >= 2 && __nb[0] == '0'
4916 && (__nb[1] == 'x' || __nb[1] == 'X'))
4919 case ios_base::left:
4921 case ios_base::right:
4934 static string weeks[14];
4935 weeks[0] = "Sunday";
4936 weeks[1] = "Monday";
4937 weeks[2] = "Tuesday";
4938 weeks[3] = "Wednesday";
4939 weeks[4] = "Thursday";
4940 weeks[5] = "Friday";
4941 weeks[6] = "Saturday";
4952 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4957 static wstring weeks[14];
4958 weeks[0] = L"Sunday";
4959 weeks[1] = L"Monday";
4960 weeks[2] = L"Tuesday";
4961 weeks[3] = L"Wednesday";
4962 weeks[4] = L"Thursday";
4963 weeks[5] = L"Friday";
4964 weeks[6] = L"Saturday";
4978 __time_get_c_storage<char>::__weeks() const
4980 static const string* weeks = init_weeks();
4984 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
4987 __time_get_c_storage<wchar_t>::__weeks() const
4989 static const wstring* weeks = init_wweeks();
4998 static string months[24];
4999 months[0] = "January";
5000 months[1] = "February";
5001 months[2] = "March";
5002 months[3] = "April";
5006 months[7] = "August";
5007 months[8] = "September";
5008 months[9] = "October";
5009 months[10] = "November";
5010 months[11] = "December";
5026 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5031 static wstring months[24];
5032 months[0] = L"January";
5033 months[1] = L"February";
5034 months[2] = L"March";
5035 months[3] = L"April";
5037 months[5] = L"June";
5038 months[6] = L"July";
5039 months[7] = L"August";
5040 months[8] = L"September";
5041 months[9] = L"October";
5042 months[10] = L"November";
5043 months[11] = L"December";
5044 months[12] = L"Jan";
5045 months[13] = L"Feb";
5046 months[14] = L"Mar";
5047 months[15] = L"Apr";
5048 months[16] = L"May";
5049 months[17] = L"Jun";
5050 months[18] = L"Jul";
5051 months[19] = L"Aug";
5052 months[20] = L"Sep";
5053 months[21] = L"Oct";
5054 months[22] = L"Nov";
5055 months[23] = L"Dec";
5062 __time_get_c_storage<char>::__months() const
5064 static const string* months = init_months();
5068 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5071 __time_get_c_storage<wchar_t>::__months() const
5073 static const wstring* months = init_wmonths();
5082 static string am_pm[2];
5088 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5093 static wstring am_pm[2];
5102 __time_get_c_storage<char>::__am_pm() const
5104 static const string* am_pm = init_am_pm();
5108 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5111 __time_get_c_storage<wchar_t>::__am_pm() const
5113 static const wstring* am_pm = init_wam_pm();
5120 __time_get_c_storage<char>::__x() const
5122 static string s("%m/%d/%y");
5126 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5129 __time_get_c_storage<wchar_t>::__x() const
5131 static wstring s(L"%m/%d/%y");
5138 __time_get_c_storage<char>::__X() const
5140 static string s("%H:%M:%S");
5144 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5147 __time_get_c_storage<wchar_t>::__X() const
5149 static wstring s(L"%H:%M:%S");
5156 __time_get_c_storage<char>::__c() const
5158 static string s("%a %b %d %H:%M:%S %Y");
5162 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5165 __time_get_c_storage<wchar_t>::__c() const
5167 static wstring s(L"%a %b %d %H:%M:%S %Y");
5174 __time_get_c_storage<char>::__r() const
5176 static string s("%I:%M:%S %p");
5180 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5183 __time_get_c_storage<wchar_t>::__r() const
5185 static wstring s(L"%I:%M:%S %p");
5192 __time_get::__time_get(const char* nm)
5193 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5196 __throw_runtime_error("time_get_byname"
5197 " failed to construct for " + string(nm));
5200 __time_get::__time_get(const string& nm)
5201 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5204 __throw_runtime_error("time_get_byname"
5205 " failed to construct for " + nm);
5208 __time_get::~__time_get()
5213 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-field-initializers")
5217 __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
5233 size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);
5239 if (ct.is(ctype_base::space, *bb))
5241 result.push_back(' ');
5242 for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
5247 ios_base::iostate err = ios_base::goodbit;
5248 ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
5253 result.push_back('%');
5255 result.push_back('A');
5257 result.push_back('a');
5262 i = __scan_keyword(w, be, this->__months_, this->__months_+24,
5267 result.push_back('%');
5269 result.push_back('B');
5271 result.push_back('b');
5272 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
5273 result.back() = 'm';
5277 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
5280 i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
5281 ct, err, false) - this->__am_pm_;
5284 result.push_back('%');
5285 result.push_back('p');
5291 if (ct.is(ctype_base::digit, *bb))
5293 switch(__get_up_to_n_digits(bb, be, err, ct, 4))
5296 result.push_back('%');
5297 result.push_back('w');
5300 result.push_back('%');
5301 result.push_back('u');
5304 result.push_back('%');
5305 result.push_back('I');
5308 result.push_back('%');
5309 result.push_back('m');
5312 result.push_back('%');
5313 result.push_back('H');
5316 result.push_back('%');
5317 result.push_back('d');
5320 result.push_back('%');
5321 result.push_back('M');
5324 result.push_back('%');
5325 result.push_back('S');
5328 result.push_back('%');
5329 result.push_back('y');
5332 result.push_back('%');
5333 result.push_back('j');
5336 result.push_back('%');
5337 result.push_back('Y');
5340 for (; w != bb; ++w)
5341 result.push_back(*w);
5348 result.push_back('%');
5349 result.push_back('%');
5353 result.push_back(*bb);
5359 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wmissing-braces")
5361 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5364 __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
5380 strftime_l(buf, countof(buf), f, &t, __loc_);
5382 wchar_t* wbb = wbuf;
5384 const char* bb = buf;
5385 size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
5386 if (j == size_t(-1))
5387 __throw_runtime_error("locale not supported");
5388 wchar_t* wbe = wbb + j;
5392 if (ct.is(ctype_base::space, *wbb))
5394 result.push_back(L' ');
5395 for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
5400 ios_base::iostate err = ios_base::goodbit;
5401 ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
5406 result.push_back(L'%');
5408 result.push_back(L'A');
5410 result.push_back(L'a');
5415 i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
5420 result.push_back(L'%');
5422 result.push_back(L'B');
5424 result.push_back(L'b');
5425 if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
5426 result.back() = L'm';
5430 if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
5433 i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
5434 ct, err, false) - this->__am_pm_;
5437 result.push_back(L'%');
5438 result.push_back(L'p');
5444 if (ct.is(ctype_base::digit, *wbb))
5446 switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
5449 result.push_back(L'%');
5450 result.push_back(L'w');
5453 result.push_back(L'%');
5454 result.push_back(L'u');
5457 result.push_back(L'%');
5458 result.push_back(L'I');
5461 result.push_back(L'%');
5462 result.push_back(L'm');
5465 result.push_back(L'%');
5466 result.push_back(L'H');
5469 result.push_back(L'%');
5470 result.push_back(L'd');
5473 result.push_back(L'%');
5474 result.push_back(L'M');
5477 result.push_back(L'%');
5478 result.push_back(L'S');
5481 result.push_back(L'%');
5482 result.push_back(L'y');
5485 result.push_back(L'%');
5486 result.push_back(L'j');
5489 result.push_back(L'%');
5490 result.push_back(L'Y');
5493 for (; w != wbb; ++w)
5494 result.push_back(*w);
5499 if (ct.narrow(*wbb, 0) == '%')
5501 result.push_back(L'%');
5502 result.push_back(L'%');
5506 result.push_back(*wbb);
5511 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5515 __time_get_storage<char>::init(const ctype<char>& ct)
5520 for (int i = 0; i < 7; ++i)
5523 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5525 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5526 __weeks_[i+7] = buf;
5529 for (int i = 0; i < 12; ++i)
5532 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5534 strftime_l(buf, countof(buf), "%b", &t, __loc_);
5535 __months_[i+12] = buf;
5539 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5542 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5544 __c_ = __analyze('c', ct);
5545 __r_ = __analyze('r', ct);
5546 __x_ = __analyze('x', ct);
5547 __X_ = __analyze('X', ct);
5550 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5553 __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
5561 for (int i = 0; i < 7; ++i)
5564 strftime_l(buf, countof(buf), "%A", &t, __loc_);
5566 const char* bb = buf;
5567 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5568 if (j == size_t(-1) || j == 0)
5569 __throw_runtime_error("locale not supported");
5571 __weeks_[i].assign(wbuf, wbe);
5572 strftime_l(buf, countof(buf), "%a", &t, __loc_);
5575 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5576 if (j == size_t(-1) || j == 0)
5577 __throw_runtime_error("locale not supported");
5579 __weeks_[i+7].assign(wbuf, wbe);
5582 for (int i = 0; i < 12; ++i)
5585 strftime_l(buf, countof(buf), "%B", &t, __loc_);
5587 const char* bb = buf;
5588 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5589 if (j == size_t(-1) || j == 0)
5590 __throw_runtime_error("locale not supported");
5592 __months_[i].assign(wbuf, wbe);
5593 strftime_l(buf, countof(buf), "%b", &t, __loc_);
5596 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5597 if (j == size_t(-1) || j == 0)
5598 __throw_runtime_error("locale not supported");
5600 __months_[i+12].assign(wbuf, wbe);
5604 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5606 const char* bb = buf;
5607 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5608 if (j == size_t(-1))
5609 __throw_runtime_error("locale not supported");
5611 __am_pm_[0].assign(wbuf, wbe);
5613 strftime_l(buf, countof(buf), "%p", &t, __loc_);
5616 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5617 if (j == size_t(-1))
5618 __throw_runtime_error("locale not supported");
5620 __am_pm_[1].assign(wbuf, wbe);
5621 __c_ = __analyze('c', ct);
5622 __r_ = __analyze('r', ct);
5623 __x_ = __analyze('x', ct);
5624 __X_ = __analyze('X', ct);
5626 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5628 template <class CharT>
5629 struct _LIBCPP_HIDDEN __time_get_temp
5630 : public ctype_byname<CharT>
5632 explicit __time_get_temp(const char* nm)
5633 : ctype_byname<CharT>(nm, 1) {}
5634 explicit __time_get_temp(const string& nm)
5635 : ctype_byname<CharT>(nm, 1) {}
5639 __time_get_storage<char>::__time_get_storage(const char* __nm)
5642 const __time_get_temp<char> ct(__nm);
5647 __time_get_storage<char>::__time_get_storage(const string& __nm)
5650 const __time_get_temp<char> ct(__nm);
5654 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5656 __time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5659 const __time_get_temp<wchar_t> ct(__nm);
5664 __time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5667 const __time_get_temp<wchar_t> ct(__nm);
5670 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5673 time_base::dateorder
5674 __time_get_storage<char>::__do_date_order() const
5677 for (i = 0; i < __x_.size(); ++i)
5685 for (++i; i < __x_.size(); ++i)
5688 if (i == __x_.size())
5694 for (++i; i < __x_.size(); ++i)
5697 if (i == __x_.size())
5701 return time_base::ymd;
5704 for (++i; i < __x_.size(); ++i)
5707 if (i == __x_.size())
5711 return time_base::ydm;
5716 for (++i; i < __x_.size(); ++i)
5719 if (i == __x_.size())
5724 for (++i; i < __x_.size(); ++i)
5727 if (i == __x_.size())
5730 if (__x_[i] == 'y' || __x_[i] == 'Y')
5731 return time_base::mdy;
5736 for (++i; i < __x_.size(); ++i)
5739 if (i == __x_.size())
5744 for (++i; i < __x_.size(); ++i)
5747 if (i == __x_.size())
5750 if (__x_[i] == 'y' || __x_[i] == 'Y')
5751 return time_base::dmy;
5756 return time_base::no_order;
5759 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5761 time_base::dateorder
5762 __time_get_storage<wchar_t>::__do_date_order() const
5765 for (i = 0; i < __x_.size(); ++i)
5766 if (__x_[i] == L'%')
5773 for (++i; i < __x_.size(); ++i)
5774 if (__x_[i] == L'%')
5776 if (i == __x_.size())
5782 for (++i; i < __x_.size(); ++i)
5783 if (__x_[i] == L'%')
5785 if (i == __x_.size())
5788 if (__x_[i] == L'd')
5789 return time_base::ymd;
5792 for (++i; i < __x_.size(); ++i)
5793 if (__x_[i] == L'%')
5795 if (i == __x_.size())
5798 if (__x_[i] == L'm')
5799 return time_base::ydm;
5804 for (++i; i < __x_.size(); ++i)
5805 if (__x_[i] == L'%')
5807 if (i == __x_.size())
5810 if (__x_[i] == L'd')
5812 for (++i; i < __x_.size(); ++i)
5813 if (__x_[i] == L'%')
5815 if (i == __x_.size())
5818 if (__x_[i] == L'y' || __x_[i] == L'Y')
5819 return time_base::mdy;
5824 for (++i; i < __x_.size(); ++i)
5825 if (__x_[i] == L'%')
5827 if (i == __x_.size())
5830 if (__x_[i] == L'm')
5832 for (++i; i < __x_.size(); ++i)
5833 if (__x_[i] == L'%')
5835 if (i == __x_.size())
5838 if (__x_[i] == L'y' || __x_[i] == L'Y')
5839 return time_base::dmy;
5844 return time_base::no_order;
5846 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5850 __time_put::__time_put(const char* nm)
5851 : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5854 __throw_runtime_error("time_put_byname"
5855 " failed to construct for " + string(nm));
5858 __time_put::__time_put(const string& nm)
5859 : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5862 __throw_runtime_error("time_put_byname"
5863 " failed to construct for " + nm);
5866 __time_put::~__time_put()
5868 if (__loc_ != _LIBCPP_GET_C_LOCALE)
5873 __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5874 char __fmt, char __mod) const
5876 char fmt[] = {'%', __fmt, __mod, 0};
5878 swap(fmt[1], fmt[2]);
5879 size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
5883 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
5885 __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5886 char __fmt, char __mod) const
5889 char* __ne = __nar + 100;
5890 __do_put(__nar, __ne, __tm, __fmt, __mod);
5892 const char* __nb = __nar;
5893 size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
5894 if (j == size_t(-1))
5895 __throw_runtime_error("locale not supported");
5898 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
5900 // moneypunct_byname
5902 template <class charT>
5905 __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
5906 bool intl, char cs_precedes, char sep_by_space, char sign_posn,
5909 const char sign = static_cast<char>(money_base::sign);
5910 const char space = static_cast<char>(money_base::space);
5911 const char none = static_cast<char>(money_base::none);
5912 const char symbol = static_cast<char>(money_base::symbol);
5913 const char value = static_cast<char>(money_base::value);
5914 const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
5916 // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5917 // function'. "Space between sign and symbol or value" means that
5918 // if the sign is adjacent to the symbol, there's a space between
5919 // them, and otherwise there's a space between the sign and value.
5921 // C11's localeconv specifies that the fourth character of an
5922 // international curr_symbol is used to separate the sign and
5923 // value when sep_by_space says to do so. C++ can't represent
5924 // that, so we just use a space. When sep_by_space says to
5925 // separate the symbol and value-or-sign with a space, we rearrange the
5926 // curr_symbol to put its spacing character on the correct side of
5929 // We also need to avoid adding an extra space between the sign
5930 // and value when the currency symbol is suppressed (by not
5931 // setting showbase). We match glibc's strfmon by interpreting
5932 // sep_by_space==1 as "omit the space when the currency symbol is
5935 // Users who want to get this right should use ICU instead.
5937 switch (cs_precedes)
5939 case 0: // value before curr_symbol
5940 if (symbol_contains_sep) {
5941 // Move the separator to before the symbol, to place it
5942 // between the value and symbol.
5943 rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,
5944 __curr_symbol_.end());
5948 case 0: // Parentheses surround the quantity and currency symbol.
5949 pat.field[0] = sign;
5950 pat.field[1] = value;
5951 pat.field[2] = none; // Any space appears in the symbol.
5952 pat.field[3] = symbol;
5953 switch (sep_by_space)
5955 case 0: // No space separates the currency symbol and value.
5956 // This case may have changed between C99 and C11;
5957 // assume the currency symbol matches the intention.
5958 case 2: // Space between sign and currency or value.
5959 // The "sign" is two parentheses, so no space here either.
5961 case 1: // Space between currency-and-sign or currency and value.
5962 if (!symbol_contains_sep) {
5963 // We insert the space into the symbol instead of
5964 // setting pat.field[2]=space so that when
5965 // showbase is not set, the space goes away too.
5966 __curr_symbol_.insert(0, 1, space_char);
5973 case 1: // The sign string precedes the quantity and currency symbol.
5974 pat.field[0] = sign;
5975 pat.field[3] = symbol;
5976 switch (sep_by_space)
5978 case 0: // No space separates the currency symbol and value.
5979 pat.field[1] = value;
5980 pat.field[2] = none;
5982 case 1: // Space between currency-and-sign or currency and value.
5983 pat.field[1] = value;
5984 pat.field[2] = none;
5985 if (!symbol_contains_sep) {
5986 // We insert the space into the symbol instead of
5987 // setting pat.field[2]=space so that when
5988 // showbase is not set, the space goes away too.
5989 __curr_symbol_.insert(0, 1, space_char);
5992 case 2: // Space between sign and currency or value.
5993 pat.field[1] = space;
5994 pat.field[2] = value;
5995 if (symbol_contains_sep) {
5996 // Remove the separator from the symbol, since it
5997 // has already appeared after the sign.
5998 __curr_symbol_.erase(__curr_symbol_.begin());
6005 case 2: // The sign string succeeds the quantity and currency symbol.
6006 pat.field[0] = value;
6007 pat.field[3] = sign;
6008 switch (sep_by_space)
6010 case 0: // No space separates the currency symbol and value.
6011 pat.field[1] = none;
6012 pat.field[2] = symbol;
6014 case 1: // Space between currency-and-sign or currency and value.
6015 if (!symbol_contains_sep) {
6016 // We insert the space into the symbol instead of
6017 // setting pat.field[1]=space so that when
6018 // showbase is not set, the space goes away too.
6019 __curr_symbol_.insert(0, 1, space_char);
6021 pat.field[1] = none;
6022 pat.field[2] = symbol;
6024 case 2: // Space between sign and currency or value.
6025 pat.field[1] = symbol;
6026 pat.field[2] = space;
6027 if (symbol_contains_sep) {
6028 // Remove the separator from the symbol, since it
6029 // should not be removed if showbase is absent.
6030 __curr_symbol_.erase(__curr_symbol_.begin());
6037 case 3: // The sign string immediately precedes the currency symbol.
6038 pat.field[0] = value;
6039 pat.field[3] = symbol;
6040 switch (sep_by_space)
6042 case 0: // No space separates the currency symbol and value.
6043 pat.field[1] = none;
6044 pat.field[2] = sign;
6046 case 1: // Space between currency-and-sign or currency and value.
6047 pat.field[1] = space;
6048 pat.field[2] = sign;
6049 if (symbol_contains_sep) {
6050 // Remove the separator from the symbol, since it
6051 // has already appeared before the sign.
6052 __curr_symbol_.erase(__curr_symbol_.begin());
6055 case 2: // Space between sign and currency or value.
6056 pat.field[1] = sign;
6057 pat.field[2] = none;
6058 if (!symbol_contains_sep) {
6059 // We insert the space into the symbol instead of
6060 // setting pat.field[2]=space so that when
6061 // showbase is not set, the space goes away too.
6062 __curr_symbol_.insert(0, 1, space_char);
6069 case 4: // The sign string immediately succeeds the currency symbol.
6070 pat.field[0] = value;
6071 pat.field[3] = sign;
6072 switch (sep_by_space)
6074 case 0: // No space separates the currency symbol and value.
6075 pat.field[1] = none;
6076 pat.field[2] = symbol;
6078 case 1: // Space between currency-and-sign or currency and value.
6079 pat.field[1] = none;
6080 pat.field[2] = symbol;
6081 if (!symbol_contains_sep) {
6082 // We insert the space into the symbol instead of
6083 // setting pat.field[1]=space so that when
6084 // showbase is not set, the space goes away too.
6085 __curr_symbol_.insert(0, 1, space_char);
6088 case 2: // Space between sign and currency or value.
6089 pat.field[1] = symbol;
6090 pat.field[2] = space;
6091 if (symbol_contains_sep) {
6092 // Remove the separator from the symbol, since it
6093 // should not disappear when showbase is absent.
6094 __curr_symbol_.erase(__curr_symbol_.begin());
6105 case 1: // curr_symbol before value
6108 case 0: // Parentheses surround the quantity and currency symbol.
6109 pat.field[0] = sign;
6110 pat.field[1] = symbol;
6111 pat.field[2] = none; // Any space appears in the symbol.
6112 pat.field[3] = value;
6113 switch (sep_by_space)
6115 case 0: // No space separates the currency symbol and value.
6116 // This case may have changed between C99 and C11;
6117 // assume the currency symbol matches the intention.
6118 case 2: // Space between sign and currency or value.
6119 // The "sign" is two parentheses, so no space here either.
6121 case 1: // Space between currency-and-sign or currency and value.
6122 if (!symbol_contains_sep) {
6123 // We insert the space into the symbol instead of
6124 // setting pat.field[2]=space so that when
6125 // showbase is not set, the space goes away too.
6126 __curr_symbol_.insert(0, 1, space_char);
6133 case 1: // The sign string precedes the quantity and currency symbol.
6134 pat.field[0] = sign;
6135 pat.field[3] = value;
6136 switch (sep_by_space)
6138 case 0: // No space separates the currency symbol and value.
6139 pat.field[1] = symbol;
6140 pat.field[2] = none;
6142 case 1: // Space between currency-and-sign or currency and value.
6143 pat.field[1] = symbol;
6144 pat.field[2] = none;
6145 if (!symbol_contains_sep) {
6146 // We insert the space into the symbol instead of
6147 // setting pat.field[2]=space so that when
6148 // showbase is not set, the space goes away too.
6149 __curr_symbol_.push_back(space_char);
6152 case 2: // Space between sign and currency or value.
6153 pat.field[1] = space;
6154 pat.field[2] = symbol;
6155 if (symbol_contains_sep) {
6156 // Remove the separator from the symbol, since it
6157 // has already appeared after the sign.
6158 __curr_symbol_.pop_back();
6165 case 2: // The sign string succeeds the quantity and currency symbol.
6166 pat.field[0] = symbol;
6167 pat.field[3] = sign;
6168 switch (sep_by_space)
6170 case 0: // No space separates the currency symbol and value.
6171 pat.field[1] = none;
6172 pat.field[2] = value;
6174 case 1: // Space between currency-and-sign or currency and value.
6175 pat.field[1] = none;
6176 pat.field[2] = value;
6177 if (!symbol_contains_sep) {
6178 // We insert the space into the symbol instead of
6179 // setting pat.field[1]=space so that when
6180 // showbase is not set, the space goes away too.
6181 __curr_symbol_.push_back(space_char);
6184 case 2: // Space between sign and currency or value.
6185 pat.field[1] = value;
6186 pat.field[2] = space;
6187 if (symbol_contains_sep) {
6188 // Remove the separator from the symbol, since it
6189 // will appear before the sign.
6190 __curr_symbol_.pop_back();
6197 case 3: // The sign string immediately precedes the currency symbol.
6198 pat.field[0] = sign;
6199 pat.field[3] = value;
6200 switch (sep_by_space)
6202 case 0: // No space separates the currency symbol and value.
6203 pat.field[1] = symbol;
6204 pat.field[2] = none;
6206 case 1: // Space between currency-and-sign or currency and value.
6207 pat.field[1] = symbol;
6208 pat.field[2] = none;
6209 if (!symbol_contains_sep) {
6210 // We insert the space into the symbol instead of
6211 // setting pat.field[2]=space so that when
6212 // showbase is not set, the space goes away too.
6213 __curr_symbol_.push_back(space_char);
6216 case 2: // Space between sign and currency or value.
6217 pat.field[1] = space;
6218 pat.field[2] = symbol;
6219 if (symbol_contains_sep) {
6220 // Remove the separator from the symbol, since it
6221 // has already appeared after the sign.
6222 __curr_symbol_.pop_back();
6229 case 4: // The sign string immediately succeeds the currency symbol.
6230 pat.field[0] = symbol;
6231 pat.field[3] = value;
6232 switch (sep_by_space)
6234 case 0: // No space separates the currency symbol and value.
6235 pat.field[1] = sign;
6236 pat.field[2] = none;
6238 case 1: // Space between currency-and-sign or currency and value.
6239 pat.field[1] = sign;
6240 pat.field[2] = space;
6241 if (symbol_contains_sep) {
6242 // Remove the separator from the symbol, since it
6243 // should not disappear when showbase is absent.
6244 __curr_symbol_.pop_back();
6247 case 2: // Space between sign and currency or value.
6248 pat.field[1] = none;
6249 pat.field[2] = sign;
6250 if (!symbol_contains_sep) {
6251 // We insert the space into the symbol instead of
6252 // setting pat.field[1]=space so that when
6253 // showbase is not set, the space goes away too.
6254 __curr_symbol_.push_back(space_char);
6268 pat.field[0] = symbol;
6269 pat.field[1] = sign;
6270 pat.field[2] = none;
6271 pat.field[3] = value;
6276 moneypunct_byname<char, false>::init(const char* nm)
6278 typedef moneypunct<char, false> base;
6279 __libcpp_unique_locale loc(nm);
6281 __throw_runtime_error("moneypunct_byname"
6282 " failed to construct for " + string(nm));
6284 lconv* lc = __libcpp_localeconv_l(loc.get());
6285 if (!checked_string_to_char_convert(__decimal_point_,
6286 lc->mon_decimal_point,
6288 __decimal_point_ = base::do_decimal_point();
6289 if (!checked_string_to_char_convert(__thousands_sep_,
6290 lc->mon_thousands_sep,
6292 __thousands_sep_ = base::do_thousands_sep();
6294 __grouping_ = lc->mon_grouping;
6295 __curr_symbol_ = lc->currency_symbol;
6296 if (lc->frac_digits != CHAR_MAX)
6297 __frac_digits_ = lc->frac_digits;
6299 __frac_digits_ = base::do_frac_digits();
6300 if (lc->p_sign_posn == 0)
6301 __positive_sign_ = "()";
6303 __positive_sign_ = lc->positive_sign;
6304 if (lc->n_sign_posn == 0)
6305 __negative_sign_ = "()";
6307 __negative_sign_ = lc->negative_sign;
6308 // Assume the positive and negative formats will want spaces in
6309 // the same places in curr_symbol since there's no way to
6310 // represent anything else.
6311 string_type __dummy_curr_symbol = __curr_symbol_;
6312 __init_pat(__pos_format_, __dummy_curr_symbol, false,
6313 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
6314 __init_pat(__neg_format_, __curr_symbol_, false,
6315 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
6320 moneypunct_byname<char, true>::init(const char* nm)
6322 typedef moneypunct<char, true> base;
6323 __libcpp_unique_locale loc(nm);
6325 __throw_runtime_error("moneypunct_byname"
6326 " failed to construct for " + string(nm));
6328 lconv* lc = __libcpp_localeconv_l(loc.get());
6329 if (!checked_string_to_char_convert(__decimal_point_,
6330 lc->mon_decimal_point,
6332 __decimal_point_ = base::do_decimal_point();
6333 if (!checked_string_to_char_convert(__thousands_sep_,
6334 lc->mon_thousands_sep,
6336 __thousands_sep_ = base::do_thousands_sep();
6337 __grouping_ = lc->mon_grouping;
6338 __curr_symbol_ = lc->int_curr_symbol;
6339 if (lc->int_frac_digits != CHAR_MAX)
6340 __frac_digits_ = lc->int_frac_digits;
6342 __frac_digits_ = base::do_frac_digits();
6343 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6344 if (lc->p_sign_posn == 0)
6345 #else // _LIBCPP_MSVCRT
6346 if (lc->int_p_sign_posn == 0)
6347 #endif // !_LIBCPP_MSVCRT
6348 __positive_sign_ = "()";
6350 __positive_sign_ = lc->positive_sign;
6351 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6352 if(lc->n_sign_posn == 0)
6353 #else // _LIBCPP_MSVCRT
6354 if (lc->int_n_sign_posn == 0)
6355 #endif // !_LIBCPP_MSVCRT
6356 __negative_sign_ = "()";
6358 __negative_sign_ = lc->negative_sign;
6359 // Assume the positive and negative formats will want spaces in
6360 // the same places in curr_symbol since there's no way to
6361 // represent anything else.
6362 string_type __dummy_curr_symbol = __curr_symbol_;
6363 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6364 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6365 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
6366 __init_pat(__neg_format_, __curr_symbol_, true,
6367 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
6368 #else // _LIBCPP_MSVCRT
6369 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6370 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6371 lc->int_p_sign_posn, ' ');
6372 __init_pat(__neg_format_, __curr_symbol_, true,
6373 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6374 lc->int_n_sign_posn, ' ');
6375 #endif // !_LIBCPP_MSVCRT
6378 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
6381 moneypunct_byname<wchar_t, false>::init(const char* nm)
6383 typedef moneypunct<wchar_t, false> base;
6384 __libcpp_unique_locale loc(nm);
6386 __throw_runtime_error("moneypunct_byname"
6387 " failed to construct for " + string(nm));
6388 lconv* lc = __libcpp_localeconv_l(loc.get());
6389 if (!checked_string_to_wchar_convert(__decimal_point_,
6390 lc->mon_decimal_point,
6392 __decimal_point_ = base::do_decimal_point();
6393 if (!checked_string_to_wchar_convert(__thousands_sep_,
6394 lc->mon_thousands_sep,
6396 __thousands_sep_ = base::do_thousands_sep();
6397 __grouping_ = lc->mon_grouping;
6400 const char* bb = lc->currency_symbol;
6401 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6402 if (j == size_t(-1))
6403 __throw_runtime_error("locale not supported");
6404 wchar_t* wbe = wbuf + j;
6405 __curr_symbol_.assign(wbuf, wbe);
6406 if (lc->frac_digits != CHAR_MAX)
6407 __frac_digits_ = lc->frac_digits;
6409 __frac_digits_ = base::do_frac_digits();
6410 if (lc->p_sign_posn == 0)
6411 __positive_sign_ = L"()";
6415 bb = lc->positive_sign;
6416 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6417 if (j == size_t(-1))
6418 __throw_runtime_error("locale not supported");
6420 __positive_sign_.assign(wbuf, wbe);
6422 if (lc->n_sign_posn == 0)
6423 __negative_sign_ = L"()";
6427 bb = lc->negative_sign;
6428 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6429 if (j == size_t(-1))
6430 __throw_runtime_error("locale not supported");
6432 __negative_sign_.assign(wbuf, wbe);
6434 // Assume the positive and negative formats will want spaces in
6435 // the same places in curr_symbol since there's no way to
6436 // represent anything else.
6437 string_type __dummy_curr_symbol = __curr_symbol_;
6438 __init_pat(__pos_format_, __dummy_curr_symbol, false,
6439 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6440 __init_pat(__neg_format_, __curr_symbol_, false,
6441 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6446 moneypunct_byname<wchar_t, true>::init(const char* nm)
6448 typedef moneypunct<wchar_t, true> base;
6449 __libcpp_unique_locale loc(nm);
6451 __throw_runtime_error("moneypunct_byname"
6452 " failed to construct for " + string(nm));
6454 lconv* lc = __libcpp_localeconv_l(loc.get());
6455 if (!checked_string_to_wchar_convert(__decimal_point_,
6456 lc->mon_decimal_point,
6458 __decimal_point_ = base::do_decimal_point();
6459 if (!checked_string_to_wchar_convert(__thousands_sep_,
6460 lc->mon_thousands_sep,
6462 __thousands_sep_ = base::do_thousands_sep();
6463 __grouping_ = lc->mon_grouping;
6466 const char* bb = lc->int_curr_symbol;
6467 size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6468 if (j == size_t(-1))
6469 __throw_runtime_error("locale not supported");
6470 wchar_t* wbe = wbuf + j;
6471 __curr_symbol_.assign(wbuf, wbe);
6472 if (lc->int_frac_digits != CHAR_MAX)
6473 __frac_digits_ = lc->int_frac_digits;
6475 __frac_digits_ = base::do_frac_digits();
6476 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6477 if (lc->p_sign_posn == 0)
6478 #else // _LIBCPP_MSVCRT
6479 if (lc->int_p_sign_posn == 0)
6480 #endif // !_LIBCPP_MSVCRT
6481 __positive_sign_ = L"()";
6485 bb = lc->positive_sign;
6486 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6487 if (j == size_t(-1))
6488 __throw_runtime_error("locale not supported");
6490 __positive_sign_.assign(wbuf, wbe);
6492 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6493 if (lc->n_sign_posn == 0)
6494 #else // _LIBCPP_MSVCRT
6495 if (lc->int_n_sign_posn == 0)
6496 #endif // !_LIBCPP_MSVCRT
6497 __negative_sign_ = L"()";
6501 bb = lc->negative_sign;
6502 j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6503 if (j == size_t(-1))
6504 __throw_runtime_error("locale not supported");
6506 __negative_sign_.assign(wbuf, wbe);
6508 // Assume the positive and negative formats will want spaces in
6509 // the same places in curr_symbol since there's no way to
6510 // represent anything else.
6511 string_type __dummy_curr_symbol = __curr_symbol_;
6512 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6513 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6514 lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6515 __init_pat(__neg_format_, __curr_symbol_, true,
6516 lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6517 #else // _LIBCPP_MSVCRT
6518 __init_pat(__pos_format_, __dummy_curr_symbol, true,
6519 lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6520 lc->int_p_sign_posn, L' ');
6521 __init_pat(__neg_format_, __curr_symbol_, true,
6522 lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6523 lc->int_n_sign_posn, L' ');
6524 #endif // !_LIBCPP_MSVCRT
6526 #endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
6528 void __do_nothing(void*) {}
6530 void __throw_runtime_error(const char* msg)
6532 #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
6533 throw runtime_error(msg);
6535 _LIBCPP_VERBOSE_ABORT("runtime_error was thrown in -fno-exceptions mode with message \"%s\"", msg);
6539 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;
6540 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;)
6542 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<char>;
6543 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<wchar_t>;)
6545 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<char>;
6546 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<wchar_t>;)
6548 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<char>;
6549 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<wchar_t>;)
6551 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<char>;
6552 _LIBCPP_IF_WIDE_CHARACTERS(template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<wchar_t>;)
6554 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<char>;
6555 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<wchar_t>;)
6557 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<char>;
6558 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<wchar_t>;)
6560 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<char>;
6561 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<wchar_t>;)
6563 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<char>;
6564 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<wchar_t>;)
6566 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, false>;
6567 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, true>;
6568 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, false>;)
6569 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, true>;)
6571 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, false>;
6572 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, true>;
6573 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, false>;)
6574 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, true>;)
6576 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<char>;
6577 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<wchar_t>;)
6579 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<char>;
6580 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<wchar_t>;)
6582 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<char>;
6583 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<wchar_t>;)
6585 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<char>;
6586 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<wchar_t>;)
6588 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<char>;
6589 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<wchar_t>;)
6591 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<char>;
6592 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t>;)
6594 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>;
6595 _LIBCPP_IF_WIDE_CHARACTERS(template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;)
6596 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
6597 template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
6598 #ifndef _LIBCPP_HAS_NO_CHAR8_T
6599 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char8_t, mbstate_t>;
6600 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char8_t, mbstate_t>;
6603 _LIBCPP_END_NAMESPACE_STD