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