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