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