libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

locale.cpp (194554B)


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