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