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