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