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