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