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