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