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