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