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