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