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