xref: /llvm-project-15.0.7/libcxx/src/locale.cpp (revision 498ee00a)
1 //===------------------------- locale.cpp ---------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // On Solaris, we need to define something to make the C99 parts of localeconv
11 // visible.
12 #ifdef __sun__
13 #define _LCONV_C99
14 #endif
15 
16 #include "string"
17 #include "locale"
18 #include "codecvt"
19 #include "vector"
20 #include "algorithm"
21 #include "typeinfo"
22 #ifndef _LIBCPP_NO_EXCEPTIONS
23 #  include "type_traits"
24 #endif
25 #include "clocale"
26 #include "cstring"
27 #include "cwctype"
28 #include "__sso_allocator"
29 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
30 #include "support/win32/locale_win32.h"
31 #elif !defined(__BIONIC__)
32 #include <langinfo.h>
33 #endif
34 #include <stdlib.h>
35 #include <stdio.h>
36 
37 // On Linux, wint_t and wchar_t have different signed-ness, and this causes
38 // lots of noise in the build log, but no bugs that I know of.
39 #if defined(__clang__)
40 #pragma clang diagnostic ignored "-Wsign-conversion"
41 #endif
42 
43 _LIBCPP_BEGIN_NAMESPACE_STD
44 
45 #ifdef __cloc_defined
46 locale_t __cloc() {
47   // In theory this could create a race condition. In practice
48   // the race condition is non-fatal since it will just create
49   // a little resource leak. Better approach would be appreciated.
50   static locale_t result = newlocale(LC_ALL_MASK, "C", 0);
51   return result;
52 }
53 #endif // __cloc_defined
54 
55 namespace {
56 
57 struct release
58 {
59     void operator()(locale::facet* p) {p->__release_shared();}
60 };
61 
62 template <class T, class A0>
63 inline
64 T&
65 make(A0 a0)
66 {
67     static typename aligned_storage<sizeof(T)>::type buf;
68     ::new (&buf) T(a0);
69     return *reinterpret_cast<T*>(&buf);
70 }
71 
72 template <class T, class A0, class A1>
73 inline
74 T&
75 make(A0 a0, A1 a1)
76 {
77     static typename aligned_storage<sizeof(T)>::type buf;
78     ::new (&buf) T(a0, a1);
79     return *reinterpret_cast<T*>(&buf);
80 }
81 
82 template <class T, class A0, class A1, class A2>
83 inline
84 T&
85 make(A0 a0, A1 a1, A2 a2)
86 {
87     static typename aligned_storage<sizeof(T)>::type buf;
88     ::new (&buf) T(a0, a1, a2);
89     return *reinterpret_cast<T*>(&buf);
90 }
91 
92 template <typename T, size_t N>
93 inline
94 _LIBCPP_CONSTEXPR
95 size_t
96 countof(const T (&)[N])
97 {
98     return N;
99 }
100 
101 template <typename T>
102 inline
103 _LIBCPP_CONSTEXPR
104 size_t
105 countof(const T * const begin, const T * const end)
106 {
107     return static_cast<size_t>(end - begin);
108 }
109 
110 _LIBCPP_NORETURN static void __throw_runtime_error(const string &msg)
111 {
112 #ifndef _LIBCPP_NO_EXCEPTIONS
113     throw runtime_error(msg);
114 #else
115     (void)msg;
116     _VSTD::abort();
117 #endif
118 }
119 
120 }
121 
122 #if defined(_AIX)
123 // Set priority to INT_MIN + 256 + 150
124 # pragma priority ( -2147483242 )
125 #endif
126 
127 const locale::category locale::none;
128 const locale::category locale::collate;
129 const locale::category locale::ctype;
130 const locale::category locale::monetary;
131 const locale::category locale::numeric;
132 const locale::category locale::time;
133 const locale::category locale::messages;
134 const locale::category locale::all;
135 
136 class _LIBCPP_HIDDEN locale::__imp
137     : public facet
138 {
139     enum {N = 28};
140 #if defined(_LIBCPP_MSVC)
141 // FIXME: MSVC doesn't support aligned parameters by value.
142 // I can't get the __sso_allocator to work here
143 // for MSVC I think for this reason.
144     vector<facet*> facets_;
145 #else
146     vector<facet*, __sso_allocator<facet*, N> > facets_;
147 #endif
148     string         name_;
149 public:
150     explicit __imp(size_t refs = 0);
151     explicit __imp(const string& name, size_t refs = 0);
152     __imp(const __imp&);
153     __imp(const __imp&, const string&, locale::category c);
154     __imp(const __imp& other, const __imp& one, locale::category c);
155     __imp(const __imp&, facet* f, long id);
156     ~__imp();
157 
158     const string& name() const {return name_;}
159     bool has_facet(long id) const
160         {return static_cast<size_t>(id) < facets_.size() && facets_[static_cast<size_t>(id)];}
161     const locale::facet* use_facet(long id) const;
162 
163     static const locale& make_classic();
164     static       locale& make_global();
165 private:
166     void install(facet* f, long id);
167     template <class F> void install(F* f) {install(f, f->id.__get());}
168     template <class F> void install_from(const __imp& other);
169 };
170 
171 locale::__imp::__imp(size_t refs)
172     : facet(refs),
173       facets_(N),
174       name_("C")
175 {
176     facets_.clear();
177     install(&make<_VSTD::collate<char> >(1u));
178     install(&make<_VSTD::collate<wchar_t> >(1u));
179     install(&make<_VSTD::ctype<char> >(nullptr, false, 1u));
180     install(&make<_VSTD::ctype<wchar_t> >(1u));
181     install(&make<codecvt<char, char, mbstate_t> >(1u));
182     install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
183     install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
184     install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
185     install(&make<numpunct<char> >(1u));
186     install(&make<numpunct<wchar_t> >(1u));
187     install(&make<num_get<char> >(1u));
188     install(&make<num_get<wchar_t> >(1u));
189     install(&make<num_put<char> >(1u));
190     install(&make<num_put<wchar_t> >(1u));
191     install(&make<moneypunct<char, false> >(1u));
192     install(&make<moneypunct<char, true> >(1u));
193     install(&make<moneypunct<wchar_t, false> >(1u));
194     install(&make<moneypunct<wchar_t, true> >(1u));
195     install(&make<money_get<char> >(1u));
196     install(&make<money_get<wchar_t> >(1u));
197     install(&make<money_put<char> >(1u));
198     install(&make<money_put<wchar_t> >(1u));
199     install(&make<time_get<char> >(1u));
200     install(&make<time_get<wchar_t> >(1u));
201     install(&make<time_put<char> >(1u));
202     install(&make<time_put<wchar_t> >(1u));
203     install(&make<_VSTD::messages<char> >(1u));
204     install(&make<_VSTD::messages<wchar_t> >(1u));
205 }
206 
207 locale::__imp::__imp(const string& name, size_t refs)
208     : facet(refs),
209       facets_(N),
210       name_(name)
211 {
212 #ifndef _LIBCPP_NO_EXCEPTIONS
213     try
214     {
215 #endif  // _LIBCPP_NO_EXCEPTIONS
216         facets_ = locale::classic().__locale_->facets_;
217         for (unsigned i = 0; i < facets_.size(); ++i)
218             if (facets_[i])
219                 facets_[i]->__add_shared();
220         install(new collate_byname<char>(name_));
221         install(new collate_byname<wchar_t>(name_));
222         install(new ctype_byname<char>(name_));
223         install(new ctype_byname<wchar_t>(name_));
224         install(new codecvt_byname<char, char, mbstate_t>(name_));
225         install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
226         install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
227         install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
228         install(new numpunct_byname<char>(name_));
229         install(new numpunct_byname<wchar_t>(name_));
230         install(new moneypunct_byname<char, false>(name_));
231         install(new moneypunct_byname<char, true>(name_));
232         install(new moneypunct_byname<wchar_t, false>(name_));
233         install(new moneypunct_byname<wchar_t, true>(name_));
234         install(new time_get_byname<char>(name_));
235         install(new time_get_byname<wchar_t>(name_));
236         install(new time_put_byname<char>(name_));
237         install(new time_put_byname<wchar_t>(name_));
238         install(new messages_byname<char>(name_));
239         install(new messages_byname<wchar_t>(name_));
240 #ifndef _LIBCPP_NO_EXCEPTIONS
241     }
242     catch (...)
243     {
244         for (unsigned i = 0; i < facets_.size(); ++i)
245             if (facets_[i])
246                 facets_[i]->__release_shared();
247         throw;
248     }
249 #endif  // _LIBCPP_NO_EXCEPTIONS
250 }
251 
252 // NOTE avoid the `base class should be explicitly initialized in the
253 // copy constructor` warning emitted by GCC
254 #if defined(__clang__) || _GNUC_VER >= 406
255 #pragma GCC diagnostic push
256 #pragma GCC diagnostic ignored "-Wextra"
257 #endif
258 
259 locale::__imp::__imp(const __imp& other)
260     : facets_(max<size_t>(N, other.facets_.size())),
261       name_(other.name_)
262 {
263     facets_ = other.facets_;
264     for (unsigned i = 0; i < facets_.size(); ++i)
265         if (facets_[i])
266             facets_[i]->__add_shared();
267 }
268 
269 #if defined(__clang__) || _GNUC_VER >= 406
270 #pragma GCC diagnostic pop
271 #endif
272 
273 locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
274     : facets_(N),
275       name_("*")
276 {
277     facets_ = other.facets_;
278     for (unsigned i = 0; i < facets_.size(); ++i)
279         if (facets_[i])
280             facets_[i]->__add_shared();
281 #ifndef _LIBCPP_NO_EXCEPTIONS
282     try
283     {
284 #endif  // _LIBCPP_NO_EXCEPTIONS
285         if (c & locale::collate)
286         {
287             install(new collate_byname<char>(name));
288             install(new collate_byname<wchar_t>(name));
289         }
290         if (c & locale::ctype)
291         {
292             install(new ctype_byname<char>(name));
293             install(new ctype_byname<wchar_t>(name));
294             install(new codecvt_byname<char, char, mbstate_t>(name));
295             install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
296             install(new codecvt_byname<char16_t, char, mbstate_t>(name));
297             install(new codecvt_byname<char32_t, char, mbstate_t>(name));
298         }
299         if (c & locale::monetary)
300         {
301             install(new moneypunct_byname<char, false>(name));
302             install(new moneypunct_byname<char, true>(name));
303             install(new moneypunct_byname<wchar_t, false>(name));
304             install(new moneypunct_byname<wchar_t, true>(name));
305         }
306         if (c & locale::numeric)
307         {
308             install(new numpunct_byname<char>(name));
309             install(new numpunct_byname<wchar_t>(name));
310         }
311         if (c & locale::time)
312         {
313             install(new time_get_byname<char>(name));
314             install(new time_get_byname<wchar_t>(name));
315             install(new time_put_byname<char>(name));
316             install(new time_put_byname<wchar_t>(name));
317         }
318         if (c & locale::messages)
319         {
320             install(new messages_byname<char>(name));
321             install(new messages_byname<wchar_t>(name));
322         }
323 #ifndef _LIBCPP_NO_EXCEPTIONS
324     }
325     catch (...)
326     {
327         for (unsigned i = 0; i < facets_.size(); ++i)
328             if (facets_[i])
329                 facets_[i]->__release_shared();
330         throw;
331     }
332 #endif  // _LIBCPP_NO_EXCEPTIONS
333 }
334 
335 template<class F>
336 inline
337 void
338 locale::__imp::install_from(const locale::__imp& one)
339 {
340     long id = F::id.__get();
341     install(const_cast<F*>(static_cast<const F*>(one.use_facet(id))), id);
342 }
343 
344 locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
345     : facets_(N),
346       name_("*")
347 {
348     facets_ = other.facets_;
349     for (unsigned i = 0; i < facets_.size(); ++i)
350         if (facets_[i])
351             facets_[i]->__add_shared();
352 #ifndef _LIBCPP_NO_EXCEPTIONS
353     try
354     {
355 #endif  // _LIBCPP_NO_EXCEPTIONS
356         if (c & locale::collate)
357         {
358             install_from<_VSTD::collate<char> >(one);
359             install_from<_VSTD::collate<wchar_t> >(one);
360         }
361         if (c & locale::ctype)
362         {
363             install_from<_VSTD::ctype<char> >(one);
364             install_from<_VSTD::ctype<wchar_t> >(one);
365             install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
366             install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
367             install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
368             install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
369         }
370         if (c & locale::monetary)
371         {
372             install_from<moneypunct<char, false> >(one);
373             install_from<moneypunct<char, true> >(one);
374             install_from<moneypunct<wchar_t, false> >(one);
375             install_from<moneypunct<wchar_t, true> >(one);
376             install_from<money_get<char> >(one);
377             install_from<money_get<wchar_t> >(one);
378             install_from<money_put<char> >(one);
379             install_from<money_put<wchar_t> >(one);
380         }
381         if (c & locale::numeric)
382         {
383             install_from<numpunct<char> >(one);
384             install_from<numpunct<wchar_t> >(one);
385             install_from<num_get<char> >(one);
386             install_from<num_get<wchar_t> >(one);
387             install_from<num_put<char> >(one);
388             install_from<num_put<wchar_t> >(one);
389         }
390         if (c & locale::time)
391         {
392             install_from<time_get<char> >(one);
393             install_from<time_get<wchar_t> >(one);
394             install_from<time_put<char> >(one);
395             install_from<time_put<wchar_t> >(one);
396         }
397         if (c & locale::messages)
398         {
399             install_from<_VSTD::messages<char> >(one);
400             install_from<_VSTD::messages<wchar_t> >(one);
401         }
402 #ifndef _LIBCPP_NO_EXCEPTIONS
403     }
404     catch (...)
405     {
406         for (unsigned i = 0; i < facets_.size(); ++i)
407             if (facets_[i])
408                 facets_[i]->__release_shared();
409         throw;
410     }
411 #endif  // _LIBCPP_NO_EXCEPTIONS
412 }
413 
414 locale::__imp::__imp(const __imp& other, facet* f, long id)
415     : facets_(max<size_t>(N, other.facets_.size()+1)),
416       name_("*")
417 {
418     f->__add_shared();
419     unique_ptr<facet, release> hold(f);
420     facets_ = other.facets_;
421     for (unsigned i = 0; i < other.facets_.size(); ++i)
422         if (facets_[i])
423             facets_[i]->__add_shared();
424     install(hold.get(), id);
425 }
426 
427 locale::__imp::~__imp()
428 {
429     for (unsigned i = 0; i < facets_.size(); ++i)
430         if (facets_[i])
431             facets_[i]->__release_shared();
432 }
433 
434 void
435 locale::__imp::install(facet* f, long id)
436 {
437     f->__add_shared();
438     unique_ptr<facet, release> hold(f);
439     if (static_cast<size_t>(id) >= facets_.size())
440         facets_.resize(static_cast<size_t>(id+1));
441     if (facets_[static_cast<size_t>(id)])
442         facets_[static_cast<size_t>(id)]->__release_shared();
443     facets_[static_cast<size_t>(id)] = hold.release();
444 }
445 
446 const locale::facet*
447 locale::__imp::use_facet(long id) const
448 {
449 #ifndef _LIBCPP_NO_EXCEPTIONS
450     if (!has_facet(id))
451         throw bad_cast();
452 #endif  // _LIBCPP_NO_EXCEPTIONS
453     return facets_[static_cast<size_t>(id)];
454 }
455 
456 // locale
457 
458 const locale&
459 locale::__imp::make_classic()
460 {
461     // only one thread can get in here and it only gets in once
462     static aligned_storage<sizeof(locale)>::type buf;
463     locale* c = reinterpret_cast<locale*>(&buf);
464     c->__locale_ = &make<__imp>(1u);
465     return *c;
466 }
467 
468 const locale&
469 locale::classic()
470 {
471     static const locale& c = __imp::make_classic();
472     return c;
473 }
474 
475 locale&
476 locale::__imp::make_global()
477 {
478     // only one thread can get in here and it only gets in once
479     static aligned_storage<sizeof(locale)>::type buf;
480     ::new (&buf) locale(locale::classic());
481     return *reinterpret_cast<locale*>(&buf);
482 }
483 
484 locale&
485 locale::__global()
486 {
487     static locale& g = __imp::make_global();
488     return g;
489 }
490 
491 locale::locale()  _NOEXCEPT
492     : __locale_(__global().__locale_)
493 {
494     __locale_->__add_shared();
495 }
496 
497 locale::locale(const locale& l)  _NOEXCEPT
498     : __locale_(l.__locale_)
499 {
500     __locale_->__add_shared();
501 }
502 
503 locale::~locale()
504 {
505     __locale_->__release_shared();
506 }
507 
508 const locale&
509 locale::operator=(const locale& other)  _NOEXCEPT
510 {
511     other.__locale_->__add_shared();
512     __locale_->__release_shared();
513     __locale_ = other.__locale_;
514     return *this;
515 }
516 
517 locale::locale(const char* name)
518 #ifndef _LIBCPP_NO_EXCEPTIONS
519     : __locale_(name ? new __imp(name)
520                      : throw runtime_error("locale constructed with null"))
521 #else  // _LIBCPP_NO_EXCEPTIONS
522     : __locale_(new __imp(name))
523 #endif
524 {
525     __locale_->__add_shared();
526 }
527 
528 locale::locale(const string& name)
529     : __locale_(new __imp(name))
530 {
531     __locale_->__add_shared();
532 }
533 
534 locale::locale(const locale& other, const char* name, category c)
535 #ifndef _LIBCPP_NO_EXCEPTIONS
536     : __locale_(name ? new __imp(*other.__locale_, name, c)
537                      : throw runtime_error("locale constructed with null"))
538 #else  // _LIBCPP_NO_EXCEPTIONS
539     : __locale_(new __imp(*other.__locale_, name, c))
540 #endif
541 {
542     __locale_->__add_shared();
543 }
544 
545 locale::locale(const locale& other, const string& name, category c)
546     : __locale_(new __imp(*other.__locale_, name, c))
547 {
548     __locale_->__add_shared();
549 }
550 
551 locale::locale(const locale& other, const locale& one, category c)
552     : __locale_(new __imp(*other.__locale_, *one.__locale_, c))
553 {
554     __locale_->__add_shared();
555 }
556 
557 string
558 locale::name() const
559 {
560     return __locale_->name();
561 }
562 
563 void
564 locale::__install_ctor(const locale& other, facet* f, long id)
565 {
566     if (f)
567         __locale_ = new __imp(*other.__locale_, f, id);
568     else
569         __locale_ = other.__locale_;
570     __locale_->__add_shared();
571 }
572 
573 locale
574 locale::global(const locale& loc)
575 {
576     locale& g = __global();
577     locale r = g;
578     g = loc;
579 #ifndef __CloudABI__
580     if (g.name() != "*")
581         setlocale(LC_ALL, g.name().c_str());
582 #endif
583     return r;
584 }
585 
586 bool
587 locale::has_facet(id& x) const
588 {
589     return __locale_->has_facet(x.__get());
590 }
591 
592 const locale::facet*
593 locale::use_facet(id& x) const
594 {
595     return __locale_->use_facet(x.__get());
596 }
597 
598 bool
599 locale::operator==(const locale& y) const
600 {
601     return (__locale_ == y.__locale_)
602         || (__locale_->name() != "*" && __locale_->name() == y.__locale_->name());
603 }
604 
605 // locale::facet
606 
607 locale::facet::~facet()
608 {
609 }
610 
611 void
612 locale::facet::__on_zero_shared() _NOEXCEPT
613 {
614     delete this;
615 }
616 
617 // locale::id
618 
619 int32_t locale::id::__next_id = 0;
620 
621 namespace
622 {
623 
624 class __fake_bind
625 {
626     locale::id* id_;
627     void (locale::id::* pmf_)();
628 public:
629     __fake_bind(void (locale::id::* pmf)(), locale::id* id)
630         : id_(id), pmf_(pmf) {}
631 
632     void operator()() const
633     {
634         (id_->*pmf_)();
635     }
636 };
637 
638 }
639 
640 long
641 locale::id::__get()
642 {
643     call_once(__flag_, __fake_bind(&locale::id::__init, this));
644     return __id_ - 1;
645 }
646 
647 void
648 locale::id::__init()
649 {
650     __id_ = __sync_add_and_fetch(&__next_id, 1);
651 }
652 
653 // template <> class collate_byname<char>
654 
655 collate_byname<char>::collate_byname(const char* n, size_t refs)
656     : collate<char>(refs),
657       __l(newlocale(LC_ALL_MASK, n, 0))
658 {
659     if (__l == 0)
660         __throw_runtime_error("collate_byname<char>::collate_byname"
661                             " failed to construct for " + string(n));
662 }
663 
664 collate_byname<char>::collate_byname(const string& name, size_t refs)
665     : collate<char>(refs),
666       __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
667 {
668     if (__l == 0)
669         __throw_runtime_error("collate_byname<char>::collate_byname"
670                             " failed to construct for " + name);
671 }
672 
673 collate_byname<char>::~collate_byname()
674 {
675     freelocale(__l);
676 }
677 
678 int
679 collate_byname<char>::do_compare(const char_type* __lo1, const char_type* __hi1,
680                                  const char_type* __lo2, const char_type* __hi2) const
681 {
682     string_type lhs(__lo1, __hi1);
683     string_type rhs(__lo2, __hi2);
684     int r = strcoll_l(lhs.c_str(), rhs.c_str(), __l);
685     if (r < 0)
686         return -1;
687     if (r > 0)
688         return 1;
689     return r;
690 }
691 
692 collate_byname<char>::string_type
693 collate_byname<char>::do_transform(const char_type* lo, const char_type* hi) const
694 {
695     const string_type in(lo, hi);
696     string_type out(strxfrm_l(0, in.c_str(), 0, __l), char());
697     strxfrm_l(const_cast<char*>(out.c_str()), in.c_str(), out.size()+1, __l);
698     return out;
699 }
700 
701 // template <> class collate_byname<wchar_t>
702 
703 collate_byname<wchar_t>::collate_byname(const char* n, size_t refs)
704     : collate<wchar_t>(refs),
705       __l(newlocale(LC_ALL_MASK, n, 0))
706 {
707     if (__l == 0)
708         __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
709                             " failed to construct for " + string(n));
710 }
711 
712 collate_byname<wchar_t>::collate_byname(const string& name, size_t refs)
713     : collate<wchar_t>(refs),
714       __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
715 {
716     if (__l == 0)
717         __throw_runtime_error("collate_byname<wchar_t>::collate_byname(size_t refs)"
718                             " failed to construct for " + name);
719 }
720 
721 collate_byname<wchar_t>::~collate_byname()
722 {
723     freelocale(__l);
724 }
725 
726 int
727 collate_byname<wchar_t>::do_compare(const char_type* __lo1, const char_type* __hi1,
728                                  const char_type* __lo2, const char_type* __hi2) const
729 {
730     string_type lhs(__lo1, __hi1);
731     string_type rhs(__lo2, __hi2);
732     int r = wcscoll_l(lhs.c_str(), rhs.c_str(), __l);
733     if (r < 0)
734         return -1;
735     if (r > 0)
736         return 1;
737     return r;
738 }
739 
740 collate_byname<wchar_t>::string_type
741 collate_byname<wchar_t>::do_transform(const char_type* lo, const char_type* hi) const
742 {
743     const string_type in(lo, hi);
744     string_type out(wcsxfrm_l(0, in.c_str(), 0, __l), wchar_t());
745     wcsxfrm_l(const_cast<wchar_t*>(out.c_str()), in.c_str(), out.size()+1, __l);
746     return out;
747 }
748 
749 // template <> class ctype<wchar_t>;
750 
751 const ctype_base::mask ctype_base::space;
752 const ctype_base::mask ctype_base::print;
753 const ctype_base::mask ctype_base::cntrl;
754 const ctype_base::mask ctype_base::upper;
755 const ctype_base::mask ctype_base::lower;
756 const ctype_base::mask ctype_base::alpha;
757 const ctype_base::mask ctype_base::digit;
758 const ctype_base::mask ctype_base::punct;
759 const ctype_base::mask ctype_base::xdigit;
760 const ctype_base::mask ctype_base::blank;
761 const ctype_base::mask ctype_base::alnum;
762 const ctype_base::mask ctype_base::graph;
763 
764 locale::id ctype<wchar_t>::id;
765 
766 ctype<wchar_t>::~ctype()
767 {
768 }
769 
770 bool
771 ctype<wchar_t>::do_is(mask m, char_type c) const
772 {
773     return isascii(c) ? (ctype<char>::classic_table()[c] & m) != 0 : false;
774 }
775 
776 const wchar_t*
777 ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
778 {
779     for (; low != high; ++low, ++vec)
780         *vec = static_cast<mask>(isascii(*low) ?
781                                    ctype<char>::classic_table()[*low] : 0);
782     return low;
783 }
784 
785 const wchar_t*
786 ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
787 {
788     for (; low != high; ++low)
789         if (isascii(*low) && (ctype<char>::classic_table()[*low] & m))
790             break;
791     return low;
792 }
793 
794 const wchar_t*
795 ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
796 {
797     for (; low != high; ++low)
798         if (!(isascii(*low) && (ctype<char>::classic_table()[*low] & m)))
799             break;
800     return low;
801 }
802 
803 wchar_t
804 ctype<wchar_t>::do_toupper(char_type c) const
805 {
806 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
807     return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
808 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
809       defined(__NetBSD__)
810     return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
811 #else
812     return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;
813 #endif
814 }
815 
816 const wchar_t*
817 ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
818 {
819     for (; low != high; ++low)
820 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
821         *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
822 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
823       defined(__NetBSD__)
824         *low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
825                              : *low;
826 #else
827         *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? (*low-L'a'+L'A') : *low;
828 #endif
829     return low;
830 }
831 
832 wchar_t
833 ctype<wchar_t>::do_tolower(char_type c) const
834 {
835 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
836     return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
837 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
838       defined(__NetBSD__)
839     return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
840 #else
841     return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;
842 #endif
843 }
844 
845 const wchar_t*
846 ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
847 {
848     for (; low != high; ++low)
849 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
850         *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
851 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
852       defined(__NetBSD__)
853         *low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
854                              : *low;
855 #else
856         *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-L'A'+L'a' : *low;
857 #endif
858     return low;
859 }
860 
861 wchar_t
862 ctype<wchar_t>::do_widen(char c) const
863 {
864     return c;
865 }
866 
867 const char*
868 ctype<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
869 {
870     for (; low != high; ++low, ++dest)
871         *dest = *low;
872     return low;
873 }
874 
875 char
876 ctype<wchar_t>::do_narrow(char_type c, char dfault) const
877 {
878     if (isascii(c))
879         return static_cast<char>(c);
880     return dfault;
881 }
882 
883 const wchar_t*
884 ctype<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
885 {
886     for (; low != high; ++low, ++dest)
887         if (isascii(*low))
888             *dest = static_cast<char>(*low);
889         else
890             *dest = dfault;
891     return low;
892 }
893 
894 // template <> class ctype<char>;
895 
896 locale::id ctype<char>::id;
897 
898 ctype<char>::ctype(const mask* tab, bool del, size_t refs)
899     : locale::facet(refs),
900       __tab_(tab),
901       __del_(del)
902 {
903   if (__tab_ == 0)
904       __tab_ = classic_table();
905 }
906 
907 ctype<char>::~ctype()
908 {
909     if (__tab_ && __del_)
910         delete [] __tab_;
911 }
912 
913 char
914 ctype<char>::do_toupper(char_type c) const
915 {
916 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
917     return isascii(c) ?
918       static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
919 #elif defined(__NetBSD__)
920     return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
921 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
922     return isascii(c) ?
923       static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
924 #else
925     return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;
926 #endif
927 }
928 
929 const char*
930 ctype<char>::do_toupper(char_type* low, const char_type* high) const
931 {
932     for (; low != high; ++low)
933 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
934         *low = isascii(*low) ?
935           static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
936 #elif defined(__NetBSD__)
937         *low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
938 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
939         *low = isascii(*low) ?
940           static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
941 #else
942         *low = (isascii(*low) && islower_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'a'+'A' : *low;
943 #endif
944     return low;
945 }
946 
947 char
948 ctype<char>::do_tolower(char_type c) const
949 {
950 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
951     return isascii(c) ?
952       static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
953 #elif defined(__NetBSD__)
954     return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
955 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
956     return isascii(c) ?
957       static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
958 #else
959     return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'A'+'a' : c;
960 #endif
961 }
962 
963 const char*
964 ctype<char>::do_tolower(char_type* low, const char_type* high) const
965 {
966     for (; low != high; ++low)
967 #ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
968         *low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
969 #elif defined(__NetBSD__)
970         *low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
971 #elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
972         *low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
973 #else
974         *low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low;
975 #endif
976     return low;
977 }
978 
979 char
980 ctype<char>::do_widen(char c) const
981 {
982     return c;
983 }
984 
985 const char*
986 ctype<char>::do_widen(const char* low, const char* high, char_type* dest) const
987 {
988     for (; low != high; ++low, ++dest)
989         *dest = *low;
990     return low;
991 }
992 
993 char
994 ctype<char>::do_narrow(char_type c, char dfault) const
995 {
996     if (isascii(c))
997         return static_cast<char>(c);
998     return dfault;
999 }
1000 
1001 const char*
1002 ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1003 {
1004     for (; low != high; ++low, ++dest)
1005         if (isascii(*low))
1006             *dest = *low;
1007         else
1008             *dest = dfault;
1009     return low;
1010 }
1011 
1012 #if defined(__EMSCRIPTEN__)
1013 extern "C" const unsigned short ** __ctype_b_loc();
1014 extern "C" const int ** __ctype_tolower_loc();
1015 extern "C" const int ** __ctype_toupper_loc();
1016 #endif
1017 
1018 #ifdef _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
1019 const ctype<char>::mask*
1020 ctype<char>::classic_table()  _NOEXCEPT
1021 {
1022     static _LIBCPP_CONSTEXPR const ctype<char>::mask builtin_table[table_size] = {
1023         cntrl,                          cntrl,
1024         cntrl,                          cntrl,
1025         cntrl,                          cntrl,
1026         cntrl,                          cntrl,
1027         cntrl,                          cntrl | space | blank,
1028         cntrl | space,                  cntrl | space,
1029         cntrl | space,                  cntrl | space,
1030         cntrl,                          cntrl,
1031         cntrl,                          cntrl,
1032         cntrl,                          cntrl,
1033         cntrl,                          cntrl,
1034         cntrl,                          cntrl,
1035         cntrl,                          cntrl,
1036         cntrl,                          cntrl,
1037         cntrl,                          cntrl,
1038         cntrl,                          cntrl,
1039         space | blank | print,          punct | print,
1040         punct | print,                  punct | print,
1041         punct | print,                  punct | print,
1042         punct | print,                  punct | print,
1043         punct | print,                  punct | print,
1044         punct | print,                  punct | print,
1045         punct | print,                  punct | print,
1046         punct | print,                  punct | print,
1047         digit | print | xdigit,         digit | print | xdigit,
1048         digit | print | xdigit,         digit | print | xdigit,
1049         digit | print | xdigit,         digit | print | xdigit,
1050         digit | print | xdigit,         digit | print | xdigit,
1051         digit | print | xdigit,         digit | print | xdigit,
1052         punct | print,                  punct | print,
1053         punct | print,                  punct | print,
1054         punct | print,                  punct | print,
1055         punct | print,                  upper | xdigit | print | alpha,
1056         upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1057         upper | xdigit | print | alpha, upper | xdigit | print | alpha,
1058         upper | xdigit | print | alpha, upper | print | alpha,
1059         upper | print | alpha,          upper | print | alpha,
1060         upper | print | alpha,          upper | print | alpha,
1061         upper | print | alpha,          upper | print | alpha,
1062         upper | print | alpha,          upper | print | alpha,
1063         upper | print | alpha,          upper | print | alpha,
1064         upper | print | alpha,          upper | print | alpha,
1065         upper | print | alpha,          upper | print | alpha,
1066         upper | print | alpha,          upper | print | alpha,
1067         upper | print | alpha,          upper | print | alpha,
1068         upper | print | alpha,          punct | print,
1069         punct | print,                  punct | print,
1070         punct | print,                  punct | print,
1071         punct | print,                  lower | xdigit | print | alpha,
1072         lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1073         lower | xdigit | print | alpha, lower | xdigit | print | alpha,
1074         lower | xdigit | print | alpha, lower | print | alpha,
1075         lower | print | alpha,          lower | print | alpha,
1076         lower | print | alpha,          lower | print | alpha,
1077         lower | print | alpha,          lower | print | alpha,
1078         lower | print | alpha,          lower | print | alpha,
1079         lower | print | alpha,          lower | print | alpha,
1080         lower | print | alpha,          lower | print | alpha,
1081         lower | print | alpha,          lower | print | alpha,
1082         lower | print | alpha,          lower | print | alpha,
1083         lower | print | alpha,          lower | print | alpha,
1084         lower | print | alpha,          punct | print,
1085         punct | print,                  punct | print,
1086         punct | print,                  cntrl,
1087         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1088         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1089         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1090         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1091         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1092         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1093         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1094         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1095     };
1096     return builtin_table;
1097 }
1098 #else
1099 const ctype<char>::mask*
1100 ctype<char>::classic_table()  _NOEXCEPT
1101 {
1102 #if defined(__APPLE__) || defined(__FreeBSD__)
1103     return _DefaultRuneLocale.__runetype;
1104 #elif defined(__NetBSD__)
1105     return _C_ctype_tab_ + 1;
1106 #elif defined(__GLIBC__)
1107     return _LIBCPP_GET_C_LOCALE->__ctype_b;
1108 #elif __sun__
1109     return __ctype_mask;
1110 #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
1111     return _ctype+1; // internal ctype mask table defined in msvcrt.dll
1112 // This is assumed to be safe, which is a nonsense assumption because we're
1113 // going to end up dereferencing it later...
1114 #elif defined(__EMSCRIPTEN__)
1115     return *__ctype_b_loc();
1116 #elif defined(_NEWLIB_VERSION)
1117     // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
1118     return _ctype_ + 1;
1119 #elif defined(_AIX)
1120     return (const unsigned int *)__lc_ctype_ptr->obj->mask;
1121 #else
1122     // Platform not supported: abort so the person doing the port knows what to
1123     // fix
1124 # warning  ctype<char>::classic_table() is not implemented
1125     printf("ctype<char>::classic_table() is not implemented\n");
1126     abort();
1127     return NULL;
1128 #endif
1129 }
1130 #endif
1131 
1132 #if defined(__GLIBC__)
1133 const int*
1134 ctype<char>::__classic_lower_table() _NOEXCEPT
1135 {
1136     return _LIBCPP_GET_C_LOCALE->__ctype_tolower;
1137 }
1138 
1139 const int*
1140 ctype<char>::__classic_upper_table() _NOEXCEPT
1141 {
1142     return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
1143 }
1144 #elif __NetBSD__
1145 const short*
1146 ctype<char>::__classic_lower_table() _NOEXCEPT
1147 {
1148     return _C_tolower_tab_ + 1;
1149 }
1150 
1151 const short*
1152 ctype<char>::__classic_upper_table() _NOEXCEPT
1153 {
1154     return _C_toupper_tab_ + 1;
1155 }
1156 
1157 #elif defined(__EMSCRIPTEN__)
1158 const int*
1159 ctype<char>::__classic_lower_table() _NOEXCEPT
1160 {
1161     return *__ctype_tolower_loc();
1162 }
1163 
1164 const int*
1165 ctype<char>::__classic_upper_table() _NOEXCEPT
1166 {
1167     return *__ctype_toupper_loc();
1168 }
1169 #endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__
1170 
1171 // template <> class ctype_byname<char>
1172 
1173 ctype_byname<char>::ctype_byname(const char* name, size_t refs)
1174     : ctype<char>(0, false, refs),
1175       __l(newlocale(LC_ALL_MASK, name, 0))
1176 {
1177     if (__l == 0)
1178         __throw_runtime_error("ctype_byname<char>::ctype_byname"
1179                             " failed to construct for " + string(name));
1180 }
1181 
1182 ctype_byname<char>::ctype_byname(const string& name, size_t refs)
1183     : ctype<char>(0, false, refs),
1184       __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1185 {
1186     if (__l == 0)
1187         __throw_runtime_error("ctype_byname<char>::ctype_byname"
1188                             " failed to construct for " + name);
1189 }
1190 
1191 ctype_byname<char>::~ctype_byname()
1192 {
1193     freelocale(__l);
1194 }
1195 
1196 char
1197 ctype_byname<char>::do_toupper(char_type c) const
1198 {
1199     return static_cast<char>(toupper_l(static_cast<unsigned char>(c), __l));
1200 }
1201 
1202 const char*
1203 ctype_byname<char>::do_toupper(char_type* low, const char_type* high) const
1204 {
1205     for (; low != high; ++low)
1206         *low = static_cast<char>(toupper_l(static_cast<unsigned char>(*low), __l));
1207     return low;
1208 }
1209 
1210 char
1211 ctype_byname<char>::do_tolower(char_type c) const
1212 {
1213     return static_cast<char>(tolower_l(static_cast<unsigned char>(c), __l));
1214 }
1215 
1216 const char*
1217 ctype_byname<char>::do_tolower(char_type* low, const char_type* high) const
1218 {
1219     for (; low != high; ++low)
1220         *low = static_cast<char>(tolower_l(static_cast<unsigned char>(*low), __l));
1221     return low;
1222 }
1223 
1224 // template <> class ctype_byname<wchar_t>
1225 
1226 ctype_byname<wchar_t>::ctype_byname(const char* name, size_t refs)
1227     : ctype<wchar_t>(refs),
1228       __l(newlocale(LC_ALL_MASK, name, 0))
1229 {
1230     if (__l == 0)
1231         __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1232                             " failed to construct for " + string(name));
1233 }
1234 
1235 ctype_byname<wchar_t>::ctype_byname(const string& name, size_t refs)
1236     : ctype<wchar_t>(refs),
1237       __l(newlocale(LC_ALL_MASK, name.c_str(), 0))
1238 {
1239     if (__l == 0)
1240         __throw_runtime_error("ctype_byname<wchar_t>::ctype_byname"
1241                             " failed to construct for " + name);
1242 }
1243 
1244 ctype_byname<wchar_t>::~ctype_byname()
1245 {
1246     freelocale(__l);
1247 }
1248 
1249 bool
1250 ctype_byname<wchar_t>::do_is(mask m, char_type c) const
1251 {
1252 #ifdef _LIBCPP_WCTYPE_IS_MASK
1253     return static_cast<bool>(iswctype_l(c, m, __l));
1254 #else
1255     bool result = false;
1256     wint_t ch = static_cast<wint_t>(c);
1257     if ((m & space) == space) result |= (iswspace_l(ch, __l) != 0);
1258     if ((m & print) == print) result |= (iswprint_l(ch, __l) != 0);
1259     if ((m & cntrl) == cntrl) result |= (iswcntrl_l(ch, __l) != 0);
1260     if ((m & upper) == upper) result |= (iswupper_l(ch, __l) != 0);
1261     if ((m & lower) == lower) result |= (iswlower_l(ch, __l) != 0);
1262     if ((m & alpha) == alpha) result |= (iswalpha_l(ch, __l) != 0);
1263     if ((m & digit) == digit) result |= (iswdigit_l(ch, __l) != 0);
1264     if ((m & punct) == punct) result |= (iswpunct_l(ch, __l) != 0);
1265     if ((m & xdigit) == xdigit) result |= (iswxdigit_l(ch, __l) != 0);
1266     if ((m & blank) == blank) result |= (iswblank_l(ch, __l) != 0);
1267     return result;
1268 #endif
1269 }
1270 
1271 const wchar_t*
1272 ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const
1273 {
1274     for (; low != high; ++low, ++vec)
1275     {
1276         if (isascii(*low))
1277             *vec = static_cast<mask>(ctype<char>::classic_table()[*low]);
1278         else
1279         {
1280             *vec = 0;
1281             wint_t ch = static_cast<wint_t>(*low);
1282             if (iswspace_l(ch, __l))
1283                 *vec |= space;
1284 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
1285             if (iswprint_l(ch, __l))
1286                 *vec |= print;
1287 #endif
1288             if (iswcntrl_l(ch, __l))
1289                 *vec |= cntrl;
1290             if (iswupper_l(ch, __l))
1291                 *vec |= upper;
1292             if (iswlower_l(ch, __l))
1293                 *vec |= lower;
1294 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
1295             if (iswalpha_l(ch, __l))
1296                 *vec |= alpha;
1297 #endif
1298             if (iswdigit_l(ch, __l))
1299                 *vec |= digit;
1300             if (iswpunct_l(ch, __l))
1301                 *vec |= punct;
1302 #ifndef _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
1303             if (iswxdigit_l(ch, __l))
1304                 *vec |= xdigit;
1305 #endif
1306 #if !defined(__sun__)
1307             if (iswblank_l(ch, __l))
1308                 *vec |= blank;
1309 #endif
1310         }
1311     }
1312     return low;
1313 }
1314 
1315 const wchar_t*
1316 ctype_byname<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const
1317 {
1318     for (; low != high; ++low)
1319     {
1320 #ifdef _LIBCPP_WCTYPE_IS_MASK
1321         if (iswctype_l(*low, m, __l))
1322             break;
1323 #else
1324         wint_t ch = static_cast<wint_t>(*low);
1325         if ((m & space) == space && iswspace_l(ch, __l)) break;
1326         if ((m & print) == print && iswprint_l(ch, __l)) break;
1327         if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) break;
1328         if ((m & upper) == upper && iswupper_l(ch, __l)) break;
1329         if ((m & lower) == lower && iswlower_l(ch, __l)) break;
1330         if ((m & alpha) == alpha && iswalpha_l(ch, __l)) break;
1331         if ((m & digit) == digit && iswdigit_l(ch, __l)) break;
1332         if ((m & punct) == punct && iswpunct_l(ch, __l)) break;
1333         if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) break;
1334         if ((m & blank) == blank && iswblank_l(ch, __l)) break;
1335 #endif
1336     }
1337     return low;
1338 }
1339 
1340 const wchar_t*
1341 ctype_byname<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const
1342 {
1343     for (; low != high; ++low)
1344     {
1345 #ifdef _LIBCPP_WCTYPE_IS_MASK
1346         if (!iswctype_l(*low, m, __l))
1347             break;
1348 #else
1349         wint_t ch = static_cast<wint_t>(*low);
1350         if ((m & space) == space && iswspace_l(ch, __l)) continue;
1351         if ((m & print) == print && iswprint_l(ch, __l)) continue;
1352         if ((m & cntrl) == cntrl && iswcntrl_l(ch, __l)) continue;
1353         if ((m & upper) == upper && iswupper_l(ch, __l)) continue;
1354         if ((m & lower) == lower && iswlower_l(ch, __l)) continue;
1355         if ((m & alpha) == alpha && iswalpha_l(ch, __l)) continue;
1356         if ((m & digit) == digit && iswdigit_l(ch, __l)) continue;
1357         if ((m & punct) == punct && iswpunct_l(ch, __l)) continue;
1358         if ((m & xdigit) == xdigit && iswxdigit_l(ch, __l)) continue;
1359         if ((m & blank) == blank && iswblank_l(ch, __l)) continue;
1360         break;
1361 #endif
1362     }
1363     return low;
1364 }
1365 
1366 wchar_t
1367 ctype_byname<wchar_t>::do_toupper(char_type c) const
1368 {
1369     return towupper_l(c, __l);
1370 }
1371 
1372 const wchar_t*
1373 ctype_byname<wchar_t>::do_toupper(char_type* low, const char_type* high) const
1374 {
1375     for (; low != high; ++low)
1376         *low = towupper_l(*low, __l);
1377     return low;
1378 }
1379 
1380 wchar_t
1381 ctype_byname<wchar_t>::do_tolower(char_type c) const
1382 {
1383     return towlower_l(c, __l);
1384 }
1385 
1386 const wchar_t*
1387 ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const
1388 {
1389     for (; low != high; ++low)
1390         *low = towlower_l(*low, __l);
1391     return low;
1392 }
1393 
1394 wchar_t
1395 ctype_byname<wchar_t>::do_widen(char c) const
1396 {
1397     return __libcpp_btowc_l(c, __l);
1398 }
1399 
1400 const char*
1401 ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const
1402 {
1403     for (; low != high; ++low, ++dest)
1404         *dest = __libcpp_btowc_l(*low, __l);
1405     return low;
1406 }
1407 
1408 char
1409 ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const
1410 {
1411     int r = __libcpp_wctob_l(c, __l);
1412     return r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
1413 }
1414 
1415 const wchar_t*
1416 ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const
1417 {
1418     for (; low != high; ++low, ++dest)
1419     {
1420         int r = __libcpp_wctob_l(*low, __l);
1421         *dest = r != static_cast<int>(WEOF) ? static_cast<char>(r) : dfault;
1422     }
1423     return low;
1424 }
1425 
1426 // template <> class codecvt<char, char, mbstate_t>
1427 
1428 locale::id codecvt<char, char, mbstate_t>::id;
1429 
1430 codecvt<char, char, mbstate_t>::~codecvt()
1431 {
1432 }
1433 
1434 codecvt<char, char, mbstate_t>::result
1435 codecvt<char, char, mbstate_t>::do_out(state_type&,
1436     const intern_type* frm, const intern_type*, const intern_type*& frm_nxt,
1437     extern_type* to, extern_type*, extern_type*& to_nxt) const
1438 {
1439     frm_nxt = frm;
1440     to_nxt = to;
1441     return noconv;
1442 }
1443 
1444 codecvt<char, char, mbstate_t>::result
1445 codecvt<char, char, mbstate_t>::do_in(state_type&,
1446     const extern_type* frm, const extern_type*, const extern_type*& frm_nxt,
1447     intern_type* to, intern_type*, intern_type*& to_nxt) const
1448 {
1449     frm_nxt = frm;
1450     to_nxt = to;
1451     return noconv;
1452 }
1453 
1454 codecvt<char, char, mbstate_t>::result
1455 codecvt<char, char, mbstate_t>::do_unshift(state_type&,
1456     extern_type* to, extern_type*, extern_type*& to_nxt) const
1457 {
1458     to_nxt = to;
1459     return noconv;
1460 }
1461 
1462 int
1463 codecvt<char, char, mbstate_t>::do_encoding() const  _NOEXCEPT
1464 {
1465     return 1;
1466 }
1467 
1468 bool
1469 codecvt<char, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT
1470 {
1471     return true;
1472 }
1473 
1474 int
1475 codecvt<char, char, mbstate_t>::do_length(state_type&,
1476     const extern_type* frm, const extern_type* end, size_t mx) const
1477 {
1478     return static_cast<int>(min<size_t>(mx, static_cast<size_t>(end-frm)));
1479 }
1480 
1481 int
1482 codecvt<char, char, mbstate_t>::do_max_length() const  _NOEXCEPT
1483 {
1484     return 1;
1485 }
1486 
1487 // template <> class codecvt<wchar_t, char, mbstate_t>
1488 
1489 locale::id codecvt<wchar_t, char, mbstate_t>::id;
1490 
1491 codecvt<wchar_t, char, mbstate_t>::codecvt(size_t refs)
1492     : locale::facet(refs),
1493       __l(_LIBCPP_GET_C_LOCALE)
1494 {
1495 }
1496 
1497 codecvt<wchar_t, char, mbstate_t>::codecvt(const char* nm, size_t refs)
1498     : locale::facet(refs),
1499       __l(newlocale(LC_ALL_MASK, nm, 0))
1500 {
1501     if (__l == 0)
1502         __throw_runtime_error("codecvt_byname<wchar_t, char, mbstate_t>::codecvt_byname"
1503                             " failed to construct for " + string(nm));
1504 }
1505 
1506 codecvt<wchar_t, char, mbstate_t>::~codecvt()
1507 {
1508     if (__l != _LIBCPP_GET_C_LOCALE)
1509         freelocale(__l);
1510 }
1511 
1512 codecvt<wchar_t, char, mbstate_t>::result
1513 codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st,
1514     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
1515     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1516 {
1517     // look for first internal null in frm
1518     const intern_type* fend = frm;
1519     for (; fend != frm_end; ++fend)
1520         if (*fend == 0)
1521             break;
1522     // loop over all null-terminated sequences in frm
1523     to_nxt = to;
1524     for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1525     {
1526         // save state in case it is needed to recover to_nxt on error
1527         mbstate_t save_state = st;
1528         size_t n = __libcpp_wcsnrtombs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1529                                      static_cast<size_t>(to_end-to), &st, __l);
1530         if (n == size_t(-1))
1531         {
1532             // need to recover to_nxt
1533             for (to_nxt = to; frm != frm_nxt; ++frm)
1534             {
1535                 n = __libcpp_wcrtomb_l(to_nxt, *frm, &save_state, __l);
1536                 if (n == size_t(-1))
1537                     break;
1538                 to_nxt += n;
1539             }
1540             frm_nxt = frm;
1541             return error;
1542         }
1543         if (n == 0)
1544             return partial;
1545         to_nxt += n;
1546         if (to_nxt == to_end)
1547             break;
1548         if (fend != frm_end)  // set up next null terminated sequence
1549         {
1550             // Try to write the terminating null
1551             extern_type tmp[MB_LEN_MAX];
1552             n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l);
1553             if (n == size_t(-1))  // on error
1554                 return error;
1555             if (n > static_cast<size_t>(to_end-to_nxt))  // is there room?
1556                 return partial;
1557             for (extern_type* p = tmp; n; --n)  // write it
1558                 *to_nxt++ = *p++;
1559             ++frm_nxt;
1560             // look for next null in frm
1561             for (fend = frm_nxt; fend != frm_end; ++fend)
1562                 if (*fend == 0)
1563                     break;
1564         }
1565     }
1566     return frm_nxt == frm_end ? ok : partial;
1567 }
1568 
1569 codecvt<wchar_t, char, mbstate_t>::result
1570 codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st,
1571     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
1572     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
1573 {
1574     // look for first internal null in frm
1575     const extern_type* fend = frm;
1576     for (; fend != frm_end; ++fend)
1577         if (*fend == 0)
1578             break;
1579     // loop over all null-terminated sequences in frm
1580     to_nxt = to;
1581     for (frm_nxt = frm; frm != frm_end && to != to_end; frm = frm_nxt, to = to_nxt)
1582     {
1583         // save state in case it is needed to recover to_nxt on error
1584         mbstate_t save_state = st;
1585         size_t n = __libcpp_mbsnrtowcs_l(to, &frm_nxt, static_cast<size_t>(fend-frm),
1586                                      static_cast<size_t>(to_end-to), &st, __l);
1587         if (n == size_t(-1))
1588         {
1589             // need to recover to_nxt
1590             for (to_nxt = to; frm != frm_nxt; ++to_nxt)
1591             {
1592                 n = __libcpp_mbrtowc_l(to_nxt, frm, static_cast<size_t>(fend-frm),
1593                                    &save_state, __l);
1594                 switch (n)
1595                 {
1596                 case 0:
1597                     ++frm;
1598                     break;
1599                 case size_t(-1):
1600                     frm_nxt = frm;
1601                     return error;
1602                 case size_t(-2):
1603                     frm_nxt = frm;
1604                     return partial;
1605                 default:
1606                     frm += n;
1607                     break;
1608                 }
1609             }
1610             frm_nxt = frm;
1611             return frm_nxt == frm_end ? ok : partial;
1612         }
1613         if (n == size_t(-1))
1614             return error;
1615         to_nxt += n;
1616         if (to_nxt == to_end)
1617             break;
1618         if (fend != frm_end)  // set up next null terminated sequence
1619         {
1620             // Try to write the terminating null
1621             n = __libcpp_mbrtowc_l(to_nxt, frm_nxt, 1, &st, __l);
1622             if (n != 0)  // on error
1623                 return error;
1624             ++to_nxt;
1625             ++frm_nxt;
1626             // look for next null in frm
1627             for (fend = frm_nxt; fend != frm_end; ++fend)
1628                 if (*fend == 0)
1629                     break;
1630         }
1631     }
1632     return frm_nxt == frm_end ? ok : partial;
1633 }
1634 
1635 codecvt<wchar_t, char, mbstate_t>::result
1636 codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st,
1637     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
1638 {
1639     to_nxt = to;
1640     extern_type tmp[MB_LEN_MAX];
1641     size_t n = __libcpp_wcrtomb_l(tmp, intern_type(), &st, __l);
1642     if (n == size_t(-1) || n == 0)  // on error
1643         return error;
1644     --n;
1645     if (n > static_cast<size_t>(to_end-to_nxt))  // is there room?
1646         return partial;
1647     for (extern_type* p = tmp; n; --n)  // write it
1648         *to_nxt++ = *p++;
1649     return ok;
1650 }
1651 
1652 int
1653 codecvt<wchar_t, char, mbstate_t>::do_encoding() const  _NOEXCEPT
1654 {
1655     if (__libcpp_mbtowc_l(nullptr, nullptr, MB_LEN_MAX, __l) != 0)
1656         return -1;
1657 
1658     // stateless encoding
1659     if (__l == 0 || __libcpp_mb_cur_max_l(__l) == 1)  // there are no known constant length encodings
1660         return 1;                // which take more than 1 char to form a wchar_t
1661     return 0;
1662 }
1663 
1664 bool
1665 codecvt<wchar_t, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT
1666 {
1667     return false;
1668 }
1669 
1670 int
1671 codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st,
1672     const extern_type* frm, const extern_type* frm_end, size_t mx) const
1673 {
1674     int nbytes = 0;
1675     for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t)
1676     {
1677         size_t n = __libcpp_mbrlen_l(frm, static_cast<size_t>(frm_end-frm), &st, __l);
1678         switch (n)
1679         {
1680         case 0:
1681             ++nbytes;
1682             ++frm;
1683             break;
1684         case size_t(-1):
1685         case size_t(-2):
1686             return nbytes;
1687         default:
1688             nbytes += n;
1689             frm += n;
1690             break;
1691         }
1692     }
1693     return nbytes;
1694 }
1695 
1696 int
1697 codecvt<wchar_t, char, mbstate_t>::do_max_length() const  _NOEXCEPT
1698 {
1699     return __l == 0 ? 1 : static_cast<int>(__libcpp_mb_cur_max_l(__l));
1700 }
1701 
1702 //                                     Valid UTF ranges
1703 //     UTF-32               UTF-16                          UTF-8               # of code points
1704 //                     first      second       first   second    third   fourth
1705 // 000000 - 00007F  0000 - 007F               00 - 7F                                 127
1706 // 000080 - 0007FF  0080 - 07FF               C2 - DF, 80 - BF                       1920
1707 // 000800 - 000FFF  0800 - 0FFF               E0 - E0, A0 - BF, 80 - BF              2048
1708 // 001000 - 00CFFF  1000 - CFFF               E1 - EC, 80 - BF, 80 - BF             49152
1709 // 00D000 - 00D7FF  D000 - D7FF               ED - ED, 80 - 9F, 80 - BF              2048
1710 // 00D800 - 00DFFF                invalid
1711 // 00E000 - 00FFFF  E000 - FFFF               EE - EF, 80 - BF, 80 - BF              8192
1712 // 010000 - 03FFFF  D800 - D8BF, DC00 - DFFF  F0 - F0, 90 - BF, 80 - BF, 80 - BF   196608
1713 // 040000 - 0FFFFF  D8C0 - DBBF, DC00 - DFFF  F1 - F3, 80 - BF, 80 - BF, 80 - BF   786432
1714 // 100000 - 10FFFF  DBC0 - DBFF, DC00 - DFFF  F4 - F4, 80 - 8F, 80 - BF, 80 - BF    65536
1715 
1716 static
1717 codecvt_base::result
1718 utf16_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
1719               uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1720               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1721 {
1722     frm_nxt = frm;
1723     to_nxt = to;
1724     if (mode & generate_header)
1725     {
1726         if (to_end-to_nxt < 3)
1727             return codecvt_base::partial;
1728         *to_nxt++ = static_cast<uint8_t>(0xEF);
1729         *to_nxt++ = static_cast<uint8_t>(0xBB);
1730         *to_nxt++ = static_cast<uint8_t>(0xBF);
1731     }
1732     for (; frm_nxt < frm_end; ++frm_nxt)
1733     {
1734         uint16_t wc1 = *frm_nxt;
1735         if (wc1 > Maxcode)
1736             return codecvt_base::error;
1737         if (wc1 < 0x0080)
1738         {
1739             if (to_end-to_nxt < 1)
1740                 return codecvt_base::partial;
1741             *to_nxt++ = static_cast<uint8_t>(wc1);
1742         }
1743         else if (wc1 < 0x0800)
1744         {
1745             if (to_end-to_nxt < 2)
1746                 return codecvt_base::partial;
1747             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1748             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1749         }
1750         else if (wc1 < 0xD800)
1751         {
1752             if (to_end-to_nxt < 3)
1753                 return codecvt_base::partial;
1754             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
1755             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1756             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
1757         }
1758         else if (wc1 < 0xDC00)
1759         {
1760             if (frm_end-frm_nxt < 2)
1761                 return codecvt_base::partial;
1762             uint16_t wc2 = frm_nxt[1];
1763             if ((wc2 & 0xFC00) != 0xDC00)
1764                 return codecvt_base::error;
1765             if (to_end-to_nxt < 4)
1766                 return codecvt_base::partial;
1767             if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1768                 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1769                 return codecvt_base::error;
1770             ++frm_nxt;
1771             uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1772             *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1773             *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4)     | ((wc1 & 0x003C) >> 2));
1774             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1775             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc2 & 0x003F));
1776         }
1777         else if (wc1 < 0xE000)
1778         {
1779             return codecvt_base::error;
1780         }
1781         else
1782         {
1783             if (to_end-to_nxt < 3)
1784                 return codecvt_base::partial;
1785             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
1786             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1787             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
1788         }
1789     }
1790     return codecvt_base::ok;
1791 }
1792 
1793 static
1794 codecvt_base::result
1795 utf16_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
1796               uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
1797               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1798 {
1799     frm_nxt = frm;
1800     to_nxt = to;
1801     if (mode & generate_header)
1802     {
1803         if (to_end-to_nxt < 3)
1804             return codecvt_base::partial;
1805         *to_nxt++ = static_cast<uint8_t>(0xEF);
1806         *to_nxt++ = static_cast<uint8_t>(0xBB);
1807         *to_nxt++ = static_cast<uint8_t>(0xBF);
1808     }
1809     for (; frm_nxt < frm_end; ++frm_nxt)
1810     {
1811         uint16_t wc1 = static_cast<uint16_t>(*frm_nxt);
1812         if (wc1 > Maxcode)
1813             return codecvt_base::error;
1814         if (wc1 < 0x0080)
1815         {
1816             if (to_end-to_nxt < 1)
1817                 return codecvt_base::partial;
1818             *to_nxt++ = static_cast<uint8_t>(wc1);
1819         }
1820         else if (wc1 < 0x0800)
1821         {
1822             if (to_end-to_nxt < 2)
1823                 return codecvt_base::partial;
1824             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc1 >> 6));
1825             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc1 & 0x03F));
1826         }
1827         else if (wc1 < 0xD800)
1828         {
1829             if (to_end-to_nxt < 3)
1830                 return codecvt_base::partial;
1831             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
1832             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1833             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
1834         }
1835         else if (wc1 < 0xDC00)
1836         {
1837             if (frm_end-frm_nxt < 2)
1838                 return codecvt_base::partial;
1839             uint16_t wc2 = static_cast<uint16_t>(frm_nxt[1]);
1840             if ((wc2 & 0xFC00) != 0xDC00)
1841                 return codecvt_base::error;
1842             if (to_end-to_nxt < 4)
1843                 return codecvt_base::partial;
1844             if (((((wc1 & 0x03C0UL) >> 6) + 1) << 16) +
1845                 ((wc1 & 0x003FUL) << 10) + (wc2 & 0x03FF) > Maxcode)
1846                 return codecvt_base::error;
1847             ++frm_nxt;
1848             uint8_t z = ((wc1 & 0x03C0) >> 6) + 1;
1849             *to_nxt++ = static_cast<uint8_t>(0xF0 | (z >> 2));
1850             *to_nxt++ = static_cast<uint8_t>(0x80 | ((z & 0x03) << 4)     | ((wc1 & 0x003C) >> 2));
1851             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0003) << 4) | ((wc2 & 0x03C0) >> 6));
1852             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc2 & 0x003F));
1853         }
1854         else if (wc1 < 0xE000)
1855         {
1856             return codecvt_base::error;
1857         }
1858         else
1859         {
1860             if (to_end-to_nxt < 3)
1861                 return codecvt_base::partial;
1862             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc1 >> 12));
1863             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc1 & 0x0FC0) >> 6));
1864             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc1 & 0x003F));
1865         }
1866     }
1867     return codecvt_base::ok;
1868 }
1869 
1870 static
1871 codecvt_base::result
1872 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1873               uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
1874               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1875 {
1876     frm_nxt = frm;
1877     to_nxt = to;
1878     if (mode & consume_header)
1879     {
1880         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
1881                                                           frm_nxt[2] == 0xBF)
1882             frm_nxt += 3;
1883     }
1884     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
1885     {
1886         uint8_t c1 = *frm_nxt;
1887         if (c1 > Maxcode)
1888             return codecvt_base::error;
1889         if (c1 < 0x80)
1890         {
1891             *to_nxt = static_cast<uint16_t>(c1);
1892             ++frm_nxt;
1893         }
1894         else if (c1 < 0xC2)
1895         {
1896             return codecvt_base::error;
1897         }
1898         else if (c1 < 0xE0)
1899         {
1900             if (frm_end-frm_nxt < 2)
1901                 return codecvt_base::partial;
1902             uint8_t c2 = frm_nxt[1];
1903             if ((c2 & 0xC0) != 0x80)
1904                 return codecvt_base::error;
1905             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
1906             if (t > Maxcode)
1907                 return codecvt_base::error;
1908             *to_nxt = t;
1909             frm_nxt += 2;
1910         }
1911         else if (c1 < 0xF0)
1912         {
1913             if (frm_end-frm_nxt < 3)
1914                 return codecvt_base::partial;
1915             uint8_t c2 = frm_nxt[1];
1916             uint8_t c3 = frm_nxt[2];
1917             switch (c1)
1918             {
1919             case 0xE0:
1920                 if ((c2 & 0xE0) != 0xA0)
1921                     return codecvt_base::error;
1922                  break;
1923             case 0xED:
1924                 if ((c2 & 0xE0) != 0x80)
1925                     return codecvt_base::error;
1926                  break;
1927             default:
1928                 if ((c2 & 0xC0) != 0x80)
1929                     return codecvt_base::error;
1930                  break;
1931             }
1932             if ((c3 & 0xC0) != 0x80)
1933                 return codecvt_base::error;
1934             uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
1935                                              | ((c2 & 0x3F) << 6)
1936                                              |  (c3 & 0x3F));
1937             if (t > Maxcode)
1938                 return codecvt_base::error;
1939             *to_nxt = t;
1940             frm_nxt += 3;
1941         }
1942         else if (c1 < 0xF5)
1943         {
1944             if (frm_end-frm_nxt < 4)
1945                 return codecvt_base::partial;
1946             uint8_t c2 = frm_nxt[1];
1947             uint8_t c3 = frm_nxt[2];
1948             uint8_t c4 = frm_nxt[3];
1949             switch (c1)
1950             {
1951             case 0xF0:
1952                 if (!(0x90 <= c2 && c2 <= 0xBF))
1953                     return codecvt_base::error;
1954                  break;
1955             case 0xF4:
1956                 if ((c2 & 0xF0) != 0x80)
1957                     return codecvt_base::error;
1958                  break;
1959             default:
1960                 if ((c2 & 0xC0) != 0x80)
1961                     return codecvt_base::error;
1962                  break;
1963             }
1964             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
1965                 return codecvt_base::error;
1966             if (to_end-to_nxt < 2)
1967                 return codecvt_base::partial;
1968             if ((((c1 & 7UL) << 18) +
1969                 ((c2 & 0x3FUL) << 12) +
1970                 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
1971                 return codecvt_base::error;
1972             *to_nxt = static_cast<uint16_t>(
1973                     0xD800
1974                   | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
1975                   | ((c2 & 0x0F) << 2)
1976                   | ((c3 & 0x30) >> 4));
1977             *++to_nxt = static_cast<uint16_t>(
1978                     0xDC00
1979                   | ((c3 & 0x0F) << 6)
1980                   |  (c4 & 0x3F));
1981             frm_nxt += 4;
1982         }
1983         else
1984         {
1985             return codecvt_base::error;
1986         }
1987     }
1988     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
1989 }
1990 
1991 static
1992 codecvt_base::result
1993 utf8_to_utf16(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
1994               uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
1995               unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
1996 {
1997     frm_nxt = frm;
1998     to_nxt = to;
1999     if (mode & consume_header)
2000     {
2001         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2002                                                           frm_nxt[2] == 0xBF)
2003             frm_nxt += 3;
2004     }
2005     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2006     {
2007         uint8_t c1 = *frm_nxt;
2008         if (c1 > Maxcode)
2009             return codecvt_base::error;
2010         if (c1 < 0x80)
2011         {
2012             *to_nxt = static_cast<uint32_t>(c1);
2013             ++frm_nxt;
2014         }
2015         else if (c1 < 0xC2)
2016         {
2017             return codecvt_base::error;
2018         }
2019         else if (c1 < 0xE0)
2020         {
2021             if (frm_end-frm_nxt < 2)
2022                 return codecvt_base::partial;
2023             uint8_t c2 = frm_nxt[1];
2024             if ((c2 & 0xC0) != 0x80)
2025                 return codecvt_base::error;
2026             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (c2 & 0x3F));
2027             if (t > Maxcode)
2028                 return codecvt_base::error;
2029             *to_nxt = static_cast<uint32_t>(t);
2030             frm_nxt += 2;
2031         }
2032         else if (c1 < 0xF0)
2033         {
2034             if (frm_end-frm_nxt < 3)
2035                 return codecvt_base::partial;
2036             uint8_t c2 = frm_nxt[1];
2037             uint8_t c3 = frm_nxt[2];
2038             switch (c1)
2039             {
2040             case 0xE0:
2041                 if ((c2 & 0xE0) != 0xA0)
2042                     return codecvt_base::error;
2043                  break;
2044             case 0xED:
2045                 if ((c2 & 0xE0) != 0x80)
2046                     return codecvt_base::error;
2047                  break;
2048             default:
2049                 if ((c2 & 0xC0) != 0x80)
2050                     return codecvt_base::error;
2051                  break;
2052             }
2053             if ((c3 & 0xC0) != 0x80)
2054                 return codecvt_base::error;
2055             uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2056                                              | ((c2 & 0x3F) << 6)
2057                                              |  (c3 & 0x3F));
2058             if (t > Maxcode)
2059                 return codecvt_base::error;
2060             *to_nxt = static_cast<uint32_t>(t);
2061             frm_nxt += 3;
2062         }
2063         else if (c1 < 0xF5)
2064         {
2065             if (frm_end-frm_nxt < 4)
2066                 return codecvt_base::partial;
2067             uint8_t c2 = frm_nxt[1];
2068             uint8_t c3 = frm_nxt[2];
2069             uint8_t c4 = frm_nxt[3];
2070             switch (c1)
2071             {
2072             case 0xF0:
2073                 if (!(0x90 <= c2 && c2 <= 0xBF))
2074                     return codecvt_base::error;
2075                  break;
2076             case 0xF4:
2077                 if ((c2 & 0xF0) != 0x80)
2078                     return codecvt_base::error;
2079                  break;
2080             default:
2081                 if ((c2 & 0xC0) != 0x80)
2082                     return codecvt_base::error;
2083                  break;
2084             }
2085             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2086                 return codecvt_base::error;
2087             if (to_end-to_nxt < 2)
2088                 return codecvt_base::partial;
2089             if ((((c1 & 7UL) << 18) +
2090                 ((c2 & 0x3FUL) << 12) +
2091                 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2092                 return codecvt_base::error;
2093             *to_nxt = static_cast<uint32_t>(
2094                     0xD800
2095                   | (((((c1 & 0x07) << 2) | ((c2 & 0x30) >> 4)) - 1) << 6)
2096                   | ((c2 & 0x0F) << 2)
2097                   | ((c3 & 0x30) >> 4));
2098             *++to_nxt = static_cast<uint32_t>(
2099                     0xDC00
2100                   | ((c3 & 0x0F) << 6)
2101                   |  (c4 & 0x3F));
2102             frm_nxt += 4;
2103         }
2104         else
2105         {
2106             return codecvt_base::error;
2107         }
2108     }
2109     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2110 }
2111 
2112 static
2113 int
2114 utf8_to_utf16_length(const uint8_t* frm, const uint8_t* frm_end,
2115                      size_t mx, unsigned long Maxcode = 0x10FFFF,
2116                      codecvt_mode mode = codecvt_mode(0))
2117 {
2118     const uint8_t* frm_nxt = frm;
2119     if (mode & consume_header)
2120     {
2121         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2122                                                           frm_nxt[2] == 0xBF)
2123             frm_nxt += 3;
2124     }
2125     for (size_t nchar16_t = 0; frm_nxt < frm_end && nchar16_t < mx; ++nchar16_t)
2126     {
2127         uint8_t c1 = *frm_nxt;
2128         if (c1 > Maxcode)
2129             break;
2130         if (c1 < 0x80)
2131         {
2132             ++frm_nxt;
2133         }
2134         else if (c1 < 0xC2)
2135         {
2136             break;
2137         }
2138         else if (c1 < 0xE0)
2139         {
2140             if ((frm_end-frm_nxt < 2) || (frm_nxt[1] & 0xC0) != 0x80)
2141                 break;
2142             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6) | (frm_nxt[1] & 0x3F));
2143             if (t > Maxcode)
2144                 break;
2145             frm_nxt += 2;
2146         }
2147         else if (c1 < 0xF0)
2148         {
2149             if (frm_end-frm_nxt < 3)
2150                 break;
2151             uint8_t c2 = frm_nxt[1];
2152             uint8_t c3 = frm_nxt[2];
2153             switch (c1)
2154             {
2155             case 0xE0:
2156                 if ((c2 & 0xE0) != 0xA0)
2157                     return static_cast<int>(frm_nxt - frm);
2158                 break;
2159             case 0xED:
2160                 if ((c2 & 0xE0) != 0x80)
2161                     return static_cast<int>(frm_nxt - frm);
2162                  break;
2163             default:
2164                 if ((c2 & 0xC0) != 0x80)
2165                     return static_cast<int>(frm_nxt - frm);
2166                  break;
2167             }
2168             if ((c3 & 0xC0) != 0x80)
2169                 break;
2170             if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2171                 break;
2172             frm_nxt += 3;
2173         }
2174         else if (c1 < 0xF5)
2175         {
2176             if (frm_end-frm_nxt < 4 || mx-nchar16_t < 2)
2177                 break;
2178             uint8_t c2 = frm_nxt[1];
2179             uint8_t c3 = frm_nxt[2];
2180             uint8_t c4 = frm_nxt[3];
2181             switch (c1)
2182             {
2183             case 0xF0:
2184                 if (!(0x90 <= c2 && c2 <= 0xBF))
2185                     return static_cast<int>(frm_nxt - frm);
2186                  break;
2187             case 0xF4:
2188                 if ((c2 & 0xF0) != 0x80)
2189                     return static_cast<int>(frm_nxt - frm);
2190                  break;
2191             default:
2192                 if ((c2 & 0xC0) != 0x80)
2193                     return static_cast<int>(frm_nxt - frm);
2194                  break;
2195             }
2196             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2197                 break;
2198             if ((((c1 & 7UL) << 18) +
2199                 ((c2 & 0x3FUL) << 12) +
2200                 ((c3 & 0x3FUL) << 6) + (c4 & 0x3F)) > Maxcode)
2201                 break;
2202             ++nchar16_t;
2203             frm_nxt += 4;
2204         }
2205         else
2206         {
2207             break;
2208         }
2209     }
2210     return static_cast<int>(frm_nxt - frm);
2211 }
2212 
2213 static
2214 codecvt_base::result
2215 ucs4_to_utf8(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2216              uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2217              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2218 {
2219     frm_nxt = frm;
2220     to_nxt = to;
2221     if (mode & generate_header)
2222     {
2223         if (to_end-to_nxt < 3)
2224             return codecvt_base::partial;
2225         *to_nxt++ = static_cast<uint8_t>(0xEF);
2226         *to_nxt++ = static_cast<uint8_t>(0xBB);
2227         *to_nxt++ = static_cast<uint8_t>(0xBF);
2228     }
2229     for (; frm_nxt < frm_end; ++frm_nxt)
2230     {
2231         uint32_t wc = *frm_nxt;
2232         if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2233             return codecvt_base::error;
2234         if (wc < 0x000080)
2235         {
2236             if (to_end-to_nxt < 1)
2237                 return codecvt_base::partial;
2238             *to_nxt++ = static_cast<uint8_t>(wc);
2239         }
2240         else if (wc < 0x000800)
2241         {
2242             if (to_end-to_nxt < 2)
2243                 return codecvt_base::partial;
2244             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2245             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2246         }
2247         else if (wc < 0x010000)
2248         {
2249             if (to_end-to_nxt < 3)
2250                 return codecvt_base::partial;
2251             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc >> 12));
2252             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2253             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc & 0x003F));
2254         }
2255         else // if (wc < 0x110000)
2256         {
2257             if (to_end-to_nxt < 4)
2258                 return codecvt_base::partial;
2259             *to_nxt++ = static_cast<uint8_t>(0xF0 |  (wc >> 18));
2260             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x03F000) >> 12));
2261             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x000FC0) >> 6));
2262             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc & 0x00003F));
2263         }
2264     }
2265     return codecvt_base::ok;
2266 }
2267 
2268 static
2269 codecvt_base::result
2270 utf8_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2271              uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2272              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2273 {
2274     frm_nxt = frm;
2275     to_nxt = to;
2276     if (mode & consume_header)
2277     {
2278         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2279                                                           frm_nxt[2] == 0xBF)
2280             frm_nxt += 3;
2281     }
2282     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2283     {
2284         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2285         if (c1 < 0x80)
2286         {
2287             if (c1 > Maxcode)
2288                 return codecvt_base::error;
2289             *to_nxt = static_cast<uint32_t>(c1);
2290             ++frm_nxt;
2291         }
2292         else if (c1 < 0xC2)
2293         {
2294             return codecvt_base::error;
2295         }
2296         else if (c1 < 0xE0)
2297         {
2298             if (frm_end-frm_nxt < 2)
2299                 return codecvt_base::partial;
2300             uint8_t c2 = frm_nxt[1];
2301             if ((c2 & 0xC0) != 0x80)
2302                 return codecvt_base::error;
2303             uint32_t t = static_cast<uint32_t>(((c1 & 0x1F) << 6)
2304                                               | (c2 & 0x3F));
2305             if (t > Maxcode)
2306                 return codecvt_base::error;
2307             *to_nxt = t;
2308             frm_nxt += 2;
2309         }
2310         else if (c1 < 0xF0)
2311         {
2312             if (frm_end-frm_nxt < 3)
2313                 return codecvt_base::partial;
2314             uint8_t c2 = frm_nxt[1];
2315             uint8_t c3 = frm_nxt[2];
2316             switch (c1)
2317             {
2318             case 0xE0:
2319                 if ((c2 & 0xE0) != 0xA0)
2320                     return codecvt_base::error;
2321                  break;
2322             case 0xED:
2323                 if ((c2 & 0xE0) != 0x80)
2324                     return codecvt_base::error;
2325                  break;
2326             default:
2327                 if ((c2 & 0xC0) != 0x80)
2328                     return codecvt_base::error;
2329                  break;
2330             }
2331             if ((c3 & 0xC0) != 0x80)
2332                 return codecvt_base::error;
2333             uint32_t t = static_cast<uint32_t>(((c1 & 0x0F) << 12)
2334                                              | ((c2 & 0x3F) << 6)
2335                                              |  (c3 & 0x3F));
2336             if (t > Maxcode)
2337                 return codecvt_base::error;
2338             *to_nxt = t;
2339             frm_nxt += 3;
2340         }
2341         else if (c1 < 0xF5)
2342         {
2343             if (frm_end-frm_nxt < 4)
2344                 return codecvt_base::partial;
2345             uint8_t c2 = frm_nxt[1];
2346             uint8_t c3 = frm_nxt[2];
2347             uint8_t c4 = frm_nxt[3];
2348             switch (c1)
2349             {
2350             case 0xF0:
2351                 if (!(0x90 <= c2 && c2 <= 0xBF))
2352                     return codecvt_base::error;
2353                  break;
2354             case 0xF4:
2355                 if ((c2 & 0xF0) != 0x80)
2356                     return codecvt_base::error;
2357                  break;
2358             default:
2359                 if ((c2 & 0xC0) != 0x80)
2360                     return codecvt_base::error;
2361                  break;
2362             }
2363             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2364                 return codecvt_base::error;
2365             uint32_t t = static_cast<uint32_t>(((c1 & 0x07) << 18)
2366                                              | ((c2 & 0x3F) << 12)
2367                                              | ((c3 & 0x3F) << 6)
2368                                              |  (c4 & 0x3F));
2369             if (t > Maxcode)
2370                 return codecvt_base::error;
2371             *to_nxt = t;
2372             frm_nxt += 4;
2373         }
2374         else
2375         {
2376             return codecvt_base::error;
2377         }
2378     }
2379     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2380 }
2381 
2382 static
2383 int
2384 utf8_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2385                     size_t mx, unsigned long Maxcode = 0x10FFFF,
2386                     codecvt_mode mode = codecvt_mode(0))
2387 {
2388     const uint8_t* frm_nxt = frm;
2389     if (mode & consume_header)
2390     {
2391         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2392                                                           frm_nxt[2] == 0xBF)
2393             frm_nxt += 3;
2394     }
2395     for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2396     {
2397         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2398         if (c1 < 0x80)
2399         {
2400             if (c1 > Maxcode)
2401                 break;
2402             ++frm_nxt;
2403         }
2404         else if (c1 < 0xC2)
2405         {
2406             break;
2407         }
2408         else if (c1 < 0xE0)
2409         {
2410             if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2411                 break;
2412             if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2413                 break;
2414             frm_nxt += 2;
2415         }
2416         else if (c1 < 0xF0)
2417         {
2418             if (frm_end-frm_nxt < 3)
2419                 break;
2420             uint8_t c2 = frm_nxt[1];
2421             uint8_t c3 = frm_nxt[2];
2422             switch (c1)
2423             {
2424             case 0xE0:
2425                 if ((c2 & 0xE0) != 0xA0)
2426                     return static_cast<int>(frm_nxt - frm);
2427                 break;
2428             case 0xED:
2429                 if ((c2 & 0xE0) != 0x80)
2430                     return static_cast<int>(frm_nxt - frm);
2431                  break;
2432             default:
2433                 if ((c2 & 0xC0) != 0x80)
2434                     return static_cast<int>(frm_nxt - frm);
2435                  break;
2436             }
2437             if ((c3 & 0xC0) != 0x80)
2438                 break;
2439             if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2440                 break;
2441             frm_nxt += 3;
2442         }
2443         else if (c1 < 0xF5)
2444         {
2445             if (frm_end-frm_nxt < 4)
2446                 break;
2447             uint8_t c2 = frm_nxt[1];
2448             uint8_t c3 = frm_nxt[2];
2449             uint8_t c4 = frm_nxt[3];
2450             switch (c1)
2451             {
2452             case 0xF0:
2453                 if (!(0x90 <= c2 && c2 <= 0xBF))
2454                     return static_cast<int>(frm_nxt - frm);
2455                  break;
2456             case 0xF4:
2457                 if ((c2 & 0xF0) != 0x80)
2458                     return static_cast<int>(frm_nxt - frm);
2459                  break;
2460             default:
2461                 if ((c2 & 0xC0) != 0x80)
2462                     return static_cast<int>(frm_nxt - frm);
2463                  break;
2464             }
2465             if ((c3 & 0xC0) != 0x80 || (c4 & 0xC0) != 0x80)
2466                 break;
2467             if ((((c1 & 0x07u) << 18) | ((c2 & 0x3Fu) << 12) |
2468                  ((c3 & 0x3Fu) << 6)  |  (c4 & 0x3Fu)) > Maxcode)
2469                 break;
2470             frm_nxt += 4;
2471         }
2472         else
2473         {
2474             break;
2475         }
2476     }
2477     return static_cast<int>(frm_nxt - frm);
2478 }
2479 
2480 static
2481 codecvt_base::result
2482 ucs2_to_utf8(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2483              uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2484              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2485 {
2486     frm_nxt = frm;
2487     to_nxt = to;
2488     if (mode & generate_header)
2489     {
2490         if (to_end-to_nxt < 3)
2491             return codecvt_base::partial;
2492         *to_nxt++ = static_cast<uint8_t>(0xEF);
2493         *to_nxt++ = static_cast<uint8_t>(0xBB);
2494         *to_nxt++ = static_cast<uint8_t>(0xBF);
2495     }
2496     for (; frm_nxt < frm_end; ++frm_nxt)
2497     {
2498         uint16_t wc = *frm_nxt;
2499         if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2500             return codecvt_base::error;
2501         if (wc < 0x0080)
2502         {
2503             if (to_end-to_nxt < 1)
2504                 return codecvt_base::partial;
2505             *to_nxt++ = static_cast<uint8_t>(wc);
2506         }
2507         else if (wc < 0x0800)
2508         {
2509             if (to_end-to_nxt < 2)
2510                 return codecvt_base::partial;
2511             *to_nxt++ = static_cast<uint8_t>(0xC0 | (wc >> 6));
2512             *to_nxt++ = static_cast<uint8_t>(0x80 | (wc & 0x03F));
2513         }
2514         else // if (wc <= 0xFFFF)
2515         {
2516             if (to_end-to_nxt < 3)
2517                 return codecvt_base::partial;
2518             *to_nxt++ = static_cast<uint8_t>(0xE0 |  (wc >> 12));
2519             *to_nxt++ = static_cast<uint8_t>(0x80 | ((wc & 0x0FC0) >> 6));
2520             *to_nxt++ = static_cast<uint8_t>(0x80 |  (wc & 0x003F));
2521         }
2522     }
2523     return codecvt_base::ok;
2524 }
2525 
2526 static
2527 codecvt_base::result
2528 utf8_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2529              uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2530              unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2531 {
2532     frm_nxt = frm;
2533     to_nxt = to;
2534     if (mode & consume_header)
2535     {
2536         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2537                                                           frm_nxt[2] == 0xBF)
2538             frm_nxt += 3;
2539     }
2540     for (; frm_nxt < frm_end && to_nxt < to_end; ++to_nxt)
2541     {
2542         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2543         if (c1 < 0x80)
2544         {
2545             if (c1 > Maxcode)
2546                 return codecvt_base::error;
2547             *to_nxt = static_cast<uint16_t>(c1);
2548             ++frm_nxt;
2549         }
2550         else if (c1 < 0xC2)
2551         {
2552             return codecvt_base::error;
2553         }
2554         else if (c1 < 0xE0)
2555         {
2556             if (frm_end-frm_nxt < 2)
2557                 return codecvt_base::partial;
2558             uint8_t c2 = frm_nxt[1];
2559             if ((c2 & 0xC0) != 0x80)
2560                 return codecvt_base::error;
2561             uint16_t t = static_cast<uint16_t>(((c1 & 0x1F) << 6)
2562                                               | (c2 & 0x3F));
2563             if (t > Maxcode)
2564                 return codecvt_base::error;
2565             *to_nxt = t;
2566             frm_nxt += 2;
2567         }
2568         else if (c1 < 0xF0)
2569         {
2570             if (frm_end-frm_nxt < 3)
2571                 return codecvt_base::partial;
2572             uint8_t c2 = frm_nxt[1];
2573             uint8_t c3 = frm_nxt[2];
2574             switch (c1)
2575             {
2576             case 0xE0:
2577                 if ((c2 & 0xE0) != 0xA0)
2578                     return codecvt_base::error;
2579                  break;
2580             case 0xED:
2581                 if ((c2 & 0xE0) != 0x80)
2582                     return codecvt_base::error;
2583                  break;
2584             default:
2585                 if ((c2 & 0xC0) != 0x80)
2586                     return codecvt_base::error;
2587                  break;
2588             }
2589             if ((c3 & 0xC0) != 0x80)
2590                 return codecvt_base::error;
2591             uint16_t t = static_cast<uint16_t>(((c1 & 0x0F) << 12)
2592                                              | ((c2 & 0x3F) << 6)
2593                                              |  (c3 & 0x3F));
2594             if (t > Maxcode)
2595                 return codecvt_base::error;
2596             *to_nxt = t;
2597             frm_nxt += 3;
2598         }
2599         else
2600         {
2601             return codecvt_base::error;
2602         }
2603     }
2604     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2605 }
2606 
2607 static
2608 int
2609 utf8_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2610                     size_t mx, unsigned long Maxcode = 0x10FFFF,
2611                     codecvt_mode mode = codecvt_mode(0))
2612 {
2613     const uint8_t* frm_nxt = frm;
2614     if (mode & consume_header)
2615     {
2616         if (frm_end-frm_nxt >= 3 && frm_nxt[0] == 0xEF && frm_nxt[1] == 0xBB &&
2617                                                           frm_nxt[2] == 0xBF)
2618             frm_nxt += 3;
2619     }
2620     for (size_t nchar32_t = 0; frm_nxt < frm_end && nchar32_t < mx; ++nchar32_t)
2621     {
2622         uint8_t c1 = static_cast<uint8_t>(*frm_nxt);
2623         if (c1 < 0x80)
2624         {
2625             if (c1 > Maxcode)
2626                 break;
2627             ++frm_nxt;
2628         }
2629         else if (c1 < 0xC2)
2630         {
2631             break;
2632         }
2633         else if (c1 < 0xE0)
2634         {
2635             if ((frm_end-frm_nxt < 2) || ((frm_nxt[1] & 0xC0) != 0x80))
2636                 break;
2637             if ((((c1 & 0x1Fu) << 6) | (frm_nxt[1] & 0x3Fu)) > Maxcode)
2638                 break;
2639             frm_nxt += 2;
2640         }
2641         else if (c1 < 0xF0)
2642         {
2643             if (frm_end-frm_nxt < 3)
2644                 break;
2645             uint8_t c2 = frm_nxt[1];
2646             uint8_t c3 = frm_nxt[2];
2647             switch (c1)
2648             {
2649             case 0xE0:
2650                 if ((c2 & 0xE0) != 0xA0)
2651                     return static_cast<int>(frm_nxt - frm);
2652                 break;
2653             case 0xED:
2654                 if ((c2 & 0xE0) != 0x80)
2655                     return static_cast<int>(frm_nxt - frm);
2656                  break;
2657             default:
2658                 if ((c2 & 0xC0) != 0x80)
2659                     return static_cast<int>(frm_nxt - frm);
2660                  break;
2661             }
2662             if ((c3 & 0xC0) != 0x80)
2663                 break;
2664             if ((((c1 & 0x0Fu) << 12) | ((c2 & 0x3Fu) << 6) | (c3 & 0x3Fu)) > Maxcode)
2665                 break;
2666             frm_nxt += 3;
2667         }
2668         else
2669         {
2670             break;
2671         }
2672     }
2673     return static_cast<int>(frm_nxt - frm);
2674 }
2675 
2676 static
2677 codecvt_base::result
2678 ucs4_to_utf16be(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2679                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2680                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2681 {
2682     frm_nxt = frm;
2683     to_nxt = to;
2684     if (mode & generate_header)
2685     {
2686         if (to_end-to_nxt < 2)
2687             return codecvt_base::partial;
2688         *to_nxt++ = static_cast<uint8_t>(0xFE);
2689         *to_nxt++ = static_cast<uint8_t>(0xFF);
2690     }
2691     for (; frm_nxt < frm_end; ++frm_nxt)
2692     {
2693         uint32_t wc = *frm_nxt;
2694         if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2695             return codecvt_base::error;
2696         if (wc < 0x010000)
2697         {
2698             if (to_end-to_nxt < 2)
2699                 return codecvt_base::partial;
2700             *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2701             *to_nxt++ = static_cast<uint8_t>(wc);
2702         }
2703         else
2704         {
2705             if (to_end-to_nxt < 4)
2706                 return codecvt_base::partial;
2707             uint16_t t = static_cast<uint16_t>(
2708                     0xD800
2709                   | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2710                   |   ((wc & 0x00FC00) >> 10));
2711             *to_nxt++ = static_cast<uint8_t>(t >> 8);
2712             *to_nxt++ = static_cast<uint8_t>(t);
2713             t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2714             *to_nxt++ = static_cast<uint8_t>(t >> 8);
2715             *to_nxt++ = static_cast<uint8_t>(t);
2716         }
2717     }
2718     return codecvt_base::ok;
2719 }
2720 
2721 static
2722 codecvt_base::result
2723 utf16be_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2724                 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2725                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2726 {
2727     frm_nxt = frm;
2728     to_nxt = to;
2729     if (mode & consume_header)
2730     {
2731         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2732             frm_nxt += 2;
2733     }
2734     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2735     {
2736         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2737         if ((c1 & 0xFC00) == 0xDC00)
2738             return codecvt_base::error;
2739         if ((c1 & 0xFC00) != 0xD800)
2740         {
2741             if (c1 > Maxcode)
2742                 return codecvt_base::error;
2743             *to_nxt = static_cast<uint32_t>(c1);
2744             frm_nxt += 2;
2745         }
2746         else
2747         {
2748             if (frm_end-frm_nxt < 4)
2749                 return codecvt_base::partial;
2750             uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2751             if ((c2 & 0xFC00) != 0xDC00)
2752                 return codecvt_base::error;
2753             uint32_t t = static_cast<uint32_t>(
2754                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
2755                   |   ((c1 & 0x003F) << 10)
2756                   |    (c2 & 0x03FF));
2757             if (t > Maxcode)
2758                 return codecvt_base::error;
2759             *to_nxt = t;
2760             frm_nxt += 4;
2761         }
2762     }
2763     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2764 }
2765 
2766 static
2767 int
2768 utf16be_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2769                        size_t mx, unsigned long Maxcode = 0x10FFFF,
2770                        codecvt_mode mode = codecvt_mode(0))
2771 {
2772     const uint8_t* frm_nxt = frm;
2773     if (mode & consume_header)
2774     {
2775         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2776             frm_nxt += 2;
2777     }
2778     for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2779     {
2780         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2781         if ((c1 & 0xFC00) == 0xDC00)
2782             break;
2783         if ((c1 & 0xFC00) != 0xD800)
2784         {
2785             if (c1 > Maxcode)
2786                 break;
2787             frm_nxt += 2;
2788         }
2789         else
2790         {
2791             if (frm_end-frm_nxt < 4)
2792                 break;
2793             uint16_t c2 = static_cast<uint16_t>(frm_nxt[2] << 8 | frm_nxt[3]);
2794             if ((c2 & 0xFC00) != 0xDC00)
2795                 break;
2796             uint32_t t = static_cast<uint32_t>(
2797                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
2798                   |   ((c1 & 0x003F) << 10)
2799                   |    (c2 & 0x03FF));
2800             if (t > Maxcode)
2801                 break;
2802             frm_nxt += 4;
2803         }
2804     }
2805     return static_cast<int>(frm_nxt - frm);
2806 }
2807 
2808 static
2809 codecvt_base::result
2810 ucs4_to_utf16le(const uint32_t* frm, const uint32_t* frm_end, const uint32_t*& frm_nxt,
2811                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2812                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2813 {
2814     frm_nxt = frm;
2815     to_nxt = to;
2816     if (mode & generate_header)
2817     {
2818         if (to_end - to_nxt < 2)
2819             return codecvt_base::partial;
2820         *to_nxt++ = static_cast<uint8_t>(0xFF);
2821         *to_nxt++ = static_cast<uint8_t>(0xFE);
2822     }
2823     for (; frm_nxt < frm_end; ++frm_nxt)
2824     {
2825         uint32_t wc = *frm_nxt;
2826         if ((wc & 0xFFFFF800) == 0x00D800 || wc > Maxcode)
2827             return codecvt_base::error;
2828         if (wc < 0x010000)
2829         {
2830             if (to_end-to_nxt < 2)
2831                 return codecvt_base::partial;
2832             *to_nxt++ = static_cast<uint8_t>(wc);
2833             *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2834         }
2835         else
2836         {
2837             if (to_end-to_nxt < 4)
2838                 return codecvt_base::partial;
2839             uint16_t t = static_cast<uint16_t>(
2840                     0xD800
2841                   | ((((wc & 0x1F0000) >> 16) - 1) << 6)
2842                   |   ((wc & 0x00FC00) >> 10));
2843             *to_nxt++ = static_cast<uint8_t>(t);
2844             *to_nxt++ = static_cast<uint8_t>(t >> 8);
2845             t = static_cast<uint16_t>(0xDC00 | (wc & 0x03FF));
2846             *to_nxt++ = static_cast<uint8_t>(t);
2847             *to_nxt++ = static_cast<uint8_t>(t >> 8);
2848         }
2849     }
2850     return codecvt_base::ok;
2851 }
2852 
2853 static
2854 codecvt_base::result
2855 utf16le_to_ucs4(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2856                 uint32_t* to, uint32_t* to_end, uint32_t*& to_nxt,
2857                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2858 {
2859     frm_nxt = frm;
2860     to_nxt = to;
2861     if (mode & consume_header)
2862     {
2863         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2864             frm_nxt += 2;
2865     }
2866     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2867     {
2868         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2869         if ((c1 & 0xFC00) == 0xDC00)
2870             return codecvt_base::error;
2871         if ((c1 & 0xFC00) != 0xD800)
2872         {
2873             if (c1 > Maxcode)
2874                 return codecvt_base::error;
2875             *to_nxt = static_cast<uint32_t>(c1);
2876             frm_nxt += 2;
2877         }
2878         else
2879         {
2880             if (frm_end-frm_nxt < 4)
2881                 return codecvt_base::partial;
2882             uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2883             if ((c2 & 0xFC00) != 0xDC00)
2884                 return codecvt_base::error;
2885             uint32_t t = static_cast<uint32_t>(
2886                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
2887                   |   ((c1 & 0x003F) << 10)
2888                   |    (c2 & 0x03FF));
2889             if (t > Maxcode)
2890                 return codecvt_base::error;
2891             *to_nxt = t;
2892             frm_nxt += 4;
2893         }
2894     }
2895     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2896 }
2897 
2898 static
2899 int
2900 utf16le_to_ucs4_length(const uint8_t* frm, const uint8_t* frm_end,
2901                        size_t mx, unsigned long Maxcode = 0x10FFFF,
2902                        codecvt_mode mode = codecvt_mode(0))
2903 {
2904     const uint8_t* frm_nxt = frm;
2905     if (mode & consume_header)
2906     {
2907         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
2908             frm_nxt += 2;
2909     }
2910     for (size_t nchar32_t = 0; frm_nxt < frm_end - 1 && nchar32_t < mx; ++nchar32_t)
2911     {
2912         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
2913         if ((c1 & 0xFC00) == 0xDC00)
2914             break;
2915         if ((c1 & 0xFC00) != 0xD800)
2916         {
2917             if (c1 > Maxcode)
2918                 break;
2919             frm_nxt += 2;
2920         }
2921         else
2922         {
2923             if (frm_end-frm_nxt < 4)
2924                 break;
2925             uint16_t c2 = static_cast<uint16_t>(frm_nxt[3] << 8 | frm_nxt[2]);
2926             if ((c2 & 0xFC00) != 0xDC00)
2927                 break;
2928             uint32_t t = static_cast<uint32_t>(
2929                     ((((c1 & 0x03C0) >> 6) + 1) << 16)
2930                   |   ((c1 & 0x003F) << 10)
2931                   |    (c2 & 0x03FF));
2932             if (t > Maxcode)
2933                 break;
2934             frm_nxt += 4;
2935         }
2936     }
2937     return static_cast<int>(frm_nxt - frm);
2938 }
2939 
2940 static
2941 codecvt_base::result
2942 ucs2_to_utf16be(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
2943                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
2944                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2945 {
2946     frm_nxt = frm;
2947     to_nxt = to;
2948     if (mode & generate_header)
2949     {
2950         if (to_end-to_nxt < 2)
2951             return codecvt_base::partial;
2952         *to_nxt++ = static_cast<uint8_t>(0xFE);
2953         *to_nxt++ = static_cast<uint8_t>(0xFF);
2954     }
2955     for (; frm_nxt < frm_end; ++frm_nxt)
2956     {
2957         uint16_t wc = *frm_nxt;
2958         if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
2959             return codecvt_base::error;
2960         if (to_end-to_nxt < 2)
2961             return codecvt_base::partial;
2962         *to_nxt++ = static_cast<uint8_t>(wc >> 8);
2963         *to_nxt++ = static_cast<uint8_t>(wc);
2964     }
2965     return codecvt_base::ok;
2966 }
2967 
2968 static
2969 codecvt_base::result
2970 utf16be_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
2971                 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
2972                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
2973 {
2974     frm_nxt = frm;
2975     to_nxt = to;
2976     if (mode & consume_header)
2977     {
2978         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
2979             frm_nxt += 2;
2980     }
2981     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
2982     {
2983         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
2984         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
2985             return codecvt_base::error;
2986         *to_nxt = c1;
2987         frm_nxt += 2;
2988     }
2989     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
2990 }
2991 
2992 static
2993 int
2994 utf16be_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
2995                        size_t mx, unsigned long Maxcode = 0x10FFFF,
2996                        codecvt_mode mode = codecvt_mode(0))
2997 {
2998     const uint8_t* frm_nxt = frm;
2999     if (mode & consume_header)
3000     {
3001         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFE && frm_nxt[1] == 0xFF)
3002             frm_nxt += 2;
3003     }
3004     for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3005     {
3006         uint16_t c1 = static_cast<uint16_t>(frm_nxt[0] << 8 | frm_nxt[1]);
3007         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3008             break;
3009         frm_nxt += 2;
3010     }
3011     return static_cast<int>(frm_nxt - frm);
3012 }
3013 
3014 static
3015 codecvt_base::result
3016 ucs2_to_utf16le(const uint16_t* frm, const uint16_t* frm_end, const uint16_t*& frm_nxt,
3017                 uint8_t* to, uint8_t* to_end, uint8_t*& to_nxt,
3018                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3019 {
3020     frm_nxt = frm;
3021     to_nxt = to;
3022     if (mode & generate_header)
3023     {
3024         if (to_end-to_nxt < 2)
3025             return codecvt_base::partial;
3026         *to_nxt++ = static_cast<uint8_t>(0xFF);
3027         *to_nxt++ = static_cast<uint8_t>(0xFE);
3028     }
3029     for (; frm_nxt < frm_end; ++frm_nxt)
3030     {
3031         uint16_t wc = *frm_nxt;
3032         if ((wc & 0xF800) == 0xD800 || wc > Maxcode)
3033             return codecvt_base::error;
3034         if (to_end-to_nxt < 2)
3035             return codecvt_base::partial;
3036         *to_nxt++ = static_cast<uint8_t>(wc);
3037         *to_nxt++ = static_cast<uint8_t>(wc >> 8);
3038     }
3039     return codecvt_base::ok;
3040 }
3041 
3042 static
3043 codecvt_base::result
3044 utf16le_to_ucs2(const uint8_t* frm, const uint8_t* frm_end, const uint8_t*& frm_nxt,
3045                 uint16_t* to, uint16_t* to_end, uint16_t*& to_nxt,
3046                 unsigned long Maxcode = 0x10FFFF, codecvt_mode mode = codecvt_mode(0))
3047 {
3048     frm_nxt = frm;
3049     to_nxt = to;
3050     if (mode & consume_header)
3051     {
3052         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3053             frm_nxt += 2;
3054     }
3055     for (; frm_nxt < frm_end - 1 && to_nxt < to_end; ++to_nxt)
3056     {
3057         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3058         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3059             return codecvt_base::error;
3060         *to_nxt = c1;
3061         frm_nxt += 2;
3062     }
3063     return frm_nxt < frm_end ? codecvt_base::partial : codecvt_base::ok;
3064 }
3065 
3066 static
3067 int
3068 utf16le_to_ucs2_length(const uint8_t* frm, const uint8_t* frm_end,
3069                        size_t mx, unsigned long Maxcode = 0x10FFFF,
3070                        codecvt_mode mode = codecvt_mode(0))
3071 {
3072     const uint8_t* frm_nxt = frm;
3073     frm_nxt = frm;
3074     if (mode & consume_header)
3075     {
3076         if (frm_end-frm_nxt >= 2 && frm_nxt[0] == 0xFF && frm_nxt[1] == 0xFE)
3077             frm_nxt += 2;
3078     }
3079     for (size_t nchar16_t = 0; frm_nxt < frm_end - 1 && nchar16_t < mx; ++nchar16_t)
3080     {
3081         uint16_t c1 = static_cast<uint16_t>(frm_nxt[1] << 8 | frm_nxt[0]);
3082         if ((c1 & 0xF800) == 0xD800 || c1 > Maxcode)
3083             break;
3084         frm_nxt += 2;
3085     }
3086     return static_cast<int>(frm_nxt - frm);
3087 }
3088 
3089 // template <> class codecvt<char16_t, char, mbstate_t>
3090 
3091 locale::id codecvt<char16_t, char, mbstate_t>::id;
3092 
3093 codecvt<char16_t, char, mbstate_t>::~codecvt()
3094 {
3095 }
3096 
3097 codecvt<char16_t, char, mbstate_t>::result
3098 codecvt<char16_t, char, mbstate_t>::do_out(state_type&,
3099     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3100     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3101 {
3102     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3103     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3104     const uint16_t* _frm_nxt = _frm;
3105     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3106     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3107     uint8_t* _to_nxt = _to;
3108     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3109     frm_nxt = frm + (_frm_nxt - _frm);
3110     to_nxt = to + (_to_nxt - _to);
3111     return r;
3112 }
3113 
3114 codecvt<char16_t, char, mbstate_t>::result
3115 codecvt<char16_t, char, mbstate_t>::do_in(state_type&,
3116     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3117     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3118 {
3119     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3120     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3121     const uint8_t* _frm_nxt = _frm;
3122     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3123     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3124     uint16_t* _to_nxt = _to;
3125     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3126     frm_nxt = frm + (_frm_nxt - _frm);
3127     to_nxt = to + (_to_nxt - _to);
3128     return r;
3129 }
3130 
3131 codecvt<char16_t, char, mbstate_t>::result
3132 codecvt<char16_t, char, mbstate_t>::do_unshift(state_type&,
3133     extern_type* to, extern_type*, extern_type*& to_nxt) const
3134 {
3135     to_nxt = to;
3136     return noconv;
3137 }
3138 
3139 int
3140 codecvt<char16_t, char, mbstate_t>::do_encoding() const  _NOEXCEPT
3141 {
3142     return 0;
3143 }
3144 
3145 bool
3146 codecvt<char16_t, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT
3147 {
3148     return false;
3149 }
3150 
3151 int
3152 codecvt<char16_t, char, mbstate_t>::do_length(state_type&,
3153     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3154 {
3155     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3156     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3157     return utf8_to_utf16_length(_frm, _frm_end, mx);
3158 }
3159 
3160 int
3161 codecvt<char16_t, char, mbstate_t>::do_max_length() const  _NOEXCEPT
3162 {
3163     return 4;
3164 }
3165 
3166 // template <> class codecvt<char32_t, char, mbstate_t>
3167 
3168 locale::id codecvt<char32_t, char, mbstate_t>::id;
3169 
3170 codecvt<char32_t, char, mbstate_t>::~codecvt()
3171 {
3172 }
3173 
3174 codecvt<char32_t, char, mbstate_t>::result
3175 codecvt<char32_t, char, mbstate_t>::do_out(state_type&,
3176     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3177     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3178 {
3179     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3180     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3181     const uint32_t* _frm_nxt = _frm;
3182     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3183     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3184     uint8_t* _to_nxt = _to;
3185     result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3186     frm_nxt = frm + (_frm_nxt - _frm);
3187     to_nxt = to + (_to_nxt - _to);
3188     return r;
3189 }
3190 
3191 codecvt<char32_t, char, mbstate_t>::result
3192 codecvt<char32_t, char, mbstate_t>::do_in(state_type&,
3193     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3194     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3195 {
3196     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3197     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3198     const uint8_t* _frm_nxt = _frm;
3199     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3200     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3201     uint32_t* _to_nxt = _to;
3202     result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
3203     frm_nxt = frm + (_frm_nxt - _frm);
3204     to_nxt = to + (_to_nxt - _to);
3205     return r;
3206 }
3207 
3208 codecvt<char32_t, char, mbstate_t>::result
3209 codecvt<char32_t, char, mbstate_t>::do_unshift(state_type&,
3210     extern_type* to, extern_type*, extern_type*& to_nxt) const
3211 {
3212     to_nxt = to;
3213     return noconv;
3214 }
3215 
3216 int
3217 codecvt<char32_t, char, mbstate_t>::do_encoding() const  _NOEXCEPT
3218 {
3219     return 0;
3220 }
3221 
3222 bool
3223 codecvt<char32_t, char, mbstate_t>::do_always_noconv() const  _NOEXCEPT
3224 {
3225     return false;
3226 }
3227 
3228 int
3229 codecvt<char32_t, char, mbstate_t>::do_length(state_type&,
3230     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3231 {
3232     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3233     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3234     return utf8_to_ucs4_length(_frm, _frm_end, mx);
3235 }
3236 
3237 int
3238 codecvt<char32_t, char, mbstate_t>::do_max_length() const  _NOEXCEPT
3239 {
3240     return 4;
3241 }
3242 
3243 // __codecvt_utf8<wchar_t>
3244 
3245 __codecvt_utf8<wchar_t>::result
3246 __codecvt_utf8<wchar_t>::do_out(state_type&,
3247     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3248     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3249 {
3250 #if _WIN32
3251     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3252     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3253     const uint16_t* _frm_nxt = _frm;
3254 #else
3255     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3256     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3257     const uint32_t* _frm_nxt = _frm;
3258 #endif
3259     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3260     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3261     uint8_t* _to_nxt = _to;
3262 #if _WIN32
3263     result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3264                             _Maxcode_, _Mode_);
3265 #else
3266     result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3267                             _Maxcode_, _Mode_);
3268 #endif
3269     frm_nxt = frm + (_frm_nxt - _frm);
3270     to_nxt = to + (_to_nxt - _to);
3271     return r;
3272 }
3273 
3274 __codecvt_utf8<wchar_t>::result
3275 __codecvt_utf8<wchar_t>::do_in(state_type&,
3276     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3277     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3278 {
3279     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3280     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3281     const uint8_t* _frm_nxt = _frm;
3282 #if _WIN32
3283     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3284     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3285     uint16_t* _to_nxt = _to;
3286     result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3287                             _Maxcode_, _Mode_);
3288 #else
3289     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3290     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3291     uint32_t* _to_nxt = _to;
3292     result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3293                             _Maxcode_, _Mode_);
3294 #endif
3295     frm_nxt = frm + (_frm_nxt - _frm);
3296     to_nxt = to + (_to_nxt - _to);
3297     return r;
3298 }
3299 
3300 __codecvt_utf8<wchar_t>::result
3301 __codecvt_utf8<wchar_t>::do_unshift(state_type&,
3302     extern_type* to, extern_type*, extern_type*& to_nxt) const
3303 {
3304     to_nxt = to;
3305     return noconv;
3306 }
3307 
3308 int
3309 __codecvt_utf8<wchar_t>::do_encoding() const  _NOEXCEPT
3310 {
3311     return 0;
3312 }
3313 
3314 bool
3315 __codecvt_utf8<wchar_t>::do_always_noconv() const  _NOEXCEPT
3316 {
3317     return false;
3318 }
3319 
3320 int
3321 __codecvt_utf8<wchar_t>::do_length(state_type&,
3322     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3323 {
3324     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3325     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3326     return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3327 }
3328 
3329 int
3330 __codecvt_utf8<wchar_t>::do_max_length() const  _NOEXCEPT
3331 {
3332     if (_Mode_ & consume_header)
3333         return 7;
3334     return 4;
3335 }
3336 
3337 // __codecvt_utf8<char16_t>
3338 
3339 __codecvt_utf8<char16_t>::result
3340 __codecvt_utf8<char16_t>::do_out(state_type&,
3341     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3342     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3343 {
3344     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3345     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3346     const uint16_t* _frm_nxt = _frm;
3347     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3348     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3349     uint8_t* _to_nxt = _to;
3350     result r = ucs2_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3351                             _Maxcode_, _Mode_);
3352     frm_nxt = frm + (_frm_nxt - _frm);
3353     to_nxt = to + (_to_nxt - _to);
3354     return r;
3355 }
3356 
3357 __codecvt_utf8<char16_t>::result
3358 __codecvt_utf8<char16_t>::do_in(state_type&,
3359     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3360     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3361 {
3362     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3363     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3364     const uint8_t* _frm_nxt = _frm;
3365     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3366     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3367     uint16_t* _to_nxt = _to;
3368     result r = utf8_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3369                             _Maxcode_, _Mode_);
3370     frm_nxt = frm + (_frm_nxt - _frm);
3371     to_nxt = to + (_to_nxt - _to);
3372     return r;
3373 }
3374 
3375 __codecvt_utf8<char16_t>::result
3376 __codecvt_utf8<char16_t>::do_unshift(state_type&,
3377     extern_type* to, extern_type*, extern_type*& to_nxt) const
3378 {
3379     to_nxt = to;
3380     return noconv;
3381 }
3382 
3383 int
3384 __codecvt_utf8<char16_t>::do_encoding() const  _NOEXCEPT
3385 {
3386     return 0;
3387 }
3388 
3389 bool
3390 __codecvt_utf8<char16_t>::do_always_noconv() const  _NOEXCEPT
3391 {
3392     return false;
3393 }
3394 
3395 int
3396 __codecvt_utf8<char16_t>::do_length(state_type&,
3397     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3398 {
3399     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3400     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3401     return utf8_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3402 }
3403 
3404 int
3405 __codecvt_utf8<char16_t>::do_max_length() const  _NOEXCEPT
3406 {
3407     if (_Mode_ & consume_header)
3408         return 6;
3409     return 3;
3410 }
3411 
3412 // __codecvt_utf8<char32_t>
3413 
3414 __codecvt_utf8<char32_t>::result
3415 __codecvt_utf8<char32_t>::do_out(state_type&,
3416     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3417     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3418 {
3419     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3420     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3421     const uint32_t* _frm_nxt = _frm;
3422     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3423     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3424     uint8_t* _to_nxt = _to;
3425     result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3426                             _Maxcode_, _Mode_);
3427     frm_nxt = frm + (_frm_nxt - _frm);
3428     to_nxt = to + (_to_nxt - _to);
3429     return r;
3430 }
3431 
3432 __codecvt_utf8<char32_t>::result
3433 __codecvt_utf8<char32_t>::do_in(state_type&,
3434     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3435     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3436 {
3437     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3438     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3439     const uint8_t* _frm_nxt = _frm;
3440     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3441     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3442     uint32_t* _to_nxt = _to;
3443     result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3444                             _Maxcode_, _Mode_);
3445     frm_nxt = frm + (_frm_nxt - _frm);
3446     to_nxt = to + (_to_nxt - _to);
3447     return r;
3448 }
3449 
3450 __codecvt_utf8<char32_t>::result
3451 __codecvt_utf8<char32_t>::do_unshift(state_type&,
3452     extern_type* to, extern_type*, extern_type*& to_nxt) const
3453 {
3454     to_nxt = to;
3455     return noconv;
3456 }
3457 
3458 int
3459 __codecvt_utf8<char32_t>::do_encoding() const  _NOEXCEPT
3460 {
3461     return 0;
3462 }
3463 
3464 bool
3465 __codecvt_utf8<char32_t>::do_always_noconv() const  _NOEXCEPT
3466 {
3467     return false;
3468 }
3469 
3470 int
3471 __codecvt_utf8<char32_t>::do_length(state_type&,
3472     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3473 {
3474     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3475     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3476     return utf8_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3477 }
3478 
3479 int
3480 __codecvt_utf8<char32_t>::do_max_length() const  _NOEXCEPT
3481 {
3482     if (_Mode_ & consume_header)
3483         return 7;
3484     return 4;
3485 }
3486 
3487 // __codecvt_utf16<wchar_t, false>
3488 
3489 __codecvt_utf16<wchar_t, false>::result
3490 __codecvt_utf16<wchar_t, false>::do_out(state_type&,
3491     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3492     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3493 {
3494     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3495     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3496     const uint32_t* _frm_nxt = _frm;
3497     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3498     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3499     uint8_t* _to_nxt = _to;
3500     result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3501                                _Maxcode_, _Mode_);
3502     frm_nxt = frm + (_frm_nxt - _frm);
3503     to_nxt = to + (_to_nxt - _to);
3504     return r;
3505 }
3506 
3507 __codecvt_utf16<wchar_t, false>::result
3508 __codecvt_utf16<wchar_t, false>::do_in(state_type&,
3509     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3510     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3511 {
3512     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3513     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3514     const uint8_t* _frm_nxt = _frm;
3515     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3516     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3517     uint32_t* _to_nxt = _to;
3518     result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3519                                _Maxcode_, _Mode_);
3520     frm_nxt = frm + (_frm_nxt - _frm);
3521     to_nxt = to + (_to_nxt - _to);
3522     return r;
3523 }
3524 
3525 __codecvt_utf16<wchar_t, false>::result
3526 __codecvt_utf16<wchar_t, false>::do_unshift(state_type&,
3527     extern_type* to, extern_type*, extern_type*& to_nxt) const
3528 {
3529     to_nxt = to;
3530     return noconv;
3531 }
3532 
3533 int
3534 __codecvt_utf16<wchar_t, false>::do_encoding() const  _NOEXCEPT
3535 {
3536     return 0;
3537 }
3538 
3539 bool
3540 __codecvt_utf16<wchar_t, false>::do_always_noconv() const  _NOEXCEPT
3541 {
3542     return false;
3543 }
3544 
3545 int
3546 __codecvt_utf16<wchar_t, false>::do_length(state_type&,
3547     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3548 {
3549     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3550     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3551     return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3552 }
3553 
3554 int
3555 __codecvt_utf16<wchar_t, false>::do_max_length() const  _NOEXCEPT
3556 {
3557     if (_Mode_ & consume_header)
3558         return 6;
3559     return 4;
3560 }
3561 
3562 // __codecvt_utf16<wchar_t, true>
3563 
3564 __codecvt_utf16<wchar_t, true>::result
3565 __codecvt_utf16<wchar_t, true>::do_out(state_type&,
3566     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3567     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3568 {
3569     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3570     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3571     const uint32_t* _frm_nxt = _frm;
3572     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3573     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3574     uint8_t* _to_nxt = _to;
3575     result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3576                                _Maxcode_, _Mode_);
3577     frm_nxt = frm + (_frm_nxt - _frm);
3578     to_nxt = to + (_to_nxt - _to);
3579     return r;
3580 }
3581 
3582 __codecvt_utf16<wchar_t, true>::result
3583 __codecvt_utf16<wchar_t, true>::do_in(state_type&,
3584     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3585     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3586 {
3587     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3588     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3589     const uint8_t* _frm_nxt = _frm;
3590     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3591     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3592     uint32_t* _to_nxt = _to;
3593     result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3594                                _Maxcode_, _Mode_);
3595     frm_nxt = frm + (_frm_nxt - _frm);
3596     to_nxt = to + (_to_nxt - _to);
3597     return r;
3598 }
3599 
3600 __codecvt_utf16<wchar_t, true>::result
3601 __codecvt_utf16<wchar_t, true>::do_unshift(state_type&,
3602     extern_type* to, extern_type*, extern_type*& to_nxt) const
3603 {
3604     to_nxt = to;
3605     return noconv;
3606 }
3607 
3608 int
3609 __codecvt_utf16<wchar_t, true>::do_encoding() const  _NOEXCEPT
3610 {
3611     return 0;
3612 }
3613 
3614 bool
3615 __codecvt_utf16<wchar_t, true>::do_always_noconv() const  _NOEXCEPT
3616 {
3617     return false;
3618 }
3619 
3620 int
3621 __codecvt_utf16<wchar_t, true>::do_length(state_type&,
3622     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3623 {
3624     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3625     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3626     return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3627 }
3628 
3629 int
3630 __codecvt_utf16<wchar_t, true>::do_max_length() const  _NOEXCEPT
3631 {
3632     if (_Mode_ & consume_header)
3633         return 6;
3634     return 4;
3635 }
3636 
3637 // __codecvt_utf16<char16_t, false>
3638 
3639 __codecvt_utf16<char16_t, false>::result
3640 __codecvt_utf16<char16_t, false>::do_out(state_type&,
3641     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3642     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3643 {
3644     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3645     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3646     const uint16_t* _frm_nxt = _frm;
3647     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3648     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3649     uint8_t* _to_nxt = _to;
3650     result r = ucs2_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3651                                _Maxcode_, _Mode_);
3652     frm_nxt = frm + (_frm_nxt - _frm);
3653     to_nxt = to + (_to_nxt - _to);
3654     return r;
3655 }
3656 
3657 __codecvt_utf16<char16_t, false>::result
3658 __codecvt_utf16<char16_t, false>::do_in(state_type&,
3659     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3660     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3661 {
3662     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3663     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3664     const uint8_t* _frm_nxt = _frm;
3665     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3666     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3667     uint16_t* _to_nxt = _to;
3668     result r = utf16be_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3669                                _Maxcode_, _Mode_);
3670     frm_nxt = frm + (_frm_nxt - _frm);
3671     to_nxt = to + (_to_nxt - _to);
3672     return r;
3673 }
3674 
3675 __codecvt_utf16<char16_t, false>::result
3676 __codecvt_utf16<char16_t, false>::do_unshift(state_type&,
3677     extern_type* to, extern_type*, extern_type*& to_nxt) const
3678 {
3679     to_nxt = to;
3680     return noconv;
3681 }
3682 
3683 int
3684 __codecvt_utf16<char16_t, false>::do_encoding() const  _NOEXCEPT
3685 {
3686     return 0;
3687 }
3688 
3689 bool
3690 __codecvt_utf16<char16_t, false>::do_always_noconv() const  _NOEXCEPT
3691 {
3692     return false;
3693 }
3694 
3695 int
3696 __codecvt_utf16<char16_t, false>::do_length(state_type&,
3697     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3698 {
3699     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3700     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3701     return utf16be_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3702 }
3703 
3704 int
3705 __codecvt_utf16<char16_t, false>::do_max_length() const  _NOEXCEPT
3706 {
3707     if (_Mode_ & consume_header)
3708         return 4;
3709     return 2;
3710 }
3711 
3712 // __codecvt_utf16<char16_t, true>
3713 
3714 __codecvt_utf16<char16_t, true>::result
3715 __codecvt_utf16<char16_t, true>::do_out(state_type&,
3716     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3717     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3718 {
3719     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
3720     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
3721     const uint16_t* _frm_nxt = _frm;
3722     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3723     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3724     uint8_t* _to_nxt = _to;
3725     result r = ucs2_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3726                                _Maxcode_, _Mode_);
3727     frm_nxt = frm + (_frm_nxt - _frm);
3728     to_nxt = to + (_to_nxt - _to);
3729     return r;
3730 }
3731 
3732 __codecvt_utf16<char16_t, true>::result
3733 __codecvt_utf16<char16_t, true>::do_in(state_type&,
3734     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3735     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3736 {
3737     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3738     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3739     const uint8_t* _frm_nxt = _frm;
3740     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
3741     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
3742     uint16_t* _to_nxt = _to;
3743     result r = utf16le_to_ucs2(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3744                                _Maxcode_, _Mode_);
3745     frm_nxt = frm + (_frm_nxt - _frm);
3746     to_nxt = to + (_to_nxt - _to);
3747     return r;
3748 }
3749 
3750 __codecvt_utf16<char16_t, true>::result
3751 __codecvt_utf16<char16_t, true>::do_unshift(state_type&,
3752     extern_type* to, extern_type*, extern_type*& to_nxt) const
3753 {
3754     to_nxt = to;
3755     return noconv;
3756 }
3757 
3758 int
3759 __codecvt_utf16<char16_t, true>::do_encoding() const  _NOEXCEPT
3760 {
3761     return 0;
3762 }
3763 
3764 bool
3765 __codecvt_utf16<char16_t, true>::do_always_noconv() const  _NOEXCEPT
3766 {
3767     return false;
3768 }
3769 
3770 int
3771 __codecvt_utf16<char16_t, true>::do_length(state_type&,
3772     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3773 {
3774     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3775     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3776     return utf16le_to_ucs2_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3777 }
3778 
3779 int
3780 __codecvt_utf16<char16_t, true>::do_max_length() const  _NOEXCEPT
3781 {
3782     if (_Mode_ & consume_header)
3783         return 4;
3784     return 2;
3785 }
3786 
3787 // __codecvt_utf16<char32_t, false>
3788 
3789 __codecvt_utf16<char32_t, false>::result
3790 __codecvt_utf16<char32_t, false>::do_out(state_type&,
3791     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3792     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3793 {
3794     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3795     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3796     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     result r = ucs4_to_utf16be(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3801                                _Maxcode_, _Mode_);
3802     frm_nxt = frm + (_frm_nxt - _frm);
3803     to_nxt = to + (_to_nxt - _to);
3804     return r;
3805 }
3806 
3807 __codecvt_utf16<char32_t, false>::result
3808 __codecvt_utf16<char32_t, false>::do_in(state_type&,
3809     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3810     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3811 {
3812     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3813     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3814     const uint8_t* _frm_nxt = _frm;
3815     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3816     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3817     uint32_t* _to_nxt = _to;
3818     result r = utf16be_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3819                                _Maxcode_, _Mode_);
3820     frm_nxt = frm + (_frm_nxt - _frm);
3821     to_nxt = to + (_to_nxt - _to);
3822     return r;
3823 }
3824 
3825 __codecvt_utf16<char32_t, false>::result
3826 __codecvt_utf16<char32_t, false>::do_unshift(state_type&,
3827     extern_type* to, extern_type*, extern_type*& to_nxt) const
3828 {
3829     to_nxt = to;
3830     return noconv;
3831 }
3832 
3833 int
3834 __codecvt_utf16<char32_t, false>::do_encoding() const  _NOEXCEPT
3835 {
3836     return 0;
3837 }
3838 
3839 bool
3840 __codecvt_utf16<char32_t, false>::do_always_noconv() const  _NOEXCEPT
3841 {
3842     return false;
3843 }
3844 
3845 int
3846 __codecvt_utf16<char32_t, false>::do_length(state_type&,
3847     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3848 {
3849     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3850     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3851     return utf16be_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3852 }
3853 
3854 int
3855 __codecvt_utf16<char32_t, false>::do_max_length() const  _NOEXCEPT
3856 {
3857     if (_Mode_ & consume_header)
3858         return 6;
3859     return 4;
3860 }
3861 
3862 // __codecvt_utf16<char32_t, true>
3863 
3864 __codecvt_utf16<char32_t, true>::result
3865 __codecvt_utf16<char32_t, true>::do_out(state_type&,
3866     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3867     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3868 {
3869     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3870     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3871     const uint32_t* _frm_nxt = _frm;
3872     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3873     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3874     uint8_t* _to_nxt = _to;
3875     result r = ucs4_to_utf16le(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3876                                _Maxcode_, _Mode_);
3877     frm_nxt = frm + (_frm_nxt - _frm);
3878     to_nxt = to + (_to_nxt - _to);
3879     return r;
3880 }
3881 
3882 __codecvt_utf16<char32_t, true>::result
3883 __codecvt_utf16<char32_t, true>::do_in(state_type&,
3884     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3885     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3886 {
3887     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3888     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3889     const uint8_t* _frm_nxt = _frm;
3890     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3891     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3892     uint32_t* _to_nxt = _to;
3893     result r = utf16le_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3894                                _Maxcode_, _Mode_);
3895     frm_nxt = frm + (_frm_nxt - _frm);
3896     to_nxt = to + (_to_nxt - _to);
3897     return r;
3898 }
3899 
3900 __codecvt_utf16<char32_t, true>::result
3901 __codecvt_utf16<char32_t, true>::do_unshift(state_type&,
3902     extern_type* to, extern_type*, extern_type*& to_nxt) const
3903 {
3904     to_nxt = to;
3905     return noconv;
3906 }
3907 
3908 int
3909 __codecvt_utf16<char32_t, true>::do_encoding() const  _NOEXCEPT
3910 {
3911     return 0;
3912 }
3913 
3914 bool
3915 __codecvt_utf16<char32_t, true>::do_always_noconv() const  _NOEXCEPT
3916 {
3917     return false;
3918 }
3919 
3920 int
3921 __codecvt_utf16<char32_t, true>::do_length(state_type&,
3922     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3923 {
3924     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3925     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3926     return utf16le_to_ucs4_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
3927 }
3928 
3929 int
3930 __codecvt_utf16<char32_t, true>::do_max_length() const  _NOEXCEPT
3931 {
3932     if (_Mode_ & consume_header)
3933         return 6;
3934     return 4;
3935 }
3936 
3937 // __codecvt_utf8_utf16<wchar_t>
3938 
3939 __codecvt_utf8_utf16<wchar_t>::result
3940 __codecvt_utf8_utf16<wchar_t>::do_out(state_type&,
3941     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
3942     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
3943 {
3944     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
3945     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
3946     const uint32_t* _frm_nxt = _frm;
3947     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
3948     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
3949     uint8_t* _to_nxt = _to;
3950     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3951                              _Maxcode_, _Mode_);
3952     frm_nxt = frm + (_frm_nxt - _frm);
3953     to_nxt = to + (_to_nxt - _to);
3954     return r;
3955 }
3956 
3957 __codecvt_utf8_utf16<wchar_t>::result
3958 __codecvt_utf8_utf16<wchar_t>::do_in(state_type&,
3959     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
3960     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
3961 {
3962     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
3963     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
3964     const uint8_t* _frm_nxt = _frm;
3965     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
3966     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
3967     uint32_t* _to_nxt = _to;
3968     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
3969                              _Maxcode_, _Mode_);
3970     frm_nxt = frm + (_frm_nxt - _frm);
3971     to_nxt = to + (_to_nxt - _to);
3972     return r;
3973 }
3974 
3975 __codecvt_utf8_utf16<wchar_t>::result
3976 __codecvt_utf8_utf16<wchar_t>::do_unshift(state_type&,
3977     extern_type* to, extern_type*, extern_type*& to_nxt) const
3978 {
3979     to_nxt = to;
3980     return noconv;
3981 }
3982 
3983 int
3984 __codecvt_utf8_utf16<wchar_t>::do_encoding() const  _NOEXCEPT
3985 {
3986     return 0;
3987 }
3988 
3989 bool
3990 __codecvt_utf8_utf16<wchar_t>::do_always_noconv() const  _NOEXCEPT
3991 {
3992     return false;
3993 }
3994 
3995 int
3996 __codecvt_utf8_utf16<wchar_t>::do_length(state_type&,
3997     const extern_type* frm, const extern_type* frm_end, size_t mx) const
3998 {
3999     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4000     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4001     return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4002 }
4003 
4004 int
4005 __codecvt_utf8_utf16<wchar_t>::do_max_length() const  _NOEXCEPT
4006 {
4007     if (_Mode_ & consume_header)
4008         return 7;
4009     return 4;
4010 }
4011 
4012 // __codecvt_utf8_utf16<char16_t>
4013 
4014 __codecvt_utf8_utf16<char16_t>::result
4015 __codecvt_utf8_utf16<char16_t>::do_out(state_type&,
4016     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4017     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4018 {
4019     const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
4020     const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
4021     const uint16_t* _frm_nxt = _frm;
4022     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4023     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4024     uint8_t* _to_nxt = _to;
4025     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4026                              _Maxcode_, _Mode_);
4027     frm_nxt = frm + (_frm_nxt - _frm);
4028     to_nxt = to + (_to_nxt - _to);
4029     return r;
4030 }
4031 
4032 __codecvt_utf8_utf16<char16_t>::result
4033 __codecvt_utf8_utf16<char16_t>::do_in(state_type&,
4034     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4035     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4036 {
4037     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4038     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4039     const uint8_t* _frm_nxt = _frm;
4040     uint16_t* _to = reinterpret_cast<uint16_t*>(to);
4041     uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
4042     uint16_t* _to_nxt = _to;
4043     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4044                              _Maxcode_, _Mode_);
4045     frm_nxt = frm + (_frm_nxt - _frm);
4046     to_nxt = to + (_to_nxt - _to);
4047     return r;
4048 }
4049 
4050 __codecvt_utf8_utf16<char16_t>::result
4051 __codecvt_utf8_utf16<char16_t>::do_unshift(state_type&,
4052     extern_type* to, extern_type*, extern_type*& to_nxt) const
4053 {
4054     to_nxt = to;
4055     return noconv;
4056 }
4057 
4058 int
4059 __codecvt_utf8_utf16<char16_t>::do_encoding() const  _NOEXCEPT
4060 {
4061     return 0;
4062 }
4063 
4064 bool
4065 __codecvt_utf8_utf16<char16_t>::do_always_noconv() const  _NOEXCEPT
4066 {
4067     return false;
4068 }
4069 
4070 int
4071 __codecvt_utf8_utf16<char16_t>::do_length(state_type&,
4072     const extern_type* frm, const extern_type* frm_end, size_t mx) const
4073 {
4074     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4075     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4076     return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4077 }
4078 
4079 int
4080 __codecvt_utf8_utf16<char16_t>::do_max_length() const  _NOEXCEPT
4081 {
4082     if (_Mode_ & consume_header)
4083         return 7;
4084     return 4;
4085 }
4086 
4087 // __codecvt_utf8_utf16<char32_t>
4088 
4089 __codecvt_utf8_utf16<char32_t>::result
4090 __codecvt_utf8_utf16<char32_t>::do_out(state_type&,
4091     const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
4092     extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
4093 {
4094     const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
4095     const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
4096     const uint32_t* _frm_nxt = _frm;
4097     uint8_t* _to = reinterpret_cast<uint8_t*>(to);
4098     uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
4099     uint8_t* _to_nxt = _to;
4100     result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4101                              _Maxcode_, _Mode_);
4102     frm_nxt = frm + (_frm_nxt - _frm);
4103     to_nxt = to + (_to_nxt - _to);
4104     return r;
4105 }
4106 
4107 __codecvt_utf8_utf16<char32_t>::result
4108 __codecvt_utf8_utf16<char32_t>::do_in(state_type&,
4109     const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
4110     intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
4111 {
4112     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4113     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4114     const uint8_t* _frm_nxt = _frm;
4115     uint32_t* _to = reinterpret_cast<uint32_t*>(to);
4116     uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
4117     uint32_t* _to_nxt = _to;
4118     result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt,
4119                              _Maxcode_, _Mode_);
4120     frm_nxt = frm + (_frm_nxt - _frm);
4121     to_nxt = to + (_to_nxt - _to);
4122     return r;
4123 }
4124 
4125 __codecvt_utf8_utf16<char32_t>::result
4126 __codecvt_utf8_utf16<char32_t>::do_unshift(state_type&,
4127     extern_type* to, extern_type*, extern_type*& to_nxt) const
4128 {
4129     to_nxt = to;
4130     return noconv;
4131 }
4132 
4133 int
4134 __codecvt_utf8_utf16<char32_t>::do_encoding() const  _NOEXCEPT
4135 {
4136     return 0;
4137 }
4138 
4139 bool
4140 __codecvt_utf8_utf16<char32_t>::do_always_noconv() const  _NOEXCEPT
4141 {
4142     return false;
4143 }
4144 
4145 int
4146 __codecvt_utf8_utf16<char32_t>::do_length(state_type&,
4147     const extern_type* frm, const extern_type* frm_end, size_t mx) const
4148 {
4149     const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
4150     const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
4151     return utf8_to_utf16_length(_frm, _frm_end, mx, _Maxcode_, _Mode_);
4152 }
4153 
4154 int
4155 __codecvt_utf8_utf16<char32_t>::do_max_length() const  _NOEXCEPT
4156 {
4157     if (_Mode_ & consume_header)
4158         return 7;
4159     return 4;
4160 }
4161 
4162 // __narrow_to_utf8<16>
4163 
4164 __narrow_to_utf8<16>::~__narrow_to_utf8()
4165 {
4166 }
4167 
4168 // __narrow_to_utf8<32>
4169 
4170 __narrow_to_utf8<32>::~__narrow_to_utf8()
4171 {
4172 }
4173 
4174 // __widen_from_utf8<16>
4175 
4176 __widen_from_utf8<16>::~__widen_from_utf8()
4177 {
4178 }
4179 
4180 // __widen_from_utf8<32>
4181 
4182 __widen_from_utf8<32>::~__widen_from_utf8()
4183 {
4184 }
4185 
4186 // numpunct<char> && numpunct<wchar_t>
4187 
4188 locale::id numpunct< char  >::id;
4189 locale::id numpunct<wchar_t>::id;
4190 
4191 numpunct<char>::numpunct(size_t refs)
4192     : locale::facet(refs),
4193       __decimal_point_('.'),
4194       __thousands_sep_(',')
4195 {
4196 }
4197 
4198 numpunct<wchar_t>::numpunct(size_t refs)
4199     : locale::facet(refs),
4200       __decimal_point_(L'.'),
4201       __thousands_sep_(L',')
4202 {
4203 }
4204 
4205 numpunct<char>::~numpunct()
4206 {
4207 }
4208 
4209 numpunct<wchar_t>::~numpunct()
4210 {
4211 }
4212 
4213  char   numpunct< char  >::do_decimal_point() const {return __decimal_point_;}
4214 wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
4215 
4216  char   numpunct< char  >::do_thousands_sep() const {return __thousands_sep_;}
4217 wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
4218 
4219 string numpunct< char  >::do_grouping() const {return __grouping_;}
4220 string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
4221 
4222  string numpunct< char  >::do_truename() const {return "true";}
4223 wstring numpunct<wchar_t>::do_truename() const {return L"true";}
4224 
4225  string numpunct< char  >::do_falsename() const {return "false";}
4226 wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
4227 
4228 // numpunct_byname<char>
4229 
4230 numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4231     : numpunct<char>(refs)
4232 {
4233     __init(nm);
4234 }
4235 
4236 numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4237     : numpunct<char>(refs)
4238 {
4239     __init(nm.c_str());
4240 }
4241 
4242 numpunct_byname<char>::~numpunct_byname()
4243 {
4244 }
4245 
4246 void
4247 numpunct_byname<char>::__init(const char* nm)
4248 {
4249     if (strcmp(nm, "C") != 0)
4250     {
4251         __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
4252         if (loc == nullptr)
4253             __throw_runtime_error("numpunct_byname<char>::numpunct_byname"
4254                                 " failed to construct for " + string(nm));
4255 
4256         lconv* lc = __libcpp_localeconv_l(loc.get());
4257         if (*lc->decimal_point)
4258             __decimal_point_ = *lc->decimal_point;
4259         if (*lc->thousands_sep)
4260             __thousands_sep_ = *lc->thousands_sep;
4261         __grouping_ = lc->grouping;
4262         // localization for truename and falsename is not available
4263     }
4264 }
4265 
4266 // numpunct_byname<wchar_t>
4267 
4268 numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4269     : numpunct<wchar_t>(refs)
4270 {
4271     __init(nm);
4272 }
4273 
4274 numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4275     : numpunct<wchar_t>(refs)
4276 {
4277     __init(nm.c_str());
4278 }
4279 
4280 numpunct_byname<wchar_t>::~numpunct_byname()
4281 {
4282 }
4283 
4284 void
4285 numpunct_byname<wchar_t>::__init(const char* nm)
4286 {
4287     if (strcmp(nm, "C") != 0)
4288     {
4289         __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
4290         if (loc == nullptr)
4291             __throw_runtime_error("numpunct_byname<char>::numpunct_byname"
4292                                 " failed to construct for " + string(nm));
4293 
4294         lconv* lc = __libcpp_localeconv_l(loc.get());
4295         if (*lc->decimal_point)
4296             __decimal_point_ = *lc->decimal_point;
4297         if (*lc->thousands_sep)
4298             __thousands_sep_ = *lc->thousands_sep;
4299         __grouping_ = lc->grouping;
4300         // locallization for truename and falsename is not available
4301     }
4302 }
4303 
4304 // num_get helpers
4305 
4306 int
4307 __num_get_base::__get_base(ios_base& iob)
4308 {
4309     ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4310     if (__basefield == ios_base::oct)
4311         return 8;
4312     else if (__basefield == ios_base::hex)
4313         return 16;
4314     else if (__basefield == 0)
4315         return 0;
4316     return 10;
4317 }
4318 
4319 const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4320 
4321 void
4322 __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4323                  ios_base::iostate& __err)
4324 {
4325     if (__grouping.size() != 0)
4326     {
4327         reverse(__g, __g_end);
4328         const char* __ig = __grouping.data();
4329         const char* __eg = __ig + __grouping.size();
4330         for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4331         {
4332             if (0 < *__ig && *__ig < numeric_limits<char>::max())
4333             {
4334                 if (static_cast<unsigned>(*__ig) != *__r)
4335                 {
4336                     __err = ios_base::failbit;
4337                     return;
4338                 }
4339             }
4340             if (__eg - __ig > 1)
4341                 ++__ig;
4342         }
4343         if (0 < *__ig && *__ig < numeric_limits<char>::max())
4344         {
4345             if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
4346                 __err = ios_base::failbit;
4347         }
4348     }
4349 }
4350 
4351 void
4352 __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4353                              ios_base::fmtflags __flags)
4354 {
4355     if (__flags & ios_base::showpos)
4356         *__fmtp++ = '+';
4357     if (__flags & ios_base::showbase)
4358         *__fmtp++ = '#';
4359     while(*__len)
4360         *__fmtp++ = *__len++;
4361     if ((__flags & ios_base::basefield) == ios_base::oct)
4362         *__fmtp = 'o';
4363     else if ((__flags & ios_base::basefield) == ios_base::hex)
4364     {
4365         if (__flags & ios_base::uppercase)
4366             *__fmtp = 'X';
4367         else
4368             *__fmtp = 'x';
4369     }
4370     else if (__signd)
4371         *__fmtp = 'd';
4372     else
4373         *__fmtp = 'u';
4374 }
4375 
4376 bool
4377 __num_put_base::__format_float(char* __fmtp, const char* __len,
4378                                ios_base::fmtflags __flags)
4379 {
4380     bool specify_precision = true;
4381     if (__flags & ios_base::showpos)
4382         *__fmtp++ = '+';
4383     if (__flags & ios_base::showpoint)
4384         *__fmtp++ = '#';
4385     ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4386     bool uppercase = (__flags & ios_base::uppercase) != 0;
4387     if (floatfield == (ios_base::fixed | ios_base::scientific))
4388         specify_precision = false;
4389     else
4390     {
4391         *__fmtp++ = '.';
4392         *__fmtp++ = '*';
4393     }
4394     while(*__len)
4395         *__fmtp++ = *__len++;
4396     if (floatfield == ios_base::fixed)
4397     {
4398         if (uppercase)
4399             *__fmtp = 'F';
4400         else
4401             *__fmtp = 'f';
4402     }
4403     else if (floatfield == ios_base::scientific)
4404     {
4405         if (uppercase)
4406             *__fmtp = 'E';
4407         else
4408             *__fmtp = 'e';
4409     }
4410     else if (floatfield == (ios_base::fixed | ios_base::scientific))
4411     {
4412         if (uppercase)
4413             *__fmtp = 'A';
4414         else
4415             *__fmtp = 'a';
4416     }
4417     else
4418     {
4419         if (uppercase)
4420             *__fmtp = 'G';
4421         else
4422             *__fmtp = 'g';
4423     }
4424     return specify_precision;
4425 }
4426 
4427 char*
4428 __num_put_base::__identify_padding(char* __nb, char* __ne,
4429                                    const ios_base& __iob)
4430 {
4431     switch (__iob.flags() & ios_base::adjustfield)
4432     {
4433     case ios_base::internal:
4434         if (__nb[0] == '-' || __nb[0] == '+')
4435             return __nb+1;
4436         if (__ne - __nb >= 2 && __nb[0] == '0'
4437                             && (__nb[1] == 'x' || __nb[1] == 'X'))
4438             return __nb+2;
4439         break;
4440     case ios_base::left:
4441         return __ne;
4442     case ios_base::right:
4443     default:
4444         break;
4445     }
4446     return __nb;
4447 }
4448 
4449 // time_get
4450 
4451 static
4452 string*
4453 init_weeks()
4454 {
4455     static string weeks[14];
4456     weeks[0]  = "Sunday";
4457     weeks[1]  = "Monday";
4458     weeks[2]  = "Tuesday";
4459     weeks[3]  = "Wednesday";
4460     weeks[4]  = "Thursday";
4461     weeks[5]  = "Friday";
4462     weeks[6]  = "Saturday";
4463     weeks[7]  = "Sun";
4464     weeks[8]  = "Mon";
4465     weeks[9]  = "Tue";
4466     weeks[10] = "Wed";
4467     weeks[11] = "Thu";
4468     weeks[12] = "Fri";
4469     weeks[13] = "Sat";
4470     return weeks;
4471 }
4472 
4473 static
4474 wstring*
4475 init_wweeks()
4476 {
4477     static wstring weeks[14];
4478     weeks[0]  = L"Sunday";
4479     weeks[1]  = L"Monday";
4480     weeks[2]  = L"Tuesday";
4481     weeks[3]  = L"Wednesday";
4482     weeks[4]  = L"Thursday";
4483     weeks[5]  = L"Friday";
4484     weeks[6]  = L"Saturday";
4485     weeks[7]  = L"Sun";
4486     weeks[8]  = L"Mon";
4487     weeks[9]  = L"Tue";
4488     weeks[10] = L"Wed";
4489     weeks[11] = L"Thu";
4490     weeks[12] = L"Fri";
4491     weeks[13] = L"Sat";
4492     return weeks;
4493 }
4494 
4495 template <>
4496 const string*
4497 __time_get_c_storage<char>::__weeks() const
4498 {
4499     static const string* weeks = init_weeks();
4500     return weeks;
4501 }
4502 
4503 template <>
4504 const wstring*
4505 __time_get_c_storage<wchar_t>::__weeks() const
4506 {
4507     static const wstring* weeks = init_wweeks();
4508     return weeks;
4509 }
4510 
4511 static
4512 string*
4513 init_months()
4514 {
4515     static string months[24];
4516     months[0]  = "January";
4517     months[1]  = "February";
4518     months[2]  = "March";
4519     months[3]  = "April";
4520     months[4]  = "May";
4521     months[5]  = "June";
4522     months[6]  = "July";
4523     months[7]  = "August";
4524     months[8]  = "September";
4525     months[9]  = "October";
4526     months[10] = "November";
4527     months[11] = "December";
4528     months[12] = "Jan";
4529     months[13] = "Feb";
4530     months[14] = "Mar";
4531     months[15] = "Apr";
4532     months[16] = "May";
4533     months[17] = "Jun";
4534     months[18] = "Jul";
4535     months[19] = "Aug";
4536     months[20] = "Sep";
4537     months[21] = "Oct";
4538     months[22] = "Nov";
4539     months[23] = "Dec";
4540     return months;
4541 }
4542 
4543 static
4544 wstring*
4545 init_wmonths()
4546 {
4547     static wstring months[24];
4548     months[0]  = L"January";
4549     months[1]  = L"February";
4550     months[2]  = L"March";
4551     months[3]  = L"April";
4552     months[4]  = L"May";
4553     months[5]  = L"June";
4554     months[6]  = L"July";
4555     months[7]  = L"August";
4556     months[8]  = L"September";
4557     months[9]  = L"October";
4558     months[10] = L"November";
4559     months[11] = L"December";
4560     months[12] = L"Jan";
4561     months[13] = L"Feb";
4562     months[14] = L"Mar";
4563     months[15] = L"Apr";
4564     months[16] = L"May";
4565     months[17] = L"Jun";
4566     months[18] = L"Jul";
4567     months[19] = L"Aug";
4568     months[20] = L"Sep";
4569     months[21] = L"Oct";
4570     months[22] = L"Nov";
4571     months[23] = L"Dec";
4572     return months;
4573 }
4574 
4575 template <>
4576 const string*
4577 __time_get_c_storage<char>::__months() const
4578 {
4579     static const string* months = init_months();
4580     return months;
4581 }
4582 
4583 template <>
4584 const wstring*
4585 __time_get_c_storage<wchar_t>::__months() const
4586 {
4587     static const wstring* months = init_wmonths();
4588     return months;
4589 }
4590 
4591 static
4592 string*
4593 init_am_pm()
4594 {
4595     static string am_pm[24];
4596     am_pm[0]  = "AM";
4597     am_pm[1]  = "PM";
4598     return am_pm;
4599 }
4600 
4601 static
4602 wstring*
4603 init_wam_pm()
4604 {
4605     static wstring am_pm[24];
4606     am_pm[0]  = L"AM";
4607     am_pm[1]  = L"PM";
4608     return am_pm;
4609 }
4610 
4611 template <>
4612 const string*
4613 __time_get_c_storage<char>::__am_pm() const
4614 {
4615     static const string* am_pm = init_am_pm();
4616     return am_pm;
4617 }
4618 
4619 template <>
4620 const wstring*
4621 __time_get_c_storage<wchar_t>::__am_pm() const
4622 {
4623     static const wstring* am_pm = init_wam_pm();
4624     return am_pm;
4625 }
4626 
4627 template <>
4628 const string&
4629 __time_get_c_storage<char>::__x() const
4630 {
4631     static string s("%m/%d/%y");
4632     return s;
4633 }
4634 
4635 template <>
4636 const wstring&
4637 __time_get_c_storage<wchar_t>::__x() const
4638 {
4639     static wstring s(L"%m/%d/%y");
4640     return s;
4641 }
4642 
4643 template <>
4644 const string&
4645 __time_get_c_storage<char>::__X() const
4646 {
4647     static string s("%H:%M:%S");
4648     return s;
4649 }
4650 
4651 template <>
4652 const wstring&
4653 __time_get_c_storage<wchar_t>::__X() const
4654 {
4655     static wstring s(L"%H:%M:%S");
4656     return s;
4657 }
4658 
4659 template <>
4660 const string&
4661 __time_get_c_storage<char>::__c() const
4662 {
4663     static string s("%a %b %d %H:%M:%S %Y");
4664     return s;
4665 }
4666 
4667 template <>
4668 const wstring&
4669 __time_get_c_storage<wchar_t>::__c() const
4670 {
4671     static wstring s(L"%a %b %d %H:%M:%S %Y");
4672     return s;
4673 }
4674 
4675 template <>
4676 const string&
4677 __time_get_c_storage<char>::__r() const
4678 {
4679     static string s("%I:%M:%S %p");
4680     return s;
4681 }
4682 
4683 template <>
4684 const wstring&
4685 __time_get_c_storage<wchar_t>::__r() const
4686 {
4687     static wstring s(L"%I:%M:%S %p");
4688     return s;
4689 }
4690 
4691 // time_get_byname
4692 
4693 __time_get::__time_get(const char* nm)
4694     : __loc_(newlocale(LC_ALL_MASK, nm, 0))
4695 {
4696     if (__loc_ == 0)
4697         __throw_runtime_error("time_get_byname"
4698                             " failed to construct for " + string(nm));
4699 }
4700 
4701 __time_get::__time_get(const string& nm)
4702     : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
4703 {
4704     if (__loc_ == 0)
4705         __throw_runtime_error("time_get_byname"
4706                             " failed to construct for " + nm);
4707 }
4708 
4709 __time_get::~__time_get()
4710 {
4711     freelocale(__loc_);
4712 }
4713 #if defined(__clang__)
4714 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
4715 #endif
4716 #if defined(__GNUG__)
4717 #pragma GCC   diagnostic ignored "-Wmissing-field-initializers"
4718 #endif
4719 
4720 template <>
4721 string
4722 __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
4723 {
4724     tm t = {0};
4725     t.tm_sec = 59;
4726     t.tm_min = 55;
4727     t.tm_hour = 23;
4728     t.tm_mday = 31;
4729     t.tm_mon = 11;
4730     t.tm_year = 161;
4731     t.tm_wday = 6;
4732     t.tm_yday = 364;
4733     t.tm_isdst = -1;
4734     char buf[100];
4735     char f[3] = {0};
4736     f[0] = '%';
4737     f[1] = fmt;
4738     size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);
4739     char* bb = buf;
4740     char* be = buf + n;
4741     string result;
4742     while (bb != be)
4743     {
4744         if (ct.is(ctype_base::space, *bb))
4745         {
4746             result.push_back(' ');
4747             for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
4748                 ;
4749             continue;
4750         }
4751         char* w = bb;
4752         ios_base::iostate err = ios_base::goodbit;
4753         ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
4754                                ct, err, false)
4755                                - this->__weeks_;
4756         if (i < 14)
4757         {
4758             result.push_back('%');
4759             if (i < 7)
4760                 result.push_back('A');
4761             else
4762                 result.push_back('a');
4763             bb = w;
4764             continue;
4765         }
4766         w = bb;
4767         i = __scan_keyword(w, be, this->__months_, this->__months_+24,
4768                            ct, err, false)
4769                            - this->__months_;
4770         if (i < 24)
4771         {
4772             result.push_back('%');
4773             if (i < 12)
4774                 result.push_back('B');
4775             else
4776                 result.push_back('b');
4777             if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4778                 result.back() = 'm';
4779             bb = w;
4780             continue;
4781         }
4782         if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4783         {
4784             w = bb;
4785             i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
4786                                ct, err, false) - this->__am_pm_;
4787             if (i < 2)
4788             {
4789                 result.push_back('%');
4790                 result.push_back('p');
4791                 bb = w;
4792                 continue;
4793             }
4794         }
4795         w = bb;
4796         if (ct.is(ctype_base::digit, *bb))
4797         {
4798             switch(__get_up_to_n_digits(bb, be, err, ct, 4))
4799             {
4800             case 6:
4801                 result.push_back('%');
4802                 result.push_back('w');
4803                 break;
4804             case 7:
4805                 result.push_back('%');
4806                 result.push_back('u');
4807                 break;
4808             case 11:
4809                 result.push_back('%');
4810                 result.push_back('I');
4811                 break;
4812             case 12:
4813                 result.push_back('%');
4814                 result.push_back('m');
4815                 break;
4816             case 23:
4817                 result.push_back('%');
4818                 result.push_back('H');
4819                 break;
4820             case 31:
4821                 result.push_back('%');
4822                 result.push_back('d');
4823                 break;
4824             case 55:
4825                 result.push_back('%');
4826                 result.push_back('M');
4827                 break;
4828             case 59:
4829                 result.push_back('%');
4830                 result.push_back('S');
4831                 break;
4832             case 61:
4833                 result.push_back('%');
4834                 result.push_back('y');
4835                 break;
4836             case 364:
4837                 result.push_back('%');
4838                 result.push_back('j');
4839                 break;
4840             case 2061:
4841                 result.push_back('%');
4842                 result.push_back('Y');
4843                 break;
4844             default:
4845                 for (; w != bb; ++w)
4846                     result.push_back(*w);
4847                 break;
4848             }
4849             continue;
4850         }
4851         if (*bb == '%')
4852         {
4853             result.push_back('%');
4854             result.push_back('%');
4855             ++bb;
4856             continue;
4857         }
4858         result.push_back(*bb);
4859         ++bb;
4860     }
4861     return result;
4862 }
4863 
4864 #if defined(__clang__)
4865 #pragma clang diagnostic ignored "-Wmissing-braces"
4866 #endif
4867 
4868 template <>
4869 wstring
4870 __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
4871 {
4872     tm t = {0};
4873     t.tm_sec = 59;
4874     t.tm_min = 55;
4875     t.tm_hour = 23;
4876     t.tm_mday = 31;
4877     t.tm_mon = 11;
4878     t.tm_year = 161;
4879     t.tm_wday = 6;
4880     t.tm_yday = 364;
4881     t.tm_isdst = -1;
4882     char buf[100];
4883     char f[3] = {0};
4884     f[0] = '%';
4885     f[1] = fmt;
4886     strftime_l(buf, countof(buf), f, &t, __loc_);
4887     wchar_t wbuf[100];
4888     wchar_t* wbb = wbuf;
4889     mbstate_t mb = {0};
4890     const char* bb = buf;
4891     size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
4892     if (j == size_t(-1))
4893         __throw_runtime_error("locale not supported");
4894     wchar_t* wbe = wbb + j;
4895     wstring result;
4896     while (wbb != wbe)
4897     {
4898         if (ct.is(ctype_base::space, *wbb))
4899         {
4900             result.push_back(L' ');
4901             for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
4902                 ;
4903             continue;
4904         }
4905         wchar_t* w = wbb;
4906         ios_base::iostate err = ios_base::goodbit;
4907         ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
4908                                ct, err, false)
4909                                - this->__weeks_;
4910         if (i < 14)
4911         {
4912             result.push_back(L'%');
4913             if (i < 7)
4914                 result.push_back(L'A');
4915             else
4916                 result.push_back(L'a');
4917             wbb = w;
4918             continue;
4919         }
4920         w = wbb;
4921         i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
4922                            ct, err, false)
4923                            - this->__months_;
4924         if (i < 24)
4925         {
4926             result.push_back(L'%');
4927             if (i < 12)
4928                 result.push_back(L'B');
4929             else
4930                 result.push_back(L'b');
4931             if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4932                 result.back() = L'm';
4933             wbb = w;
4934             continue;
4935         }
4936         if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4937         {
4938             w = wbb;
4939             i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
4940                                ct, err, false) - this->__am_pm_;
4941             if (i < 2)
4942             {
4943                 result.push_back(L'%');
4944                 result.push_back(L'p');
4945                 wbb = w;
4946                 continue;
4947             }
4948         }
4949         w = wbb;
4950         if (ct.is(ctype_base::digit, *wbb))
4951         {
4952             switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
4953             {
4954             case 6:
4955                 result.push_back(L'%');
4956                 result.push_back(L'w');
4957                 break;
4958             case 7:
4959                 result.push_back(L'%');
4960                 result.push_back(L'u');
4961                 break;
4962             case 11:
4963                 result.push_back(L'%');
4964                 result.push_back(L'I');
4965                 break;
4966             case 12:
4967                 result.push_back(L'%');
4968                 result.push_back(L'm');
4969                 break;
4970             case 23:
4971                 result.push_back(L'%');
4972                 result.push_back(L'H');
4973                 break;
4974             case 31:
4975                 result.push_back(L'%');
4976                 result.push_back(L'd');
4977                 break;
4978             case 55:
4979                 result.push_back(L'%');
4980                 result.push_back(L'M');
4981                 break;
4982             case 59:
4983                 result.push_back(L'%');
4984                 result.push_back(L'S');
4985                 break;
4986             case 61:
4987                 result.push_back(L'%');
4988                 result.push_back(L'y');
4989                 break;
4990             case 364:
4991                 result.push_back(L'%');
4992                 result.push_back(L'j');
4993                 break;
4994             case 2061:
4995                 result.push_back(L'%');
4996                 result.push_back(L'Y');
4997                 break;
4998             default:
4999                 for (; w != wbb; ++w)
5000                     result.push_back(*w);
5001                 break;
5002             }
5003             continue;
5004         }
5005         if (ct.narrow(*wbb, 0) == '%')
5006         {
5007             result.push_back(L'%');
5008             result.push_back(L'%');
5009             ++wbb;
5010             continue;
5011         }
5012         result.push_back(*wbb);
5013         ++wbb;
5014     }
5015     return result;
5016 }
5017 
5018 template <>
5019 void
5020 __time_get_storage<char>::init(const ctype<char>& ct)
5021 {
5022     tm t = {0};
5023     char buf[100];
5024     // __weeks_
5025     for (int i = 0; i < 7; ++i)
5026     {
5027         t.tm_wday = i;
5028         strftime_l(buf, countof(buf), "%A", &t, __loc_);
5029         __weeks_[i] = buf;
5030         strftime_l(buf, countof(buf), "%a", &t, __loc_);
5031         __weeks_[i+7] = buf;
5032     }
5033     // __months_
5034     for (int i = 0; i < 12; ++i)
5035     {
5036         t.tm_mon = i;
5037         strftime_l(buf, countof(buf), "%B", &t, __loc_);
5038         __months_[i] = buf;
5039         strftime_l(buf, countof(buf), "%b", &t, __loc_);
5040         __months_[i+12] = buf;
5041     }
5042     // __am_pm_
5043     t.tm_hour = 1;
5044     strftime_l(buf, countof(buf), "%p", &t, __loc_);
5045     __am_pm_[0] = buf;
5046     t.tm_hour = 13;
5047     strftime_l(buf, countof(buf), "%p", &t, __loc_);
5048     __am_pm_[1] = buf;
5049     __c_ = __analyze('c', ct);
5050     __r_ = __analyze('r', ct);
5051     __x_ = __analyze('x', ct);
5052     __X_ = __analyze('X', ct);
5053 }
5054 
5055 template <>
5056 void
5057 __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
5058 {
5059     tm t = {0};
5060     char buf[100];
5061     wchar_t wbuf[100];
5062     wchar_t* wbe;
5063     mbstate_t mb = {0};
5064     // __weeks_
5065     for (int i = 0; i < 7; ++i)
5066     {
5067         t.tm_wday = i;
5068         strftime_l(buf, countof(buf), "%A", &t, __loc_);
5069         mb = mbstate_t();
5070         const char* bb = buf;
5071         size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5072         if (j == size_t(-1))
5073             __throw_runtime_error("locale not supported");
5074         wbe = wbuf + j;
5075         __weeks_[i].assign(wbuf, wbe);
5076         strftime_l(buf, countof(buf), "%a", &t, __loc_);
5077         mb = mbstate_t();
5078         bb = buf;
5079         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5080         if (j == size_t(-1))
5081             __throw_runtime_error("locale not supported");
5082         wbe = wbuf + j;
5083         __weeks_[i+7].assign(wbuf, wbe);
5084     }
5085     // __months_
5086     for (int i = 0; i < 12; ++i)
5087     {
5088         t.tm_mon = i;
5089         strftime_l(buf, countof(buf), "%B", &t, __loc_);
5090         mb = mbstate_t();
5091         const char* bb = buf;
5092         size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5093         if (j == size_t(-1))
5094             __throw_runtime_error("locale not supported");
5095         wbe = wbuf + j;
5096         __months_[i].assign(wbuf, wbe);
5097         strftime_l(buf, countof(buf), "%b", &t, __loc_);
5098         mb = mbstate_t();
5099         bb = buf;
5100         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5101         if (j == size_t(-1))
5102             __throw_runtime_error("locale not supported");
5103         wbe = wbuf + j;
5104         __months_[i+12].assign(wbuf, wbe);
5105     }
5106     // __am_pm_
5107     t.tm_hour = 1;
5108     strftime_l(buf, countof(buf), "%p", &t, __loc_);
5109     mb = mbstate_t();
5110     const char* bb = buf;
5111     size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5112     if (j == size_t(-1))
5113         __throw_runtime_error("locale not supported");
5114     wbe = wbuf + j;
5115     __am_pm_[0].assign(wbuf, wbe);
5116     t.tm_hour = 13;
5117     strftime_l(buf, countof(buf), "%p", &t, __loc_);
5118     mb = mbstate_t();
5119     bb = buf;
5120     j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5121     if (j == size_t(-1))
5122         __throw_runtime_error("locale not supported");
5123     wbe = wbuf + j;
5124     __am_pm_[1].assign(wbuf, wbe);
5125     __c_ = __analyze('c', ct);
5126     __r_ = __analyze('r', ct);
5127     __x_ = __analyze('x', ct);
5128     __X_ = __analyze('X', ct);
5129 }
5130 
5131 template <class CharT>
5132 struct _LIBCPP_HIDDEN __time_get_temp
5133     : public ctype_byname<CharT>
5134 {
5135     explicit __time_get_temp(const char* nm)
5136         : ctype_byname<CharT>(nm, 1) {}
5137     explicit __time_get_temp(const string& nm)
5138         : ctype_byname<CharT>(nm, 1) {}
5139 };
5140 
5141 template <>
5142 __time_get_storage<char>::__time_get_storage(const char* __nm)
5143     : __time_get(__nm)
5144 {
5145     const __time_get_temp<char> ct(__nm);
5146     init(ct);
5147 }
5148 
5149 template <>
5150 __time_get_storage<char>::__time_get_storage(const string& __nm)
5151     : __time_get(__nm)
5152 {
5153     const __time_get_temp<char> ct(__nm);
5154     init(ct);
5155 }
5156 
5157 template <>
5158 __time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5159     : __time_get(__nm)
5160 {
5161     const __time_get_temp<wchar_t> ct(__nm);
5162     init(ct);
5163 }
5164 
5165 template <>
5166 __time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5167     : __time_get(__nm)
5168 {
5169     const __time_get_temp<wchar_t> ct(__nm);
5170     init(ct);
5171 }
5172 
5173 template <>
5174 time_base::dateorder
5175 __time_get_storage<char>::__do_date_order() const
5176 {
5177     unsigned i;
5178     for (i = 0; i < __x_.size(); ++i)
5179         if (__x_[i] == '%')
5180             break;
5181     ++i;
5182     switch (__x_[i])
5183     {
5184     case 'y':
5185     case 'Y':
5186         for (++i; i < __x_.size(); ++i)
5187             if (__x_[i] == '%')
5188                 break;
5189         if (i == __x_.size())
5190             break;
5191         ++i;
5192         switch (__x_[i])
5193         {
5194         case 'm':
5195             for (++i; i < __x_.size(); ++i)
5196                 if (__x_[i] == '%')
5197                     break;
5198             if (i == __x_.size())
5199                 break;
5200             ++i;
5201             if (__x_[i] == 'd')
5202                 return time_base::ymd;
5203             break;
5204         case 'd':
5205             for (++i; i < __x_.size(); ++i)
5206                 if (__x_[i] == '%')
5207                     break;
5208             if (i == __x_.size())
5209                 break;
5210             ++i;
5211             if (__x_[i] == 'm')
5212                 return time_base::ydm;
5213             break;
5214         }
5215         break;
5216     case 'm':
5217         for (++i; i < __x_.size(); ++i)
5218             if (__x_[i] == '%')
5219                 break;
5220         if (i == __x_.size())
5221             break;
5222         ++i;
5223         if (__x_[i] == 'd')
5224         {
5225             for (++i; i < __x_.size(); ++i)
5226                 if (__x_[i] == '%')
5227                     break;
5228             if (i == __x_.size())
5229                 break;
5230             ++i;
5231             if (__x_[i] == 'y' || __x_[i] == 'Y')
5232                 return time_base::mdy;
5233             break;
5234         }
5235         break;
5236     case 'd':
5237         for (++i; i < __x_.size(); ++i)
5238             if (__x_[i] == '%')
5239                 break;
5240         if (i == __x_.size())
5241             break;
5242         ++i;
5243         if (__x_[i] == 'm')
5244         {
5245             for (++i; i < __x_.size(); ++i)
5246                 if (__x_[i] == '%')
5247                     break;
5248             if (i == __x_.size())
5249                 break;
5250             ++i;
5251             if (__x_[i] == 'y' || __x_[i] == 'Y')
5252                 return time_base::dmy;
5253             break;
5254         }
5255         break;
5256     }
5257     return time_base::no_order;
5258 }
5259 
5260 template <>
5261 time_base::dateorder
5262 __time_get_storage<wchar_t>::__do_date_order() const
5263 {
5264     unsigned i;
5265     for (i = 0; i < __x_.size(); ++i)
5266         if (__x_[i] == L'%')
5267             break;
5268     ++i;
5269     switch (__x_[i])
5270     {
5271     case L'y':
5272     case L'Y':
5273         for (++i; i < __x_.size(); ++i)
5274             if (__x_[i] == L'%')
5275                 break;
5276         if (i == __x_.size())
5277             break;
5278         ++i;
5279         switch (__x_[i])
5280         {
5281         case L'm':
5282             for (++i; i < __x_.size(); ++i)
5283                 if (__x_[i] == L'%')
5284                     break;
5285             if (i == __x_.size())
5286                 break;
5287             ++i;
5288             if (__x_[i] == L'd')
5289                 return time_base::ymd;
5290             break;
5291         case L'd':
5292             for (++i; i < __x_.size(); ++i)
5293                 if (__x_[i] == L'%')
5294                     break;
5295             if (i == __x_.size())
5296                 break;
5297             ++i;
5298             if (__x_[i] == L'm')
5299                 return time_base::ydm;
5300             break;
5301         }
5302         break;
5303     case L'm':
5304         for (++i; i < __x_.size(); ++i)
5305             if (__x_[i] == L'%')
5306                 break;
5307         if (i == __x_.size())
5308             break;
5309         ++i;
5310         if (__x_[i] == L'd')
5311         {
5312             for (++i; i < __x_.size(); ++i)
5313                 if (__x_[i] == L'%')
5314                     break;
5315             if (i == __x_.size())
5316                 break;
5317             ++i;
5318             if (__x_[i] == L'y' || __x_[i] == L'Y')
5319                 return time_base::mdy;
5320             break;
5321         }
5322         break;
5323     case L'd':
5324         for (++i; i < __x_.size(); ++i)
5325             if (__x_[i] == L'%')
5326                 break;
5327         if (i == __x_.size())
5328             break;
5329         ++i;
5330         if (__x_[i] == L'm')
5331         {
5332             for (++i; i < __x_.size(); ++i)
5333                 if (__x_[i] == L'%')
5334                     break;
5335             if (i == __x_.size())
5336                 break;
5337             ++i;
5338             if (__x_[i] == L'y' || __x_[i] == L'Y')
5339                 return time_base::dmy;
5340             break;
5341         }
5342         break;
5343     }
5344     return time_base::no_order;
5345 }
5346 
5347 // time_put
5348 
5349 __time_put::__time_put(const char* nm)
5350     : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5351 {
5352     if (__loc_ == 0)
5353         __throw_runtime_error("time_put_byname"
5354                             " failed to construct for " + string(nm));
5355 }
5356 
5357 __time_put::__time_put(const string& nm)
5358     : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5359 {
5360     if (__loc_ == 0)
5361         __throw_runtime_error("time_put_byname"
5362                             " failed to construct for " + nm);
5363 }
5364 
5365 __time_put::~__time_put()
5366 {
5367     if (__loc_ != _LIBCPP_GET_C_LOCALE)
5368         freelocale(__loc_);
5369 }
5370 
5371 void
5372 __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5373                      char __fmt, char __mod) const
5374 {
5375     char fmt[] = {'%', __fmt, __mod, 0};
5376     if (__mod != 0)
5377         swap(fmt[1], fmt[2]);
5378     size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
5379     __ne = __nb + n;
5380 }
5381 
5382 void
5383 __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5384                      char __fmt, char __mod) const
5385 {
5386     char __nar[100];
5387     char* __ne = __nar + 100;
5388     __do_put(__nar, __ne, __tm, __fmt, __mod);
5389     mbstate_t mb = {0};
5390     const char* __nb = __nar;
5391     size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
5392     if (j == size_t(-1))
5393         __throw_runtime_error("locale not supported");
5394     __we = __wb + j;
5395 }
5396 
5397 // moneypunct_byname
5398 
5399 template <class charT>
5400 static
5401 void
5402 __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
5403            bool intl, char cs_precedes, char sep_by_space, char sign_posn,
5404            charT space_char)
5405 {
5406     const char sign = static_cast<char>(money_base::sign);
5407     const char space = static_cast<char>(money_base::space);
5408     const char none = static_cast<char>(money_base::none);
5409     const char symbol = static_cast<char>(money_base::symbol);
5410     const char value = static_cast<char>(money_base::value);
5411     const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
5412 
5413     // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5414     // function'. "Space between sign and symbol or value" means that
5415     // if the sign is adjacent to the symbol, there's a space between
5416     // them, and otherwise there's a space between the sign and value.
5417     //
5418     // C11's localeconv specifies that the fourth character of an
5419     // international curr_symbol is used to separate the sign and
5420     // value when sep_by_space says to do so. C++ can't represent
5421     // that, so we just use a space.  When sep_by_space says to
5422     // separate the symbol and value-or-sign with a space, we rearrange the
5423     // curr_symbol to put its spacing character on the correct side of
5424     // the symbol.
5425     //
5426     // We also need to avoid adding an extra space between the sign
5427     // and value when the currency symbol is suppressed (by not
5428     // setting showbase).  We match glibc's strfmon by interpreting
5429     // sep_by_space==1 as "omit the space when the currency symbol is
5430     // absent".
5431     //
5432     // Users who want to get this right should use ICU instead.
5433 
5434     switch (cs_precedes)
5435     {
5436     case 0:  // value before curr_symbol
5437         if (symbol_contains_sep) {
5438             // Move the separator to before the symbol, to place it
5439             // between the value and symbol.
5440             rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,
5441                    __curr_symbol_.end());
5442         }
5443         switch (sign_posn)
5444         {
5445         case 0:  // Parentheses surround the quantity and currency symbol.
5446             pat.field[0] = sign;
5447             pat.field[1] = value;
5448             pat.field[2] = none;  // Any space appears in the symbol.
5449             pat.field[3] = symbol;
5450             switch (sep_by_space)
5451             {
5452             case 0:  // No space separates the currency symbol and value.
5453                 // This case may have changed between C99 and C11;
5454                 // assume the currency symbol matches the intention.
5455             case 2:  // Space between sign and currency or value.
5456                 // The "sign" is two parentheses, so no space here either.
5457                 return;
5458             case 1:  // Space between currency-and-sign or currency and value.
5459                 if (!symbol_contains_sep) {
5460                     // We insert the space into the symbol instead of
5461                     // setting pat.field[2]=space so that when
5462                     // showbase is not set, the space goes away too.
5463                     __curr_symbol_.insert(0, 1, space_char);
5464                 }
5465                 return;
5466             default:
5467                 break;
5468             }
5469             break;
5470         case 1:  // The sign string precedes the quantity and currency symbol.
5471             pat.field[0] = sign;
5472             pat.field[3] = symbol;
5473             switch (sep_by_space)
5474             {
5475             case 0:  // No space separates the currency symbol and value.
5476                 pat.field[1] = value;
5477                 pat.field[2] = none;
5478                 return;
5479             case 1:  // Space between currency-and-sign or currency and value.
5480                 pat.field[1] = value;
5481                 pat.field[2] = none;
5482                 if (!symbol_contains_sep) {
5483                     // We insert the space into the symbol instead of
5484                     // setting pat.field[2]=space so that when
5485                     // showbase is not set, the space goes away too.
5486                     __curr_symbol_.insert(0, 1, space_char);
5487                 }
5488                 return;
5489             case 2:  // Space between sign and currency or value.
5490                 pat.field[1] = space;
5491                 pat.field[2] = value;
5492                 if (symbol_contains_sep) {
5493                     // Remove the separator from the symbol, since it
5494                     // has already appeared after the sign.
5495                     __curr_symbol_.erase(__curr_symbol_.begin());
5496                 }
5497                 return;
5498             default:
5499                 break;
5500             }
5501             break;
5502         case 2:  // The sign string succeeds the quantity and currency symbol.
5503             pat.field[0] = value;
5504             pat.field[3] = sign;
5505             switch (sep_by_space)
5506             {
5507             case 0:  // No space separates the currency symbol and value.
5508                 pat.field[1] = none;
5509                 pat.field[2] = symbol;
5510                 return;
5511             case 1:  // Space between currency-and-sign or currency and value.
5512                 if (!symbol_contains_sep) {
5513                     // We insert the space into the symbol instead of
5514                     // setting pat.field[1]=space so that when
5515                     // showbase is not set, the space goes away too.
5516                     __curr_symbol_.insert(0, 1, space_char);
5517                 }
5518                 pat.field[1] = none;
5519                 pat.field[2] = symbol;
5520                 return;
5521             case 2:  // Space between sign and currency or value.
5522                 pat.field[1] = symbol;
5523                 pat.field[2] = space;
5524                 if (symbol_contains_sep) {
5525                     // Remove the separator from the symbol, since it
5526                     // should not be removed if showbase is absent.
5527                     __curr_symbol_.erase(__curr_symbol_.begin());
5528                 }
5529                 return;
5530             default:
5531                 break;
5532             }
5533             break;
5534         case 3:  // The sign string immediately precedes the currency symbol.
5535             pat.field[0] = value;
5536             pat.field[3] = symbol;
5537             switch (sep_by_space)
5538             {
5539             case 0:  // No space separates the currency symbol and value.
5540                 pat.field[1] = none;
5541                 pat.field[2] = sign;
5542                 return;
5543             case 1:  // Space between currency-and-sign or currency and value.
5544                 pat.field[1] = space;
5545                 pat.field[2] = sign;
5546                 if (symbol_contains_sep) {
5547                     // Remove the separator from the symbol, since it
5548                     // has already appeared before the sign.
5549                     __curr_symbol_.erase(__curr_symbol_.begin());
5550                 }
5551                 return;
5552             case 2:  // Space between sign and currency or value.
5553                 pat.field[1] = sign;
5554                 pat.field[2] = none;
5555                 if (!symbol_contains_sep) {
5556                     // We insert the space into the symbol instead of
5557                     // setting pat.field[2]=space so that when
5558                     // showbase is not set, the space goes away too.
5559                     __curr_symbol_.insert(0, 1, space_char);
5560                 }
5561                 return;
5562             default:
5563                 break;
5564             }
5565             break;
5566         case 4:  // The sign string immediately succeeds the currency symbol.
5567             pat.field[0] = value;
5568             pat.field[3] = sign;
5569             switch (sep_by_space)
5570             {
5571             case 0:  // No space separates the currency symbol and value.
5572                 pat.field[1] = none;
5573                 pat.field[2] = symbol;
5574                 return;
5575             case 1:  // Space between currency-and-sign or currency and value.
5576                 pat.field[1] = none;
5577                 pat.field[2] = symbol;
5578                 if (!symbol_contains_sep) {
5579                     // We insert the space into the symbol instead of
5580                     // setting pat.field[1]=space so that when
5581                     // showbase is not set, the space goes away too.
5582                     __curr_symbol_.insert(0, 1, space_char);
5583                 }
5584                 return;
5585             case 2:  // Space between sign and currency or value.
5586                 pat.field[1] = symbol;
5587                 pat.field[2] = space;
5588                 if (symbol_contains_sep) {
5589                     // Remove the separator from the symbol, since it
5590                     // should not disappear when showbase is absent.
5591                     __curr_symbol_.erase(__curr_symbol_.begin());
5592                 }
5593                 return;
5594             default:
5595                 break;
5596             }
5597             break;
5598         default:
5599             break;
5600         }
5601         break;
5602     case 1:  // curr_symbol before value
5603         switch (sign_posn)
5604         {
5605         case 0:  // Parentheses surround the quantity and currency symbol.
5606             pat.field[0] = sign;
5607             pat.field[1] = symbol;
5608             pat.field[2] = none;  // Any space appears in the symbol.
5609             pat.field[3] = value;
5610             switch (sep_by_space)
5611             {
5612             case 0:  // No space separates the currency symbol and value.
5613                 // This case may have changed between C99 and C11;
5614                 // assume the currency symbol matches the intention.
5615             case 2:  // Space between sign and currency or value.
5616                 // The "sign" is two parentheses, so no space here either.
5617                 return;
5618             case 1:  // Space between currency-and-sign or currency and value.
5619                 if (!symbol_contains_sep) {
5620                     // We insert the space into the symbol instead of
5621                     // setting pat.field[2]=space so that when
5622                     // showbase is not set, the space goes away too.
5623                     __curr_symbol_.insert(0, 1, space_char);
5624                 }
5625                 return;
5626             default:
5627                 break;
5628             }
5629             break;
5630         case 1:  // The sign string precedes the quantity and currency symbol.
5631             pat.field[0] = sign;
5632             pat.field[3] = value;
5633             switch (sep_by_space)
5634             {
5635             case 0:  // No space separates the currency symbol and value.
5636                 pat.field[1] = symbol;
5637                 pat.field[2] = none;
5638                 return;
5639             case 1:  // Space between currency-and-sign or currency and value.
5640                 pat.field[1] = symbol;
5641                 pat.field[2] = none;
5642                 if (!symbol_contains_sep) {
5643                     // We insert the space into the symbol instead of
5644                     // setting pat.field[2]=space so that when
5645                     // showbase is not set, the space goes away too.
5646                     __curr_symbol_.push_back(space_char);
5647                 }
5648                 return;
5649             case 2:  // Space between sign and currency or value.
5650                 pat.field[1] = space;
5651                 pat.field[2] = symbol;
5652                 if (symbol_contains_sep) {
5653                     // Remove the separator from the symbol, since it
5654                     // has already appeared after the sign.
5655                     __curr_symbol_.pop_back();
5656                 }
5657                 return;
5658             default:
5659                 break;
5660             }
5661             break;
5662         case 2:  // The sign string succeeds the quantity and currency symbol.
5663             pat.field[0] = symbol;
5664             pat.field[3] = sign;
5665             switch (sep_by_space)
5666             {
5667             case 0:  // No space separates the currency symbol and value.
5668                 pat.field[1] = none;
5669                 pat.field[2] = value;
5670                 return;
5671             case 1:  // Space between currency-and-sign or currency and value.
5672                 pat.field[1] = none;
5673                 pat.field[2] = value;
5674                 if (!symbol_contains_sep) {
5675                     // We insert the space into the symbol instead of
5676                     // setting pat.field[1]=space so that when
5677                     // showbase is not set, the space goes away too.
5678                     __curr_symbol_.push_back(space_char);
5679                 }
5680                 return;
5681             case 2:  // Space between sign and currency or value.
5682                 pat.field[1] = value;
5683                 pat.field[2] = space;
5684                 if (symbol_contains_sep) {
5685                     // Remove the separator from the symbol, since it
5686                     // will appear before the sign.
5687                     __curr_symbol_.pop_back();
5688                 }
5689                 return;
5690             default:
5691                 break;
5692             }
5693             break;
5694         case 3:  // The sign string immediately precedes the currency symbol.
5695             pat.field[0] = sign;
5696             pat.field[3] = value;
5697             switch (sep_by_space)
5698             {
5699             case 0:  // No space separates the currency symbol and value.
5700                 pat.field[1] = symbol;
5701                 pat.field[2] = none;
5702                 return;
5703             case 1:  // Space between currency-and-sign or currency and value.
5704                 pat.field[1] = symbol;
5705                 pat.field[2] = none;
5706                 if (!symbol_contains_sep) {
5707                     // We insert the space into the symbol instead of
5708                     // setting pat.field[2]=space so that when
5709                     // showbase is not set, the space goes away too.
5710                     __curr_symbol_.push_back(space_char);
5711                 }
5712                 return;
5713             case 2:  // Space between sign and currency or value.
5714                 pat.field[1] = space;
5715                 pat.field[2] = symbol;
5716                 if (symbol_contains_sep) {
5717                     // Remove the separator from the symbol, since it
5718                     // has already appeared after the sign.
5719                     __curr_symbol_.pop_back();
5720                 }
5721                 return;
5722             default:
5723                 break;
5724             }
5725             break;
5726         case 4:  // The sign string immediately succeeds the currency symbol.
5727             pat.field[0] = symbol;
5728             pat.field[3] = value;
5729             switch (sep_by_space)
5730             {
5731             case 0:  // No space separates the currency symbol and value.
5732                 pat.field[1] = sign;
5733                 pat.field[2] = none;
5734                 return;
5735             case 1:  // Space between currency-and-sign or currency and value.
5736                 pat.field[1] = sign;
5737                 pat.field[2] = space;
5738                 if (symbol_contains_sep) {
5739                     // Remove the separator from the symbol, since it
5740                     // should not disappear when showbase is absent.
5741                     __curr_symbol_.pop_back();
5742                 }
5743                 return;
5744             case 2:  // Space between sign and currency or value.
5745                 pat.field[1] = none;
5746                 pat.field[2] = sign;
5747                 if (!symbol_contains_sep) {
5748                     // We insert the space into the symbol instead of
5749                     // setting pat.field[1]=space so that when
5750                     // showbase is not set, the space goes away too.
5751                     __curr_symbol_.push_back(space_char);
5752                 }
5753                 return;
5754            default:
5755                 break;
5756             }
5757             break;
5758         default:
5759             break;
5760         }
5761         break;
5762     default:
5763         break;
5764     }
5765     pat.field[0] = symbol;
5766     pat.field[1] = sign;
5767     pat.field[2] = none;
5768     pat.field[3] = value;
5769 }
5770 
5771 template<>
5772 void
5773 moneypunct_byname<char, false>::init(const char* nm)
5774 {
5775     typedef moneypunct<char, false> base;
5776     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5777     if (loc == nullptr)
5778         __throw_runtime_error("moneypunct_byname"
5779                             " failed to construct for " + string(nm));
5780 
5781     lconv* lc = __libcpp_localeconv_l(loc.get());
5782     if (*lc->mon_decimal_point)
5783         __decimal_point_ = *lc->mon_decimal_point;
5784     else
5785         __decimal_point_ = base::do_decimal_point();
5786     if (*lc->mon_thousands_sep)
5787         __thousands_sep_ = *lc->mon_thousands_sep;
5788     else
5789         __thousands_sep_ = base::do_thousands_sep();
5790     __grouping_ = lc->mon_grouping;
5791     __curr_symbol_ = lc->currency_symbol;
5792     if (lc->frac_digits != CHAR_MAX)
5793         __frac_digits_ = lc->frac_digits;
5794     else
5795         __frac_digits_ = base::do_frac_digits();
5796     if (lc->p_sign_posn == 0)
5797         __positive_sign_ = "()";
5798     else
5799         __positive_sign_ = lc->positive_sign;
5800     if (lc->n_sign_posn == 0)
5801         __negative_sign_ = "()";
5802     else
5803         __negative_sign_ = lc->negative_sign;
5804     // Assume the positive and negative formats will want spaces in
5805     // the same places in curr_symbol since there's no way to
5806     // represent anything else.
5807     string_type __dummy_curr_symbol = __curr_symbol_;
5808     __init_pat(__pos_format_, __dummy_curr_symbol, false,
5809                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5810     __init_pat(__neg_format_, __curr_symbol_, false,
5811                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5812 }
5813 
5814 template<>
5815 void
5816 moneypunct_byname<char, true>::init(const char* nm)
5817 {
5818     typedef moneypunct<char, true> base;
5819     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5820     if (loc == nullptr)
5821         __throw_runtime_error("moneypunct_byname"
5822                             " failed to construct for " + string(nm));
5823 
5824     lconv* lc = __libcpp_localeconv_l(loc.get());
5825     if (*lc->mon_decimal_point)
5826         __decimal_point_ = *lc->mon_decimal_point;
5827     else
5828         __decimal_point_ = base::do_decimal_point();
5829     if (*lc->mon_thousands_sep)
5830         __thousands_sep_ = *lc->mon_thousands_sep;
5831     else
5832         __thousands_sep_ = base::do_thousands_sep();
5833     __grouping_ = lc->mon_grouping;
5834     __curr_symbol_ = lc->int_curr_symbol;
5835     if (lc->int_frac_digits != CHAR_MAX)
5836         __frac_digits_ = lc->int_frac_digits;
5837     else
5838         __frac_digits_ = base::do_frac_digits();
5839 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5840     if (lc->p_sign_posn == 0)
5841 #else // _LIBCPP_MSVCRT
5842     if (lc->int_p_sign_posn == 0)
5843 #endif // !_LIBCPP_MSVCRT
5844         __positive_sign_ = "()";
5845     else
5846         __positive_sign_ = lc->positive_sign;
5847 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5848     if(lc->n_sign_posn == 0)
5849 #else // _LIBCPP_MSVCRT
5850     if (lc->int_n_sign_posn == 0)
5851 #endif // !_LIBCPP_MSVCRT
5852         __negative_sign_ = "()";
5853     else
5854         __negative_sign_ = lc->negative_sign;
5855     // Assume the positive and negative formats will want spaces in
5856     // the same places in curr_symbol since there's no way to
5857     // represent anything else.
5858     string_type __dummy_curr_symbol = __curr_symbol_;
5859 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5860     __init_pat(__pos_format_, __dummy_curr_symbol, true,
5861                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5862     __init_pat(__neg_format_, __curr_symbol_, true,
5863                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5864 #else // _LIBCPP_MSVCRT
5865     __init_pat(__pos_format_, __dummy_curr_symbol, true,
5866                lc->int_p_cs_precedes, lc->int_p_sep_by_space,
5867                lc->int_p_sign_posn, ' ');
5868     __init_pat(__neg_format_, __curr_symbol_, true,
5869                lc->int_n_cs_precedes, lc->int_n_sep_by_space,
5870                lc->int_n_sign_posn, ' ');
5871 #endif // !_LIBCPP_MSVCRT
5872 }
5873 
5874 template<>
5875 void
5876 moneypunct_byname<wchar_t, false>::init(const char* nm)
5877 {
5878     typedef moneypunct<wchar_t, false> base;
5879     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5880     if (loc == nullptr)
5881         __throw_runtime_error("moneypunct_byname"
5882                             " failed to construct for " + string(nm));
5883     lconv* lc = __libcpp_localeconv_l(loc.get());
5884     if (*lc->mon_decimal_point)
5885         __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
5886     else
5887         __decimal_point_ = base::do_decimal_point();
5888     if (*lc->mon_thousands_sep)
5889         __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
5890     else
5891         __thousands_sep_ = base::do_thousands_sep();
5892     __grouping_ = lc->mon_grouping;
5893     wchar_t wbuf[100];
5894     mbstate_t mb = {0};
5895     const char* bb = lc->currency_symbol;
5896     size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5897     if (j == size_t(-1))
5898         __throw_runtime_error("locale not supported");
5899     wchar_t* wbe = wbuf + j;
5900     __curr_symbol_.assign(wbuf, wbe);
5901     if (lc->frac_digits != CHAR_MAX)
5902         __frac_digits_ = lc->frac_digits;
5903     else
5904         __frac_digits_ = base::do_frac_digits();
5905     if (lc->p_sign_posn == 0)
5906         __positive_sign_ = L"()";
5907     else
5908     {
5909         mb = mbstate_t();
5910         bb = lc->positive_sign;
5911         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5912         if (j == size_t(-1))
5913             __throw_runtime_error("locale not supported");
5914         wbe = wbuf + j;
5915         __positive_sign_.assign(wbuf, wbe);
5916     }
5917     if (lc->n_sign_posn == 0)
5918         __negative_sign_ = L"()";
5919     else
5920     {
5921         mb = mbstate_t();
5922         bb = lc->negative_sign;
5923         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5924         if (j == size_t(-1))
5925             __throw_runtime_error("locale not supported");
5926         wbe = wbuf + j;
5927         __negative_sign_.assign(wbuf, wbe);
5928     }
5929     // Assume the positive and negative formats will want spaces in
5930     // the same places in curr_symbol since there's no way to
5931     // represent anything else.
5932     string_type __dummy_curr_symbol = __curr_symbol_;
5933     __init_pat(__pos_format_, __dummy_curr_symbol, false,
5934                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
5935     __init_pat(__neg_format_, __curr_symbol_, false,
5936                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
5937 }
5938 
5939 template<>
5940 void
5941 moneypunct_byname<wchar_t, true>::init(const char* nm)
5942 {
5943     typedef moneypunct<wchar_t, true> base;
5944     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5945     if (loc == nullptr)
5946         __throw_runtime_error("moneypunct_byname"
5947                             " failed to construct for " + string(nm));
5948 
5949     lconv* lc = __libcpp_localeconv_l(loc.get());
5950     if (*lc->mon_decimal_point)
5951         __decimal_point_ = static_cast<wchar_t>(*lc->mon_decimal_point);
5952     else
5953         __decimal_point_ = base::do_decimal_point();
5954     if (*lc->mon_thousands_sep)
5955         __thousands_sep_ = static_cast<wchar_t>(*lc->mon_thousands_sep);
5956     else
5957         __thousands_sep_ = base::do_thousands_sep();
5958     __grouping_ = lc->mon_grouping;
5959     wchar_t wbuf[100];
5960     mbstate_t mb = {0};
5961     const char* bb = lc->int_curr_symbol;
5962     size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5963     if (j == size_t(-1))
5964         __throw_runtime_error("locale not supported");
5965     wchar_t* wbe = wbuf + j;
5966     __curr_symbol_.assign(wbuf, wbe);
5967     if (lc->int_frac_digits != CHAR_MAX)
5968         __frac_digits_ = lc->int_frac_digits;
5969     else
5970         __frac_digits_ = base::do_frac_digits();
5971 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5972     if (lc->p_sign_posn == 0)
5973 #else // _LIBCPP_MSVCRT
5974     if (lc->int_p_sign_posn == 0)
5975 #endif // !_LIBCPP_MSVCRT
5976         __positive_sign_ = L"()";
5977     else
5978     {
5979         mb = mbstate_t();
5980         bb = lc->positive_sign;
5981         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5982         if (j == size_t(-1))
5983             __throw_runtime_error("locale not supported");
5984         wbe = wbuf + j;
5985         __positive_sign_.assign(wbuf, wbe);
5986     }
5987 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5988     if (lc->n_sign_posn == 0)
5989 #else // _LIBCPP_MSVCRT
5990     if (lc->int_n_sign_posn == 0)
5991 #endif // !_LIBCPP_MSVCRT
5992         __negative_sign_ = L"()";
5993     else
5994     {
5995         mb = mbstate_t();
5996         bb = lc->negative_sign;
5997         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5998         if (j == size_t(-1))
5999             __throw_runtime_error("locale not supported");
6000         wbe = wbuf + j;
6001         __negative_sign_.assign(wbuf, wbe);
6002     }
6003     // Assume the positive and negative formats will want spaces in
6004     // the same places in curr_symbol since there's no way to
6005     // represent anything else.
6006     string_type __dummy_curr_symbol = __curr_symbol_;
6007 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6008     __init_pat(__pos_format_, __dummy_curr_symbol, true,
6009                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6010     __init_pat(__neg_format_, __curr_symbol_, true,
6011                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6012 #else // _LIBCPP_MSVCRT
6013     __init_pat(__pos_format_, __dummy_curr_symbol, true,
6014                lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6015                lc->int_p_sign_posn, L' ');
6016     __init_pat(__neg_format_, __curr_symbol_, true,
6017                lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6018                lc->int_n_sign_posn, L' ');
6019 #endif // !_LIBCPP_MSVCRT
6020 }
6021 
6022 void __do_nothing(void*) {}
6023 
6024 void __throw_runtime_error(const char* msg)
6025 {
6026 #ifndef _LIBCPP_NO_EXCEPTIONS
6027     throw runtime_error(msg);
6028 #else
6029     (void)msg;
6030     _VSTD::abort();
6031 #endif
6032 }
6033 
6034 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;
6035 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;
6036 
6037 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<char>;
6038 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<wchar_t>;
6039 
6040 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<char>;
6041 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<wchar_t>;
6042 
6043 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<char>;
6044 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<wchar_t>;
6045 
6046 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<char>;
6047 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<wchar_t>;
6048 
6049 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<char>;
6050 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<wchar_t>;
6051 
6052 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<char>;
6053 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<wchar_t>;
6054 
6055 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<char>;
6056 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<wchar_t>;
6057 
6058 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<char>;
6059 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<wchar_t>;
6060 
6061 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, false>;
6062 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, true>;
6063 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, false>;
6064 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, true>;
6065 
6066 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, false>;
6067 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, true>;
6068 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, false>;
6069 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, true>;
6070 
6071 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<char>;
6072 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<wchar_t>;
6073 
6074 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<char>;
6075 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<wchar_t>;
6076 
6077 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<char>;
6078 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<wchar_t>;
6079 
6080 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<char>;
6081 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<wchar_t>;
6082 
6083 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<char>;
6084 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<wchar_t>;
6085 
6086 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<char>;
6087 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t>;
6088 
6089 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>;
6090 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;
6091 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
6092 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
6093 
6094 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __vector_base_common<true>;
6095 
6096 _LIBCPP_END_NAMESPACE_STD
6097