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