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