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