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