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