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