xref: /llvm-project-15.0.7/libcxx/src/locale.cpp (revision f4debddb)
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 
4187 static bool checked_string_to_wchar_convert(wchar_t& dest,
4188                                             const char* ptr,
4189                                             __locale_struct* loc) {
4190   if (*ptr == '\0')
4191     return false;
4192   mbstate_t mb = {};
4193   wchar_t out;
4194   size_t ret = __libcpp_mbrtowc_l(&out, ptr, strlen(ptr), &mb, loc);
4195   if (ret == static_cast<size_t>(-1) || ret == static_cast<size_t>(-2)) {
4196     return false;
4197   }
4198   dest = out;
4199   return true;
4200 }
4201 
4202 static bool checked_string_to_char_convert(char& dest,
4203                                            const char* ptr,
4204                                            __locale_struct* __loc) {
4205   if (*ptr == '\0')
4206     return false;
4207   if (!ptr[1]) {
4208     dest = *ptr;
4209     return true;
4210   }
4211   // First convert the MBS into a wide char then attempt to narrow it using
4212   // wctob_l.
4213   wchar_t wout;
4214   if (!checked_string_to_wchar_convert(wout, ptr, __loc))
4215     return false;
4216   int res;
4217   if ((res = __libcpp_wctob_l(wout, __loc)) != char_traits<char>::eof()) {
4218     dest = res;
4219     return true;
4220   }
4221   // FIXME: Work around specific multibyte sequences that we can reasonable
4222   // translate into a different single byte.
4223   switch (wout) {
4224   case L'\u00A0': // non-breaking space
4225     dest = ' ';
4226     return true;
4227   default:
4228     return false;
4229   }
4230   _LIBCPP_UNREACHABLE();
4231 }
4232 
4233 
4234 // numpunct<char> && numpunct<wchar_t>
4235 
4236 locale::id numpunct< char  >::id;
4237 locale::id numpunct<wchar_t>::id;
4238 
4239 numpunct<char>::numpunct(size_t refs)
4240     : locale::facet(refs),
4241       __decimal_point_('.'),
4242       __thousands_sep_(',')
4243 {
4244 }
4245 
4246 numpunct<wchar_t>::numpunct(size_t refs)
4247     : locale::facet(refs),
4248       __decimal_point_(L'.'),
4249       __thousands_sep_(L',')
4250 {
4251 }
4252 
4253 numpunct<char>::~numpunct()
4254 {
4255 }
4256 
4257 numpunct<wchar_t>::~numpunct()
4258 {
4259 }
4260 
4261  char   numpunct< char  >::do_decimal_point() const {return __decimal_point_;}
4262 wchar_t numpunct<wchar_t>::do_decimal_point() const {return __decimal_point_;}
4263 
4264  char   numpunct< char  >::do_thousands_sep() const {return __thousands_sep_;}
4265 wchar_t numpunct<wchar_t>::do_thousands_sep() const {return __thousands_sep_;}
4266 
4267 string numpunct< char  >::do_grouping() const {return __grouping_;}
4268 string numpunct<wchar_t>::do_grouping() const {return __grouping_;}
4269 
4270  string numpunct< char  >::do_truename() const {return "true";}
4271 wstring numpunct<wchar_t>::do_truename() const {return L"true";}
4272 
4273  string numpunct< char  >::do_falsename() const {return "false";}
4274 wstring numpunct<wchar_t>::do_falsename() const {return L"false";}
4275 
4276 // numpunct_byname<char>
4277 
4278 numpunct_byname<char>::numpunct_byname(const char* nm, size_t refs)
4279     : numpunct<char>(refs)
4280 {
4281     __init(nm);
4282 }
4283 
4284 numpunct_byname<char>::numpunct_byname(const string& nm, size_t refs)
4285     : numpunct<char>(refs)
4286 {
4287     __init(nm.c_str());
4288 }
4289 
4290 numpunct_byname<char>::~numpunct_byname()
4291 {
4292 }
4293 
4294 void
4295 numpunct_byname<char>::__init(const char* nm)
4296 {
4297     if (strcmp(nm, "C") != 0)
4298     {
4299         __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
4300         if (loc == nullptr)
4301             __throw_runtime_error("numpunct_byname<char>::numpunct_byname"
4302                                 " failed to construct for " + string(nm));
4303 
4304         lconv* lc = __libcpp_localeconv_l(loc.get());
4305         checked_string_to_char_convert(__decimal_point_, lc->decimal_point,
4306                                        loc.get());
4307         checked_string_to_char_convert(__thousands_sep_, lc->thousands_sep,
4308                                        loc.get());
4309         __grouping_ = lc->grouping;
4310         // localization for truename and falsename is not available
4311     }
4312 }
4313 
4314 // numpunct_byname<wchar_t>
4315 
4316 numpunct_byname<wchar_t>::numpunct_byname(const char* nm, size_t refs)
4317     : numpunct<wchar_t>(refs)
4318 {
4319     __init(nm);
4320 }
4321 
4322 numpunct_byname<wchar_t>::numpunct_byname(const string& nm, size_t refs)
4323     : numpunct<wchar_t>(refs)
4324 {
4325     __init(nm.c_str());
4326 }
4327 
4328 numpunct_byname<wchar_t>::~numpunct_byname()
4329 {
4330 }
4331 
4332 void
4333 numpunct_byname<wchar_t>::__init(const char* nm)
4334 {
4335     if (strcmp(nm, "C") != 0)
4336     {
4337         __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
4338         if (loc == nullptr)
4339             __throw_runtime_error("numpunct_byname<wchar_t>::numpunct_byname"
4340                                 " failed to construct for " + string(nm));
4341 
4342         lconv* lc = __libcpp_localeconv_l(loc.get());
4343         checked_string_to_wchar_convert(__decimal_point_, lc->decimal_point,
4344                                         loc.get());
4345         checked_string_to_wchar_convert(__thousands_sep_, lc->thousands_sep,
4346                                         loc.get());
4347         __grouping_ = lc->grouping;
4348         // localization for truename and falsename is not available
4349     }
4350 }
4351 
4352 // num_get helpers
4353 
4354 int
4355 __num_get_base::__get_base(ios_base& iob)
4356 {
4357     ios_base::fmtflags __basefield = iob.flags() & ios_base::basefield;
4358     if (__basefield == ios_base::oct)
4359         return 8;
4360     else if (__basefield == ios_base::hex)
4361         return 16;
4362     else if (__basefield == 0)
4363         return 0;
4364     return 10;
4365 }
4366 
4367 const char __num_get_base::__src[33] = "0123456789abcdefABCDEFxX+-pPiInN";
4368 
4369 void
4370 __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end,
4371                  ios_base::iostate& __err)
4372 {
4373     if (__grouping.size() != 0)
4374     {
4375         reverse(__g, __g_end);
4376         const char* __ig = __grouping.data();
4377         const char* __eg = __ig + __grouping.size();
4378         for (unsigned* __r = __g; __r < __g_end-1; ++__r)
4379         {
4380             if (0 < *__ig && *__ig < numeric_limits<char>::max())
4381             {
4382                 if (static_cast<unsigned>(*__ig) != *__r)
4383                 {
4384                     __err = ios_base::failbit;
4385                     return;
4386                 }
4387             }
4388             if (__eg - __ig > 1)
4389                 ++__ig;
4390         }
4391         if (0 < *__ig && *__ig < numeric_limits<char>::max())
4392         {
4393             if (static_cast<unsigned>(*__ig) < __g_end[-1] || __g_end[-1] == 0)
4394                 __err = ios_base::failbit;
4395         }
4396     }
4397 }
4398 
4399 void
4400 __num_put_base::__format_int(char* __fmtp, const char* __len, bool __signd,
4401                              ios_base::fmtflags __flags)
4402 {
4403     if (__flags & ios_base::showpos)
4404         *__fmtp++ = '+';
4405     if (__flags & ios_base::showbase)
4406         *__fmtp++ = '#';
4407     while(*__len)
4408         *__fmtp++ = *__len++;
4409     if ((__flags & ios_base::basefield) == ios_base::oct)
4410         *__fmtp = 'o';
4411     else if ((__flags & ios_base::basefield) == ios_base::hex)
4412     {
4413         if (__flags & ios_base::uppercase)
4414             *__fmtp = 'X';
4415         else
4416             *__fmtp = 'x';
4417     }
4418     else if (__signd)
4419         *__fmtp = 'd';
4420     else
4421         *__fmtp = 'u';
4422 }
4423 
4424 bool
4425 __num_put_base::__format_float(char* __fmtp, const char* __len,
4426                                ios_base::fmtflags __flags)
4427 {
4428     bool specify_precision = true;
4429     if (__flags & ios_base::showpos)
4430         *__fmtp++ = '+';
4431     if (__flags & ios_base::showpoint)
4432         *__fmtp++ = '#';
4433     ios_base::fmtflags floatfield = __flags & ios_base::floatfield;
4434     bool uppercase = (__flags & ios_base::uppercase) != 0;
4435     if (floatfield == (ios_base::fixed | ios_base::scientific))
4436         specify_precision = false;
4437     else
4438     {
4439         *__fmtp++ = '.';
4440         *__fmtp++ = '*';
4441     }
4442     while(*__len)
4443         *__fmtp++ = *__len++;
4444     if (floatfield == ios_base::fixed)
4445     {
4446         if (uppercase)
4447             *__fmtp = 'F';
4448         else
4449             *__fmtp = 'f';
4450     }
4451     else if (floatfield == ios_base::scientific)
4452     {
4453         if (uppercase)
4454             *__fmtp = 'E';
4455         else
4456             *__fmtp = 'e';
4457     }
4458     else if (floatfield == (ios_base::fixed | ios_base::scientific))
4459     {
4460         if (uppercase)
4461             *__fmtp = 'A';
4462         else
4463             *__fmtp = 'a';
4464     }
4465     else
4466     {
4467         if (uppercase)
4468             *__fmtp = 'G';
4469         else
4470             *__fmtp = 'g';
4471     }
4472     return specify_precision;
4473 }
4474 
4475 char*
4476 __num_put_base::__identify_padding(char* __nb, char* __ne,
4477                                    const ios_base& __iob)
4478 {
4479     switch (__iob.flags() & ios_base::adjustfield)
4480     {
4481     case ios_base::internal:
4482         if (__nb[0] == '-' || __nb[0] == '+')
4483             return __nb+1;
4484         if (__ne - __nb >= 2 && __nb[0] == '0'
4485                             && (__nb[1] == 'x' || __nb[1] == 'X'))
4486             return __nb+2;
4487         break;
4488     case ios_base::left:
4489         return __ne;
4490     case ios_base::right:
4491     default:
4492         break;
4493     }
4494     return __nb;
4495 }
4496 
4497 // time_get
4498 
4499 static
4500 string*
4501 init_weeks()
4502 {
4503     static string weeks[14];
4504     weeks[0]  = "Sunday";
4505     weeks[1]  = "Monday";
4506     weeks[2]  = "Tuesday";
4507     weeks[3]  = "Wednesday";
4508     weeks[4]  = "Thursday";
4509     weeks[5]  = "Friday";
4510     weeks[6]  = "Saturday";
4511     weeks[7]  = "Sun";
4512     weeks[8]  = "Mon";
4513     weeks[9]  = "Tue";
4514     weeks[10] = "Wed";
4515     weeks[11] = "Thu";
4516     weeks[12] = "Fri";
4517     weeks[13] = "Sat";
4518     return weeks;
4519 }
4520 
4521 static
4522 wstring*
4523 init_wweeks()
4524 {
4525     static wstring weeks[14];
4526     weeks[0]  = L"Sunday";
4527     weeks[1]  = L"Monday";
4528     weeks[2]  = L"Tuesday";
4529     weeks[3]  = L"Wednesday";
4530     weeks[4]  = L"Thursday";
4531     weeks[5]  = L"Friday";
4532     weeks[6]  = L"Saturday";
4533     weeks[7]  = L"Sun";
4534     weeks[8]  = L"Mon";
4535     weeks[9]  = L"Tue";
4536     weeks[10] = L"Wed";
4537     weeks[11] = L"Thu";
4538     weeks[12] = L"Fri";
4539     weeks[13] = L"Sat";
4540     return weeks;
4541 }
4542 
4543 template <>
4544 const string*
4545 __time_get_c_storage<char>::__weeks() const
4546 {
4547     static const string* weeks = init_weeks();
4548     return weeks;
4549 }
4550 
4551 template <>
4552 const wstring*
4553 __time_get_c_storage<wchar_t>::__weeks() const
4554 {
4555     static const wstring* weeks = init_wweeks();
4556     return weeks;
4557 }
4558 
4559 static
4560 string*
4561 init_months()
4562 {
4563     static string months[24];
4564     months[0]  = "January";
4565     months[1]  = "February";
4566     months[2]  = "March";
4567     months[3]  = "April";
4568     months[4]  = "May";
4569     months[5]  = "June";
4570     months[6]  = "July";
4571     months[7]  = "August";
4572     months[8]  = "September";
4573     months[9]  = "October";
4574     months[10] = "November";
4575     months[11] = "December";
4576     months[12] = "Jan";
4577     months[13] = "Feb";
4578     months[14] = "Mar";
4579     months[15] = "Apr";
4580     months[16] = "May";
4581     months[17] = "Jun";
4582     months[18] = "Jul";
4583     months[19] = "Aug";
4584     months[20] = "Sep";
4585     months[21] = "Oct";
4586     months[22] = "Nov";
4587     months[23] = "Dec";
4588     return months;
4589 }
4590 
4591 static
4592 wstring*
4593 init_wmonths()
4594 {
4595     static wstring months[24];
4596     months[0]  = L"January";
4597     months[1]  = L"February";
4598     months[2]  = L"March";
4599     months[3]  = L"April";
4600     months[4]  = L"May";
4601     months[5]  = L"June";
4602     months[6]  = L"July";
4603     months[7]  = L"August";
4604     months[8]  = L"September";
4605     months[9]  = L"October";
4606     months[10] = L"November";
4607     months[11] = L"December";
4608     months[12] = L"Jan";
4609     months[13] = L"Feb";
4610     months[14] = L"Mar";
4611     months[15] = L"Apr";
4612     months[16] = L"May";
4613     months[17] = L"Jun";
4614     months[18] = L"Jul";
4615     months[19] = L"Aug";
4616     months[20] = L"Sep";
4617     months[21] = L"Oct";
4618     months[22] = L"Nov";
4619     months[23] = L"Dec";
4620     return months;
4621 }
4622 
4623 template <>
4624 const string*
4625 __time_get_c_storage<char>::__months() const
4626 {
4627     static const string* months = init_months();
4628     return months;
4629 }
4630 
4631 template <>
4632 const wstring*
4633 __time_get_c_storage<wchar_t>::__months() const
4634 {
4635     static const wstring* months = init_wmonths();
4636     return months;
4637 }
4638 
4639 static
4640 string*
4641 init_am_pm()
4642 {
4643     static string am_pm[24];
4644     am_pm[0]  = "AM";
4645     am_pm[1]  = "PM";
4646     return am_pm;
4647 }
4648 
4649 static
4650 wstring*
4651 init_wam_pm()
4652 {
4653     static wstring am_pm[24];
4654     am_pm[0]  = L"AM";
4655     am_pm[1]  = L"PM";
4656     return am_pm;
4657 }
4658 
4659 template <>
4660 const string*
4661 __time_get_c_storage<char>::__am_pm() const
4662 {
4663     static const string* am_pm = init_am_pm();
4664     return am_pm;
4665 }
4666 
4667 template <>
4668 const wstring*
4669 __time_get_c_storage<wchar_t>::__am_pm() const
4670 {
4671     static const wstring* am_pm = init_wam_pm();
4672     return am_pm;
4673 }
4674 
4675 template <>
4676 const string&
4677 __time_get_c_storage<char>::__x() const
4678 {
4679     static string s("%m/%d/%y");
4680     return s;
4681 }
4682 
4683 template <>
4684 const wstring&
4685 __time_get_c_storage<wchar_t>::__x() const
4686 {
4687     static wstring s(L"%m/%d/%y");
4688     return s;
4689 }
4690 
4691 template <>
4692 const string&
4693 __time_get_c_storage<char>::__X() const
4694 {
4695     static string s("%H:%M:%S");
4696     return s;
4697 }
4698 
4699 template <>
4700 const wstring&
4701 __time_get_c_storage<wchar_t>::__X() const
4702 {
4703     static wstring s(L"%H:%M:%S");
4704     return s;
4705 }
4706 
4707 template <>
4708 const string&
4709 __time_get_c_storage<char>::__c() const
4710 {
4711     static string s("%a %b %d %H:%M:%S %Y");
4712     return s;
4713 }
4714 
4715 template <>
4716 const wstring&
4717 __time_get_c_storage<wchar_t>::__c() const
4718 {
4719     static wstring s(L"%a %b %d %H:%M:%S %Y");
4720     return s;
4721 }
4722 
4723 template <>
4724 const string&
4725 __time_get_c_storage<char>::__r() const
4726 {
4727     static string s("%I:%M:%S %p");
4728     return s;
4729 }
4730 
4731 template <>
4732 const wstring&
4733 __time_get_c_storage<wchar_t>::__r() const
4734 {
4735     static wstring s(L"%I:%M:%S %p");
4736     return s;
4737 }
4738 
4739 // time_get_byname
4740 
4741 __time_get::__time_get(const char* nm)
4742     : __loc_(newlocale(LC_ALL_MASK, nm, 0))
4743 {
4744     if (__loc_ == 0)
4745         __throw_runtime_error("time_get_byname"
4746                             " failed to construct for " + string(nm));
4747 }
4748 
4749 __time_get::__time_get(const string& nm)
4750     : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
4751 {
4752     if (__loc_ == 0)
4753         __throw_runtime_error("time_get_byname"
4754                             " failed to construct for " + nm);
4755 }
4756 
4757 __time_get::~__time_get()
4758 {
4759     freelocale(__loc_);
4760 }
4761 #if defined(__clang__)
4762 #pragma clang diagnostic ignored "-Wmissing-field-initializers"
4763 #endif
4764 #if defined(__GNUG__)
4765 #pragma GCC   diagnostic ignored "-Wmissing-field-initializers"
4766 #endif
4767 
4768 template <>
4769 string
4770 __time_get_storage<char>::__analyze(char fmt, const ctype<char>& ct)
4771 {
4772     tm t = {0};
4773     t.tm_sec = 59;
4774     t.tm_min = 55;
4775     t.tm_hour = 23;
4776     t.tm_mday = 31;
4777     t.tm_mon = 11;
4778     t.tm_year = 161;
4779     t.tm_wday = 6;
4780     t.tm_yday = 364;
4781     t.tm_isdst = -1;
4782     char buf[100];
4783     char f[3] = {0};
4784     f[0] = '%';
4785     f[1] = fmt;
4786     size_t n = strftime_l(buf, countof(buf), f, &t, __loc_);
4787     char* bb = buf;
4788     char* be = buf + n;
4789     string result;
4790     while (bb != be)
4791     {
4792         if (ct.is(ctype_base::space, *bb))
4793         {
4794             result.push_back(' ');
4795             for (++bb; bb != be && ct.is(ctype_base::space, *bb); ++bb)
4796                 ;
4797             continue;
4798         }
4799         char* w = bb;
4800         ios_base::iostate err = ios_base::goodbit;
4801         ptrdiff_t i = __scan_keyword(w, be, this->__weeks_, this->__weeks_+14,
4802                                ct, err, false)
4803                                - this->__weeks_;
4804         if (i < 14)
4805         {
4806             result.push_back('%');
4807             if (i < 7)
4808                 result.push_back('A');
4809             else
4810                 result.push_back('a');
4811             bb = w;
4812             continue;
4813         }
4814         w = bb;
4815         i = __scan_keyword(w, be, this->__months_, this->__months_+24,
4816                            ct, err, false)
4817                            - this->__months_;
4818         if (i < 24)
4819         {
4820             result.push_back('%');
4821             if (i < 12)
4822                 result.push_back('B');
4823             else
4824                 result.push_back('b');
4825             if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4826                 result.back() = 'm';
4827             bb = w;
4828             continue;
4829         }
4830         if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4831         {
4832             w = bb;
4833             i = __scan_keyword(w, be, this->__am_pm_, this->__am_pm_+2,
4834                                ct, err, false) - this->__am_pm_;
4835             if (i < 2)
4836             {
4837                 result.push_back('%');
4838                 result.push_back('p');
4839                 bb = w;
4840                 continue;
4841             }
4842         }
4843         w = bb;
4844         if (ct.is(ctype_base::digit, *bb))
4845         {
4846             switch(__get_up_to_n_digits(bb, be, err, ct, 4))
4847             {
4848             case 6:
4849                 result.push_back('%');
4850                 result.push_back('w');
4851                 break;
4852             case 7:
4853                 result.push_back('%');
4854                 result.push_back('u');
4855                 break;
4856             case 11:
4857                 result.push_back('%');
4858                 result.push_back('I');
4859                 break;
4860             case 12:
4861                 result.push_back('%');
4862                 result.push_back('m');
4863                 break;
4864             case 23:
4865                 result.push_back('%');
4866                 result.push_back('H');
4867                 break;
4868             case 31:
4869                 result.push_back('%');
4870                 result.push_back('d');
4871                 break;
4872             case 55:
4873                 result.push_back('%');
4874                 result.push_back('M');
4875                 break;
4876             case 59:
4877                 result.push_back('%');
4878                 result.push_back('S');
4879                 break;
4880             case 61:
4881                 result.push_back('%');
4882                 result.push_back('y');
4883                 break;
4884             case 364:
4885                 result.push_back('%');
4886                 result.push_back('j');
4887                 break;
4888             case 2061:
4889                 result.push_back('%');
4890                 result.push_back('Y');
4891                 break;
4892             default:
4893                 for (; w != bb; ++w)
4894                     result.push_back(*w);
4895                 break;
4896             }
4897             continue;
4898         }
4899         if (*bb == '%')
4900         {
4901             result.push_back('%');
4902             result.push_back('%');
4903             ++bb;
4904             continue;
4905         }
4906         result.push_back(*bb);
4907         ++bb;
4908     }
4909     return result;
4910 }
4911 
4912 #if defined(__clang__)
4913 #pragma clang diagnostic ignored "-Wmissing-braces"
4914 #endif
4915 
4916 template <>
4917 wstring
4918 __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct)
4919 {
4920     tm t = {0};
4921     t.tm_sec = 59;
4922     t.tm_min = 55;
4923     t.tm_hour = 23;
4924     t.tm_mday = 31;
4925     t.tm_mon = 11;
4926     t.tm_year = 161;
4927     t.tm_wday = 6;
4928     t.tm_yday = 364;
4929     t.tm_isdst = -1;
4930     char buf[100];
4931     char f[3] = {0};
4932     f[0] = '%';
4933     f[1] = fmt;
4934     strftime_l(buf, countof(buf), f, &t, __loc_);
4935     wchar_t wbuf[100];
4936     wchar_t* wbb = wbuf;
4937     mbstate_t mb = {0};
4938     const char* bb = buf;
4939     size_t j = __libcpp_mbsrtowcs_l( wbb, &bb, countof(wbuf), &mb, __loc_);
4940     if (j == size_t(-1))
4941         __throw_runtime_error("locale not supported");
4942     wchar_t* wbe = wbb + j;
4943     wstring result;
4944     while (wbb != wbe)
4945     {
4946         if (ct.is(ctype_base::space, *wbb))
4947         {
4948             result.push_back(L' ');
4949             for (++wbb; wbb != wbe && ct.is(ctype_base::space, *wbb); ++wbb)
4950                 ;
4951             continue;
4952         }
4953         wchar_t* w = wbb;
4954         ios_base::iostate err = ios_base::goodbit;
4955         ptrdiff_t i = __scan_keyword(w, wbe, this->__weeks_, this->__weeks_+14,
4956                                ct, err, false)
4957                                - this->__weeks_;
4958         if (i < 14)
4959         {
4960             result.push_back(L'%');
4961             if (i < 7)
4962                 result.push_back(L'A');
4963             else
4964                 result.push_back(L'a');
4965             wbb = w;
4966             continue;
4967         }
4968         w = wbb;
4969         i = __scan_keyword(w, wbe, this->__months_, this->__months_+24,
4970                            ct, err, false)
4971                            - this->__months_;
4972         if (i < 24)
4973         {
4974             result.push_back(L'%');
4975             if (i < 12)
4976                 result.push_back(L'B');
4977             else
4978                 result.push_back(L'b');
4979             if (fmt == 'x' && ct.is(ctype_base::digit, this->__months_[i][0]))
4980                 result.back() = L'm';
4981             wbb = w;
4982             continue;
4983         }
4984         if (this->__am_pm_[0].size() + this->__am_pm_[1].size() > 0)
4985         {
4986             w = wbb;
4987             i = __scan_keyword(w, wbe, this->__am_pm_, this->__am_pm_+2,
4988                                ct, err, false) - this->__am_pm_;
4989             if (i < 2)
4990             {
4991                 result.push_back(L'%');
4992                 result.push_back(L'p');
4993                 wbb = w;
4994                 continue;
4995             }
4996         }
4997         w = wbb;
4998         if (ct.is(ctype_base::digit, *wbb))
4999         {
5000             switch(__get_up_to_n_digits(wbb, wbe, err, ct, 4))
5001             {
5002             case 6:
5003                 result.push_back(L'%');
5004                 result.push_back(L'w');
5005                 break;
5006             case 7:
5007                 result.push_back(L'%');
5008                 result.push_back(L'u');
5009                 break;
5010             case 11:
5011                 result.push_back(L'%');
5012                 result.push_back(L'I');
5013                 break;
5014             case 12:
5015                 result.push_back(L'%');
5016                 result.push_back(L'm');
5017                 break;
5018             case 23:
5019                 result.push_back(L'%');
5020                 result.push_back(L'H');
5021                 break;
5022             case 31:
5023                 result.push_back(L'%');
5024                 result.push_back(L'd');
5025                 break;
5026             case 55:
5027                 result.push_back(L'%');
5028                 result.push_back(L'M');
5029                 break;
5030             case 59:
5031                 result.push_back(L'%');
5032                 result.push_back(L'S');
5033                 break;
5034             case 61:
5035                 result.push_back(L'%');
5036                 result.push_back(L'y');
5037                 break;
5038             case 364:
5039                 result.push_back(L'%');
5040                 result.push_back(L'j');
5041                 break;
5042             case 2061:
5043                 result.push_back(L'%');
5044                 result.push_back(L'Y');
5045                 break;
5046             default:
5047                 for (; w != wbb; ++w)
5048                     result.push_back(*w);
5049                 break;
5050             }
5051             continue;
5052         }
5053         if (ct.narrow(*wbb, 0) == '%')
5054         {
5055             result.push_back(L'%');
5056             result.push_back(L'%');
5057             ++wbb;
5058             continue;
5059         }
5060         result.push_back(*wbb);
5061         ++wbb;
5062     }
5063     return result;
5064 }
5065 
5066 template <>
5067 void
5068 __time_get_storage<char>::init(const ctype<char>& ct)
5069 {
5070     tm t = {0};
5071     char buf[100];
5072     // __weeks_
5073     for (int i = 0; i < 7; ++i)
5074     {
5075         t.tm_wday = i;
5076         strftime_l(buf, countof(buf), "%A", &t, __loc_);
5077         __weeks_[i] = buf;
5078         strftime_l(buf, countof(buf), "%a", &t, __loc_);
5079         __weeks_[i+7] = buf;
5080     }
5081     // __months_
5082     for (int i = 0; i < 12; ++i)
5083     {
5084         t.tm_mon = i;
5085         strftime_l(buf, countof(buf), "%B", &t, __loc_);
5086         __months_[i] = buf;
5087         strftime_l(buf, countof(buf), "%b", &t, __loc_);
5088         __months_[i+12] = buf;
5089     }
5090     // __am_pm_
5091     t.tm_hour = 1;
5092     strftime_l(buf, countof(buf), "%p", &t, __loc_);
5093     __am_pm_[0] = buf;
5094     t.tm_hour = 13;
5095     strftime_l(buf, countof(buf), "%p", &t, __loc_);
5096     __am_pm_[1] = buf;
5097     __c_ = __analyze('c', ct);
5098     __r_ = __analyze('r', ct);
5099     __x_ = __analyze('x', ct);
5100     __X_ = __analyze('X', ct);
5101 }
5102 
5103 template <>
5104 void
5105 __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
5106 {
5107     tm t = {0};
5108     char buf[100];
5109     wchar_t wbuf[100];
5110     wchar_t* wbe;
5111     mbstate_t mb = {0};
5112     // __weeks_
5113     for (int i = 0; i < 7; ++i)
5114     {
5115         t.tm_wday = i;
5116         strftime_l(buf, countof(buf), "%A", &t, __loc_);
5117         mb = mbstate_t();
5118         const char* bb = buf;
5119         size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5120         if (j == size_t(-1))
5121             __throw_runtime_error("locale not supported");
5122         wbe = wbuf + j;
5123         __weeks_[i].assign(wbuf, wbe);
5124         strftime_l(buf, countof(buf), "%a", &t, __loc_);
5125         mb = mbstate_t();
5126         bb = buf;
5127         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5128         if (j == size_t(-1))
5129             __throw_runtime_error("locale not supported");
5130         wbe = wbuf + j;
5131         __weeks_[i+7].assign(wbuf, wbe);
5132     }
5133     // __months_
5134     for (int i = 0; i < 12; ++i)
5135     {
5136         t.tm_mon = i;
5137         strftime_l(buf, countof(buf), "%B", &t, __loc_);
5138         mb = mbstate_t();
5139         const char* bb = buf;
5140         size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5141         if (j == size_t(-1))
5142             __throw_runtime_error("locale not supported");
5143         wbe = wbuf + j;
5144         __months_[i].assign(wbuf, wbe);
5145         strftime_l(buf, countof(buf), "%b", &t, __loc_);
5146         mb = mbstate_t();
5147         bb = buf;
5148         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5149         if (j == size_t(-1))
5150             __throw_runtime_error("locale not supported");
5151         wbe = wbuf + j;
5152         __months_[i+12].assign(wbuf, wbe);
5153     }
5154     // __am_pm_
5155     t.tm_hour = 1;
5156     strftime_l(buf, countof(buf), "%p", &t, __loc_);
5157     mb = mbstate_t();
5158     const char* bb = buf;
5159     size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5160     if (j == size_t(-1))
5161         __throw_runtime_error("locale not supported");
5162     wbe = wbuf + j;
5163     __am_pm_[0].assign(wbuf, wbe);
5164     t.tm_hour = 13;
5165     strftime_l(buf, countof(buf), "%p", &t, __loc_);
5166     mb = mbstate_t();
5167     bb = buf;
5168     j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
5169     if (j == size_t(-1))
5170         __throw_runtime_error("locale not supported");
5171     wbe = wbuf + j;
5172     __am_pm_[1].assign(wbuf, wbe);
5173     __c_ = __analyze('c', ct);
5174     __r_ = __analyze('r', ct);
5175     __x_ = __analyze('x', ct);
5176     __X_ = __analyze('X', ct);
5177 }
5178 
5179 template <class CharT>
5180 struct _LIBCPP_HIDDEN __time_get_temp
5181     : public ctype_byname<CharT>
5182 {
5183     explicit __time_get_temp(const char* nm)
5184         : ctype_byname<CharT>(nm, 1) {}
5185     explicit __time_get_temp(const string& nm)
5186         : ctype_byname<CharT>(nm, 1) {}
5187 };
5188 
5189 template <>
5190 __time_get_storage<char>::__time_get_storage(const char* __nm)
5191     : __time_get(__nm)
5192 {
5193     const __time_get_temp<char> ct(__nm);
5194     init(ct);
5195 }
5196 
5197 template <>
5198 __time_get_storage<char>::__time_get_storage(const string& __nm)
5199     : __time_get(__nm)
5200 {
5201     const __time_get_temp<char> ct(__nm);
5202     init(ct);
5203 }
5204 
5205 template <>
5206 __time_get_storage<wchar_t>::__time_get_storage(const char* __nm)
5207     : __time_get(__nm)
5208 {
5209     const __time_get_temp<wchar_t> ct(__nm);
5210     init(ct);
5211 }
5212 
5213 template <>
5214 __time_get_storage<wchar_t>::__time_get_storage(const string& __nm)
5215     : __time_get(__nm)
5216 {
5217     const __time_get_temp<wchar_t> ct(__nm);
5218     init(ct);
5219 }
5220 
5221 template <>
5222 time_base::dateorder
5223 __time_get_storage<char>::__do_date_order() const
5224 {
5225     unsigned i;
5226     for (i = 0; i < __x_.size(); ++i)
5227         if (__x_[i] == '%')
5228             break;
5229     ++i;
5230     switch (__x_[i])
5231     {
5232     case 'y':
5233     case 'Y':
5234         for (++i; i < __x_.size(); ++i)
5235             if (__x_[i] == '%')
5236                 break;
5237         if (i == __x_.size())
5238             break;
5239         ++i;
5240         switch (__x_[i])
5241         {
5242         case 'm':
5243             for (++i; i < __x_.size(); ++i)
5244                 if (__x_[i] == '%')
5245                     break;
5246             if (i == __x_.size())
5247                 break;
5248             ++i;
5249             if (__x_[i] == 'd')
5250                 return time_base::ymd;
5251             break;
5252         case 'd':
5253             for (++i; i < __x_.size(); ++i)
5254                 if (__x_[i] == '%')
5255                     break;
5256             if (i == __x_.size())
5257                 break;
5258             ++i;
5259             if (__x_[i] == 'm')
5260                 return time_base::ydm;
5261             break;
5262         }
5263         break;
5264     case 'm':
5265         for (++i; i < __x_.size(); ++i)
5266             if (__x_[i] == '%')
5267                 break;
5268         if (i == __x_.size())
5269             break;
5270         ++i;
5271         if (__x_[i] == 'd')
5272         {
5273             for (++i; i < __x_.size(); ++i)
5274                 if (__x_[i] == '%')
5275                     break;
5276             if (i == __x_.size())
5277                 break;
5278             ++i;
5279             if (__x_[i] == 'y' || __x_[i] == 'Y')
5280                 return time_base::mdy;
5281             break;
5282         }
5283         break;
5284     case 'd':
5285         for (++i; i < __x_.size(); ++i)
5286             if (__x_[i] == '%')
5287                 break;
5288         if (i == __x_.size())
5289             break;
5290         ++i;
5291         if (__x_[i] == 'm')
5292         {
5293             for (++i; i < __x_.size(); ++i)
5294                 if (__x_[i] == '%')
5295                     break;
5296             if (i == __x_.size())
5297                 break;
5298             ++i;
5299             if (__x_[i] == 'y' || __x_[i] == 'Y')
5300                 return time_base::dmy;
5301             break;
5302         }
5303         break;
5304     }
5305     return time_base::no_order;
5306 }
5307 
5308 template <>
5309 time_base::dateorder
5310 __time_get_storage<wchar_t>::__do_date_order() const
5311 {
5312     unsigned i;
5313     for (i = 0; i < __x_.size(); ++i)
5314         if (__x_[i] == L'%')
5315             break;
5316     ++i;
5317     switch (__x_[i])
5318     {
5319     case L'y':
5320     case L'Y':
5321         for (++i; i < __x_.size(); ++i)
5322             if (__x_[i] == L'%')
5323                 break;
5324         if (i == __x_.size())
5325             break;
5326         ++i;
5327         switch (__x_[i])
5328         {
5329         case L'm':
5330             for (++i; i < __x_.size(); ++i)
5331                 if (__x_[i] == L'%')
5332                     break;
5333             if (i == __x_.size())
5334                 break;
5335             ++i;
5336             if (__x_[i] == L'd')
5337                 return time_base::ymd;
5338             break;
5339         case L'd':
5340             for (++i; i < __x_.size(); ++i)
5341                 if (__x_[i] == L'%')
5342                     break;
5343             if (i == __x_.size())
5344                 break;
5345             ++i;
5346             if (__x_[i] == L'm')
5347                 return time_base::ydm;
5348             break;
5349         }
5350         break;
5351     case L'm':
5352         for (++i; i < __x_.size(); ++i)
5353             if (__x_[i] == L'%')
5354                 break;
5355         if (i == __x_.size())
5356             break;
5357         ++i;
5358         if (__x_[i] == L'd')
5359         {
5360             for (++i; i < __x_.size(); ++i)
5361                 if (__x_[i] == L'%')
5362                     break;
5363             if (i == __x_.size())
5364                 break;
5365             ++i;
5366             if (__x_[i] == L'y' || __x_[i] == L'Y')
5367                 return time_base::mdy;
5368             break;
5369         }
5370         break;
5371     case L'd':
5372         for (++i; i < __x_.size(); ++i)
5373             if (__x_[i] == L'%')
5374                 break;
5375         if (i == __x_.size())
5376             break;
5377         ++i;
5378         if (__x_[i] == L'm')
5379         {
5380             for (++i; i < __x_.size(); ++i)
5381                 if (__x_[i] == L'%')
5382                     break;
5383             if (i == __x_.size())
5384                 break;
5385             ++i;
5386             if (__x_[i] == L'y' || __x_[i] == L'Y')
5387                 return time_base::dmy;
5388             break;
5389         }
5390         break;
5391     }
5392     return time_base::no_order;
5393 }
5394 
5395 // time_put
5396 
5397 __time_put::__time_put(const char* nm)
5398     : __loc_(newlocale(LC_ALL_MASK, nm, 0))
5399 {
5400     if (__loc_ == 0)
5401         __throw_runtime_error("time_put_byname"
5402                             " failed to construct for " + string(nm));
5403 }
5404 
5405 __time_put::__time_put(const string& nm)
5406     : __loc_(newlocale(LC_ALL_MASK, nm.c_str(), 0))
5407 {
5408     if (__loc_ == 0)
5409         __throw_runtime_error("time_put_byname"
5410                             " failed to construct for " + nm);
5411 }
5412 
5413 __time_put::~__time_put()
5414 {
5415     if (__loc_ != _LIBCPP_GET_C_LOCALE)
5416         freelocale(__loc_);
5417 }
5418 
5419 void
5420 __time_put::__do_put(char* __nb, char*& __ne, const tm* __tm,
5421                      char __fmt, char __mod) const
5422 {
5423     char fmt[] = {'%', __fmt, __mod, 0};
5424     if (__mod != 0)
5425         swap(fmt[1], fmt[2]);
5426     size_t n = strftime_l(__nb, countof(__nb, __ne), fmt, __tm, __loc_);
5427     __ne = __nb + n;
5428 }
5429 
5430 void
5431 __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm,
5432                      char __fmt, char __mod) const
5433 {
5434     char __nar[100];
5435     char* __ne = __nar + 100;
5436     __do_put(__nar, __ne, __tm, __fmt, __mod);
5437     mbstate_t mb = {0};
5438     const char* __nb = __nar;
5439     size_t j = __libcpp_mbsrtowcs_l(__wb, &__nb, countof(__wb, __we), &mb, __loc_);
5440     if (j == size_t(-1))
5441         __throw_runtime_error("locale not supported");
5442     __we = __wb + j;
5443 }
5444 
5445 // moneypunct_byname
5446 
5447 template <class charT>
5448 static
5449 void
5450 __init_pat(money_base::pattern& pat, basic_string<charT>& __curr_symbol_,
5451            bool intl, char cs_precedes, char sep_by_space, char sign_posn,
5452            charT space_char)
5453 {
5454     const char sign = static_cast<char>(money_base::sign);
5455     const char space = static_cast<char>(money_base::space);
5456     const char none = static_cast<char>(money_base::none);
5457     const char symbol = static_cast<char>(money_base::symbol);
5458     const char value = static_cast<char>(money_base::value);
5459     const bool symbol_contains_sep = intl && __curr_symbol_.size() == 4;
5460 
5461     // Comments on case branches reflect 'C11 7.11.2.1 The localeconv
5462     // function'. "Space between sign and symbol or value" means that
5463     // if the sign is adjacent to the symbol, there's a space between
5464     // them, and otherwise there's a space between the sign and value.
5465     //
5466     // C11's localeconv specifies that the fourth character of an
5467     // international curr_symbol is used to separate the sign and
5468     // value when sep_by_space says to do so. C++ can't represent
5469     // that, so we just use a space.  When sep_by_space says to
5470     // separate the symbol and value-or-sign with a space, we rearrange the
5471     // curr_symbol to put its spacing character on the correct side of
5472     // the symbol.
5473     //
5474     // We also need to avoid adding an extra space between the sign
5475     // and value when the currency symbol is suppressed (by not
5476     // setting showbase).  We match glibc's strfmon by interpreting
5477     // sep_by_space==1 as "omit the space when the currency symbol is
5478     // absent".
5479     //
5480     // Users who want to get this right should use ICU instead.
5481 
5482     switch (cs_precedes)
5483     {
5484     case 0:  // value before curr_symbol
5485         if (symbol_contains_sep) {
5486             // Move the separator to before the symbol, to place it
5487             // between the value and symbol.
5488             rotate(__curr_symbol_.begin(), __curr_symbol_.begin() + 3,
5489                    __curr_symbol_.end());
5490         }
5491         switch (sign_posn)
5492         {
5493         case 0:  // Parentheses surround the quantity and currency symbol.
5494             pat.field[0] = sign;
5495             pat.field[1] = value;
5496             pat.field[2] = none;  // Any space appears in the symbol.
5497             pat.field[3] = symbol;
5498             switch (sep_by_space)
5499             {
5500             case 0:  // No space separates the currency symbol and value.
5501                 // This case may have changed between C99 and C11;
5502                 // assume the currency symbol matches the intention.
5503             case 2:  // Space between sign and currency or value.
5504                 // The "sign" is two parentheses, so no space here either.
5505                 return;
5506             case 1:  // Space between currency-and-sign or currency and value.
5507                 if (!symbol_contains_sep) {
5508                     // We insert the space into the symbol instead of
5509                     // setting pat.field[2]=space so that when
5510                     // showbase is not set, the space goes away too.
5511                     __curr_symbol_.insert(0, 1, space_char);
5512                 }
5513                 return;
5514             default:
5515                 break;
5516             }
5517             break;
5518         case 1:  // The sign string precedes the quantity and currency symbol.
5519             pat.field[0] = sign;
5520             pat.field[3] = symbol;
5521             switch (sep_by_space)
5522             {
5523             case 0:  // No space separates the currency symbol and value.
5524                 pat.field[1] = value;
5525                 pat.field[2] = none;
5526                 return;
5527             case 1:  // Space between currency-and-sign or currency and value.
5528                 pat.field[1] = value;
5529                 pat.field[2] = none;
5530                 if (!symbol_contains_sep) {
5531                     // We insert the space into the symbol instead of
5532                     // setting pat.field[2]=space so that when
5533                     // showbase is not set, the space goes away too.
5534                     __curr_symbol_.insert(0, 1, space_char);
5535                 }
5536                 return;
5537             case 2:  // Space between sign and currency or value.
5538                 pat.field[1] = space;
5539                 pat.field[2] = value;
5540                 if (symbol_contains_sep) {
5541                     // Remove the separator from the symbol, since it
5542                     // has already appeared after the sign.
5543                     __curr_symbol_.erase(__curr_symbol_.begin());
5544                 }
5545                 return;
5546             default:
5547                 break;
5548             }
5549             break;
5550         case 2:  // The sign string succeeds the quantity and currency symbol.
5551             pat.field[0] = value;
5552             pat.field[3] = sign;
5553             switch (sep_by_space)
5554             {
5555             case 0:  // No space separates the currency symbol and value.
5556                 pat.field[1] = none;
5557                 pat.field[2] = symbol;
5558                 return;
5559             case 1:  // Space between currency-and-sign or currency and value.
5560                 if (!symbol_contains_sep) {
5561                     // We insert the space into the symbol instead of
5562                     // setting pat.field[1]=space so that when
5563                     // showbase is not set, the space goes away too.
5564                     __curr_symbol_.insert(0, 1, space_char);
5565                 }
5566                 pat.field[1] = none;
5567                 pat.field[2] = symbol;
5568                 return;
5569             case 2:  // Space between sign and currency or value.
5570                 pat.field[1] = symbol;
5571                 pat.field[2] = space;
5572                 if (symbol_contains_sep) {
5573                     // Remove the separator from the symbol, since it
5574                     // should not be removed if showbase is absent.
5575                     __curr_symbol_.erase(__curr_symbol_.begin());
5576                 }
5577                 return;
5578             default:
5579                 break;
5580             }
5581             break;
5582         case 3:  // The sign string immediately precedes the currency symbol.
5583             pat.field[0] = value;
5584             pat.field[3] = symbol;
5585             switch (sep_by_space)
5586             {
5587             case 0:  // No space separates the currency symbol and value.
5588                 pat.field[1] = none;
5589                 pat.field[2] = sign;
5590                 return;
5591             case 1:  // Space between currency-and-sign or currency and value.
5592                 pat.field[1] = space;
5593                 pat.field[2] = sign;
5594                 if (symbol_contains_sep) {
5595                     // Remove the separator from the symbol, since it
5596                     // has already appeared before the sign.
5597                     __curr_symbol_.erase(__curr_symbol_.begin());
5598                 }
5599                 return;
5600             case 2:  // Space between sign and currency or value.
5601                 pat.field[1] = sign;
5602                 pat.field[2] = none;
5603                 if (!symbol_contains_sep) {
5604                     // We insert the space into the symbol instead of
5605                     // setting pat.field[2]=space so that when
5606                     // showbase is not set, the space goes away too.
5607                     __curr_symbol_.insert(0, 1, space_char);
5608                 }
5609                 return;
5610             default:
5611                 break;
5612             }
5613             break;
5614         case 4:  // The sign string immediately succeeds the currency symbol.
5615             pat.field[0] = value;
5616             pat.field[3] = sign;
5617             switch (sep_by_space)
5618             {
5619             case 0:  // No space separates the currency symbol and value.
5620                 pat.field[1] = none;
5621                 pat.field[2] = symbol;
5622                 return;
5623             case 1:  // Space between currency-and-sign or currency and value.
5624                 pat.field[1] = none;
5625                 pat.field[2] = symbol;
5626                 if (!symbol_contains_sep) {
5627                     // We insert the space into the symbol instead of
5628                     // setting pat.field[1]=space so that when
5629                     // showbase is not set, the space goes away too.
5630                     __curr_symbol_.insert(0, 1, space_char);
5631                 }
5632                 return;
5633             case 2:  // Space between sign and currency or value.
5634                 pat.field[1] = symbol;
5635                 pat.field[2] = space;
5636                 if (symbol_contains_sep) {
5637                     // Remove the separator from the symbol, since it
5638                     // should not disappear when showbase is absent.
5639                     __curr_symbol_.erase(__curr_symbol_.begin());
5640                 }
5641                 return;
5642             default:
5643                 break;
5644             }
5645             break;
5646         default:
5647             break;
5648         }
5649         break;
5650     case 1:  // curr_symbol before value
5651         switch (sign_posn)
5652         {
5653         case 0:  // Parentheses surround the quantity and currency symbol.
5654             pat.field[0] = sign;
5655             pat.field[1] = symbol;
5656             pat.field[2] = none;  // Any space appears in the symbol.
5657             pat.field[3] = value;
5658             switch (sep_by_space)
5659             {
5660             case 0:  // No space separates the currency symbol and value.
5661                 // This case may have changed between C99 and C11;
5662                 // assume the currency symbol matches the intention.
5663             case 2:  // Space between sign and currency or value.
5664                 // The "sign" is two parentheses, so no space here either.
5665                 return;
5666             case 1:  // Space between currency-and-sign or currency and value.
5667                 if (!symbol_contains_sep) {
5668                     // We insert the space into the symbol instead of
5669                     // setting pat.field[2]=space so that when
5670                     // showbase is not set, the space goes away too.
5671                     __curr_symbol_.insert(0, 1, space_char);
5672                 }
5673                 return;
5674             default:
5675                 break;
5676             }
5677             break;
5678         case 1:  // The sign string precedes the quantity and currency symbol.
5679             pat.field[0] = sign;
5680             pat.field[3] = value;
5681             switch (sep_by_space)
5682             {
5683             case 0:  // No space separates the currency symbol and value.
5684                 pat.field[1] = symbol;
5685                 pat.field[2] = none;
5686                 return;
5687             case 1:  // Space between currency-and-sign or currency and value.
5688                 pat.field[1] = symbol;
5689                 pat.field[2] = none;
5690                 if (!symbol_contains_sep) {
5691                     // We insert the space into the symbol instead of
5692                     // setting pat.field[2]=space so that when
5693                     // showbase is not set, the space goes away too.
5694                     __curr_symbol_.push_back(space_char);
5695                 }
5696                 return;
5697             case 2:  // Space between sign and currency or value.
5698                 pat.field[1] = space;
5699                 pat.field[2] = symbol;
5700                 if (symbol_contains_sep) {
5701                     // Remove the separator from the symbol, since it
5702                     // has already appeared after the sign.
5703                     __curr_symbol_.pop_back();
5704                 }
5705                 return;
5706             default:
5707                 break;
5708             }
5709             break;
5710         case 2:  // The sign string succeeds the quantity and currency symbol.
5711             pat.field[0] = symbol;
5712             pat.field[3] = sign;
5713             switch (sep_by_space)
5714             {
5715             case 0:  // No space separates the currency symbol and value.
5716                 pat.field[1] = none;
5717                 pat.field[2] = value;
5718                 return;
5719             case 1:  // Space between currency-and-sign or currency and value.
5720                 pat.field[1] = none;
5721                 pat.field[2] = value;
5722                 if (!symbol_contains_sep) {
5723                     // We insert the space into the symbol instead of
5724                     // setting pat.field[1]=space so that when
5725                     // showbase is not set, the space goes away too.
5726                     __curr_symbol_.push_back(space_char);
5727                 }
5728                 return;
5729             case 2:  // Space between sign and currency or value.
5730                 pat.field[1] = value;
5731                 pat.field[2] = space;
5732                 if (symbol_contains_sep) {
5733                     // Remove the separator from the symbol, since it
5734                     // will appear before the sign.
5735                     __curr_symbol_.pop_back();
5736                 }
5737                 return;
5738             default:
5739                 break;
5740             }
5741             break;
5742         case 3:  // The sign string immediately precedes the currency symbol.
5743             pat.field[0] = sign;
5744             pat.field[3] = value;
5745             switch (sep_by_space)
5746             {
5747             case 0:  // No space separates the currency symbol and value.
5748                 pat.field[1] = symbol;
5749                 pat.field[2] = none;
5750                 return;
5751             case 1:  // Space between currency-and-sign or currency and value.
5752                 pat.field[1] = symbol;
5753                 pat.field[2] = none;
5754                 if (!symbol_contains_sep) {
5755                     // We insert the space into the symbol instead of
5756                     // setting pat.field[2]=space so that when
5757                     // showbase is not set, the space goes away too.
5758                     __curr_symbol_.push_back(space_char);
5759                 }
5760                 return;
5761             case 2:  // Space between sign and currency or value.
5762                 pat.field[1] = space;
5763                 pat.field[2] = symbol;
5764                 if (symbol_contains_sep) {
5765                     // Remove the separator from the symbol, since it
5766                     // has already appeared after the sign.
5767                     __curr_symbol_.pop_back();
5768                 }
5769                 return;
5770             default:
5771                 break;
5772             }
5773             break;
5774         case 4:  // The sign string immediately succeeds the currency symbol.
5775             pat.field[0] = symbol;
5776             pat.field[3] = value;
5777             switch (sep_by_space)
5778             {
5779             case 0:  // No space separates the currency symbol and value.
5780                 pat.field[1] = sign;
5781                 pat.field[2] = none;
5782                 return;
5783             case 1:  // Space between currency-and-sign or currency and value.
5784                 pat.field[1] = sign;
5785                 pat.field[2] = space;
5786                 if (symbol_contains_sep) {
5787                     // Remove the separator from the symbol, since it
5788                     // should not disappear when showbase is absent.
5789                     __curr_symbol_.pop_back();
5790                 }
5791                 return;
5792             case 2:  // Space between sign and currency or value.
5793                 pat.field[1] = none;
5794                 pat.field[2] = sign;
5795                 if (!symbol_contains_sep) {
5796                     // We insert the space into the symbol instead of
5797                     // setting pat.field[1]=space so that when
5798                     // showbase is not set, the space goes away too.
5799                     __curr_symbol_.push_back(space_char);
5800                 }
5801                 return;
5802            default:
5803                 break;
5804             }
5805             break;
5806         default:
5807             break;
5808         }
5809         break;
5810     default:
5811         break;
5812     }
5813     pat.field[0] = symbol;
5814     pat.field[1] = sign;
5815     pat.field[2] = none;
5816     pat.field[3] = value;
5817 }
5818 
5819 template<>
5820 void
5821 moneypunct_byname<char, false>::init(const char* nm)
5822 {
5823     typedef moneypunct<char, false> base;
5824     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5825     if (loc == nullptr)
5826         __throw_runtime_error("moneypunct_byname"
5827                             " failed to construct for " + string(nm));
5828 
5829     lconv* lc = __libcpp_localeconv_l(loc.get());
5830     if (!checked_string_to_char_convert(__decimal_point_,
5831                                         lc->mon_decimal_point,
5832                                         loc.get()))
5833       __decimal_point_ = base::do_decimal_point();
5834     if (!checked_string_to_char_convert(__thousands_sep_,
5835                                         lc->mon_thousands_sep,
5836                                         loc.get()))
5837       __thousands_sep_ = base::do_thousands_sep();
5838 
5839     __grouping_ = lc->mon_grouping;
5840     __curr_symbol_ = lc->currency_symbol;
5841     if (lc->frac_digits != CHAR_MAX)
5842         __frac_digits_ = lc->frac_digits;
5843     else
5844         __frac_digits_ = base::do_frac_digits();
5845     if (lc->p_sign_posn == 0)
5846         __positive_sign_ = "()";
5847     else
5848         __positive_sign_ = lc->positive_sign;
5849     if (lc->n_sign_posn == 0)
5850         __negative_sign_ = "()";
5851     else
5852         __negative_sign_ = lc->negative_sign;
5853     // Assume the positive and negative formats will want spaces in
5854     // the same places in curr_symbol since there's no way to
5855     // represent anything else.
5856     string_type __dummy_curr_symbol = __curr_symbol_;
5857     __init_pat(__pos_format_, __dummy_curr_symbol, false,
5858                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5859     __init_pat(__neg_format_, __curr_symbol_, false,
5860                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5861 }
5862 
5863 template<>
5864 void
5865 moneypunct_byname<char, true>::init(const char* nm)
5866 {
5867     typedef moneypunct<char, true> base;
5868     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5869     if (loc == nullptr)
5870         __throw_runtime_error("moneypunct_byname"
5871                             " failed to construct for " + string(nm));
5872 
5873     lconv* lc = __libcpp_localeconv_l(loc.get());
5874     if (!checked_string_to_char_convert(__decimal_point_,
5875                                         lc->mon_decimal_point,
5876                                         loc.get()))
5877       __decimal_point_ = base::do_decimal_point();
5878     if (!checked_string_to_char_convert(__thousands_sep_,
5879                                         lc->mon_thousands_sep,
5880                                         loc.get()))
5881       __thousands_sep_ = base::do_thousands_sep();
5882     __grouping_ = lc->mon_grouping;
5883     __curr_symbol_ = lc->int_curr_symbol;
5884     if (lc->int_frac_digits != CHAR_MAX)
5885         __frac_digits_ = lc->int_frac_digits;
5886     else
5887         __frac_digits_ = base::do_frac_digits();
5888 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5889     if (lc->p_sign_posn == 0)
5890 #else // _LIBCPP_MSVCRT
5891     if (lc->int_p_sign_posn == 0)
5892 #endif // !_LIBCPP_MSVCRT
5893         __positive_sign_ = "()";
5894     else
5895         __positive_sign_ = lc->positive_sign;
5896 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5897     if(lc->n_sign_posn == 0)
5898 #else // _LIBCPP_MSVCRT
5899     if (lc->int_n_sign_posn == 0)
5900 #endif // !_LIBCPP_MSVCRT
5901         __negative_sign_ = "()";
5902     else
5903         __negative_sign_ = lc->negative_sign;
5904     // Assume the positive and negative formats will want spaces in
5905     // the same places in curr_symbol since there's no way to
5906     // represent anything else.
5907     string_type __dummy_curr_symbol = __curr_symbol_;
5908 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
5909     __init_pat(__pos_format_, __dummy_curr_symbol, true,
5910                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, ' ');
5911     __init_pat(__neg_format_, __curr_symbol_, true,
5912                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, ' ');
5913 #else // _LIBCPP_MSVCRT
5914     __init_pat(__pos_format_, __dummy_curr_symbol, true,
5915                lc->int_p_cs_precedes, lc->int_p_sep_by_space,
5916                lc->int_p_sign_posn, ' ');
5917     __init_pat(__neg_format_, __curr_symbol_, true,
5918                lc->int_n_cs_precedes, lc->int_n_sep_by_space,
5919                lc->int_n_sign_posn, ' ');
5920 #endif // !_LIBCPP_MSVCRT
5921 }
5922 
5923 template<>
5924 void
5925 moneypunct_byname<wchar_t, false>::init(const char* nm)
5926 {
5927     typedef moneypunct<wchar_t, false> base;
5928     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5929     if (loc == nullptr)
5930         __throw_runtime_error("moneypunct_byname"
5931                             " failed to construct for " + string(nm));
5932     lconv* lc = __libcpp_localeconv_l(loc.get());
5933     if (!checked_string_to_wchar_convert(__decimal_point_,
5934                                          lc->mon_decimal_point,
5935                                          loc.get()))
5936       __decimal_point_ = base::do_decimal_point();
5937     if (!checked_string_to_wchar_convert(__thousands_sep_,
5938                                          lc->mon_thousands_sep,
5939                                          loc.get()))
5940       __thousands_sep_ = base::do_thousands_sep();
5941     __grouping_ = lc->mon_grouping;
5942     wchar_t wbuf[100];
5943     mbstate_t mb = {0};
5944     const char* bb = lc->currency_symbol;
5945     size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5946     if (j == size_t(-1))
5947         __throw_runtime_error("locale not supported");
5948     wchar_t* wbe = wbuf + j;
5949     __curr_symbol_.assign(wbuf, wbe);
5950     if (lc->frac_digits != CHAR_MAX)
5951         __frac_digits_ = lc->frac_digits;
5952     else
5953         __frac_digits_ = base::do_frac_digits();
5954     if (lc->p_sign_posn == 0)
5955         __positive_sign_ = L"()";
5956     else
5957     {
5958         mb = mbstate_t();
5959         bb = lc->positive_sign;
5960         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5961         if (j == size_t(-1))
5962             __throw_runtime_error("locale not supported");
5963         wbe = wbuf + j;
5964         __positive_sign_.assign(wbuf, wbe);
5965     }
5966     if (lc->n_sign_posn == 0)
5967         __negative_sign_ = L"()";
5968     else
5969     {
5970         mb = mbstate_t();
5971         bb = lc->negative_sign;
5972         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
5973         if (j == size_t(-1))
5974             __throw_runtime_error("locale not supported");
5975         wbe = wbuf + j;
5976         __negative_sign_.assign(wbuf, wbe);
5977     }
5978     // Assume the positive and negative formats will want spaces in
5979     // the same places in curr_symbol since there's no way to
5980     // represent anything else.
5981     string_type __dummy_curr_symbol = __curr_symbol_;
5982     __init_pat(__pos_format_, __dummy_curr_symbol, false,
5983                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
5984     __init_pat(__neg_format_, __curr_symbol_, false,
5985                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
5986 }
5987 
5988 template<>
5989 void
5990 moneypunct_byname<wchar_t, true>::init(const char* nm)
5991 {
5992     typedef moneypunct<wchar_t, true> base;
5993     __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale);
5994     if (loc == nullptr)
5995         __throw_runtime_error("moneypunct_byname"
5996                             " failed to construct for " + string(nm));
5997 
5998     lconv* lc = __libcpp_localeconv_l(loc.get());
5999     if (!checked_string_to_wchar_convert(__decimal_point_,
6000                                          lc->mon_decimal_point,
6001                                          loc.get()))
6002       __decimal_point_ = base::do_decimal_point();
6003     if (!checked_string_to_wchar_convert(__thousands_sep_,
6004                                          lc->mon_thousands_sep,
6005                                          loc.get()))
6006       __thousands_sep_ = base::do_thousands_sep();
6007     __grouping_ = lc->mon_grouping;
6008     wchar_t wbuf[100];
6009     mbstate_t mb = {0};
6010     const char* bb = lc->int_curr_symbol;
6011     size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6012     if (j == size_t(-1))
6013         __throw_runtime_error("locale not supported");
6014     wchar_t* wbe = wbuf + j;
6015     __curr_symbol_.assign(wbuf, wbe);
6016     if (lc->int_frac_digits != CHAR_MAX)
6017         __frac_digits_ = lc->int_frac_digits;
6018     else
6019         __frac_digits_ = base::do_frac_digits();
6020 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6021     if (lc->p_sign_posn == 0)
6022 #else // _LIBCPP_MSVCRT
6023     if (lc->int_p_sign_posn == 0)
6024 #endif // !_LIBCPP_MSVCRT
6025         __positive_sign_ = L"()";
6026     else
6027     {
6028         mb = mbstate_t();
6029         bb = lc->positive_sign;
6030         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6031         if (j == size_t(-1))
6032             __throw_runtime_error("locale not supported");
6033         wbe = wbuf + j;
6034         __positive_sign_.assign(wbuf, wbe);
6035     }
6036 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6037     if (lc->n_sign_posn == 0)
6038 #else // _LIBCPP_MSVCRT
6039     if (lc->int_n_sign_posn == 0)
6040 #endif // !_LIBCPP_MSVCRT
6041         __negative_sign_ = L"()";
6042     else
6043     {
6044         mb = mbstate_t();
6045         bb = lc->negative_sign;
6046         j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, loc.get());
6047         if (j == size_t(-1))
6048             __throw_runtime_error("locale not supported");
6049         wbe = wbuf + j;
6050         __negative_sign_.assign(wbuf, wbe);
6051     }
6052     // Assume the positive and negative formats will want spaces in
6053     // the same places in curr_symbol since there's no way to
6054     // represent anything else.
6055     string_type __dummy_curr_symbol = __curr_symbol_;
6056 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
6057     __init_pat(__pos_format_, __dummy_curr_symbol, true,
6058                lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn, L' ');
6059     __init_pat(__neg_format_, __curr_symbol_, true,
6060                lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn, L' ');
6061 #else // _LIBCPP_MSVCRT
6062     __init_pat(__pos_format_, __dummy_curr_symbol, true,
6063                lc->int_p_cs_precedes, lc->int_p_sep_by_space,
6064                lc->int_p_sign_posn, L' ');
6065     __init_pat(__neg_format_, __curr_symbol_, true,
6066                lc->int_n_cs_precedes, lc->int_n_sep_by_space,
6067                lc->int_n_sign_posn, L' ');
6068 #endif // !_LIBCPP_MSVCRT
6069 }
6070 
6071 void __do_nothing(void*) {}
6072 
6073 void __throw_runtime_error(const char* msg)
6074 {
6075 #ifndef _LIBCPP_NO_EXCEPTIONS
6076     throw runtime_error(msg);
6077 #else
6078     (void)msg;
6079     _VSTD::abort();
6080 #endif
6081 }
6082 
6083 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<char>;
6084 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS collate<wchar_t>;
6085 
6086 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<char>;
6087 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_get<wchar_t>;
6088 
6089 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<char>;
6090 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_get<wchar_t>;
6091 
6092 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<char>;
6093 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS num_put<wchar_t>;
6094 
6095 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<char>;
6096 template struct _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __num_put<wchar_t>;
6097 
6098 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<char>;
6099 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get<wchar_t>;
6100 
6101 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<char>;
6102 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_get_byname<wchar_t>;
6103 
6104 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<char>;
6105 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put<wchar_t>;
6106 
6107 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<char>;
6108 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS time_put_byname<wchar_t>;
6109 
6110 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, false>;
6111 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<char, true>;
6112 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, false>;
6113 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct<wchar_t, true>;
6114 
6115 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, false>;
6116 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<char, true>;
6117 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, false>;
6118 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS moneypunct_byname<wchar_t, true>;
6119 
6120 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<char>;
6121 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_get<wchar_t>;
6122 
6123 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<char>;
6124 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_get<wchar_t>;
6125 
6126 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<char>;
6127 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS money_put<wchar_t>;
6128 
6129 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<char>;
6130 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __money_put<wchar_t>;
6131 
6132 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<char>;
6133 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages<wchar_t>;
6134 
6135 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<char>;
6136 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t>;
6137 
6138 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>;
6139 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;
6140 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
6141 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
6142 
6143 template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __vector_base_common<true>;
6144 
6145 _LIBCPP_END_NAMESPACE_STD
6146