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