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