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