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