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