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