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