Home | History | Annotate | Download | only in include
      1 // -*- C++ -*-
      2 //===----------------------------------------------------------------------===//
      3 //
      4 //                     The LLVM Compiler Infrastructure
      5 //
      6 // This file is dual licensed under the MIT and the University of Illinois Open
      7 // Source Licenses. See LICENSE.TXT for details.
      8 //
      9 //===----------------------------------------------------------------------===//
     10 
     11 #ifndef _LIBCPP___LOCALE
     12 #define _LIBCPP___LOCALE
     13 
     14 #include <__config>
     15 #include <string>
     16 #include <memory>
     17 #include <utility>
     18 #include <mutex>
     19 #include <cstdint>
     20 #include <cctype>
     21 #include <locale.h>
     22 #if defined(_LIBCPP_MSVCRT_LIKE)
     23 # include <support/win32/locale_win32.h>
     24 #elif defined(_AIX)
     25 # include <support/ibm/xlocale.h>
     26 #elif defined(__ANDROID__)
     27 # include <support/android/locale_bionic.h>
     28 #elif defined(__sun__)
     29 # include <xlocale.h>
     30 # include <support/solaris/xlocale.h>
     31 #elif defined(_NEWLIB_VERSION)
     32 # include <support/newlib/xlocale.h>
     33 #elif (defined(__APPLE__)      || defined(__FreeBSD__) \
     34     || defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
     35 # include <xlocale.h>
     36 #elif defined(__Fuchsia__)
     37 # include <support/fuchsia/xlocale.h>
     38 #elif defined(_LIBCPP_HAS_MUSL_LIBC)
     39 # include <support/musl/xlocale.h>
     40 #endif
     41 
     42 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
     43 #pragma GCC system_header
     44 #endif
     45 
     46 _LIBCPP_BEGIN_NAMESPACE_STD
     47 
     48 #if !defined(_LIBCPP_LOCALE__L_EXTENSIONS)
     49 struct __libcpp_locale_guard {
     50   _LIBCPP_INLINE_VISIBILITY
     51   __libcpp_locale_guard(locale_t& __loc) : __old_loc_(uselocale(__loc)) {}
     52 
     53   _LIBCPP_INLINE_VISIBILITY
     54   ~__libcpp_locale_guard() {
     55     if (__old_loc_)
     56       uselocale(__old_loc_);
     57   }
     58 
     59   locale_t __old_loc_;
     60 private:
     61   __libcpp_locale_guard(__libcpp_locale_guard const&);
     62   __libcpp_locale_guard& operator=(__libcpp_locale_guard const&);
     63 };
     64 #elif defined(_LIBCPP_MSVCRT_LIKE)
     65 struct __libcpp_locale_guard {
     66     __libcpp_locale_guard(locale_t __l) :
     67         __status(_configthreadlocale(_ENABLE_PER_THREAD_LOCALE)),
     68         __locale_collate(setlocale(LC_COLLATE, __l.__get_locale())),
     69         __locale_ctype(setlocale(LC_CTYPE, __l.__get_locale())),
     70         __locale_monetary(setlocale(LC_MONETARY, __l.__get_locale())),
     71         __locale_numeric(setlocale(LC_NUMERIC, __l.__get_locale())),
     72         __locale_time(setlocale(LC_TIME, __l.__get_locale()))
     73         // LC_MESSAGES is not supported on Windows.
     74     {}
     75     ~__libcpp_locale_guard() {
     76         setlocale(LC_COLLATE, __locale_collate);
     77         setlocale(LC_CTYPE, __locale_ctype);
     78         setlocale(LC_MONETARY, __locale_monetary);
     79         setlocale(LC_NUMERIC, __locale_numeric);
     80         setlocale(LC_TIME, __locale_time);
     81         _configthreadlocale(__status);
     82     }
     83     int __status;
     84     char* __locale_collate;
     85     char* __locale_ctype;
     86     char* __locale_monetary;
     87     char* __locale_numeric;
     88     char* __locale_time;
     89 };
     90 #endif
     91 
     92 
     93 class _LIBCPP_TYPE_VIS locale;
     94 
     95 template <class _Facet>
     96 _LIBCPP_INLINE_VISIBILITY
     97 bool
     98 has_facet(const locale&) _NOEXCEPT;
     99 
    100 template <class _Facet>
    101 _LIBCPP_INLINE_VISIBILITY
    102 const _Facet&
    103 use_facet(const locale&);
    104 
    105 class _LIBCPP_TYPE_VIS locale
    106 {
    107 public:
    108     // types:
    109     class _LIBCPP_TYPE_VIS facet;
    110     class _LIBCPP_TYPE_VIS id;
    111 
    112     typedef int category;
    113     _LIBCPP_AVAILABILITY_LOCALE_CATEGORY
    114     static const category // values assigned here are for exposition only
    115         none     = 0,
    116         collate  = LC_COLLATE_MASK,
    117         ctype    = LC_CTYPE_MASK,
    118         monetary = LC_MONETARY_MASK,
    119         numeric  = LC_NUMERIC_MASK,
    120         time     = LC_TIME_MASK,
    121         messages = LC_MESSAGES_MASK,
    122         all = collate | ctype | monetary | numeric | time | messages;
    123 
    124     // construct/copy/destroy:
    125     locale()  _NOEXCEPT;
    126     locale(const locale&)  _NOEXCEPT;
    127     explicit locale(const char*);
    128     explicit locale(const string&);
    129     locale(const locale&, const char*, category);
    130     locale(const locale&, const string&, category);
    131     template <class _Facet>
    132         _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
    133     locale(const locale&, const locale&, category);
    134 
    135     ~locale();
    136 
    137     const locale& operator=(const locale&)  _NOEXCEPT;
    138 
    139     template <class _Facet>
    140       _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
    141       locale combine(const locale&) const;
    142 
    143     // locale operations:
    144     string name() const;
    145     bool operator==(const locale&) const;
    146     bool operator!=(const locale& __y) const {return !(*this == __y);}
    147     template <class _CharT, class _Traits, class _Allocator>
    148       _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS
    149       bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
    150                       const basic_string<_CharT, _Traits, _Allocator>&) const;
    151 
    152     // global locale objects:
    153     static locale global(const locale&);
    154     static const locale& classic();
    155 
    156 private:
    157     class __imp;
    158     __imp* __locale_;
    159 
    160     void __install_ctor(const locale&, facet*, long);
    161     static locale& __global();
    162     bool has_facet(id&) const;
    163     const facet* use_facet(id&) const;
    164 
    165     template <class _Facet> friend bool has_facet(const locale&)  _NOEXCEPT;
    166     template <class _Facet> friend const _Facet& use_facet(const locale&);
    167 };
    168 
    169 class _LIBCPP_TYPE_VIS locale::facet
    170     : public __shared_count
    171 {
    172 protected:
    173     _LIBCPP_INLINE_VISIBILITY
    174     explicit facet(size_t __refs = 0)
    175         : __shared_count(static_cast<long>(__refs)-1) {}
    176 
    177     virtual ~facet();
    178 
    179 //    facet(const facet&) = delete;     // effectively done in __shared_count
    180 //    void operator=(const facet&) = delete;
    181 private:
    182     virtual void __on_zero_shared() _NOEXCEPT;
    183 };
    184 
    185 class _LIBCPP_TYPE_VIS locale::id
    186 {
    187     once_flag      __flag_;
    188     int32_t        __id_;
    189 
    190     static int32_t __next_id;
    191 public:
    192     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {}
    193 private:
    194     void __init();
    195     void operator=(const id&); // = delete;
    196     id(const id&); // = delete;
    197 public:  // only needed for tests
    198     long __get();
    199 
    200     friend class locale;
    201     friend class locale::__imp;
    202 };
    203 
    204 template <class _Facet>
    205 inline _LIBCPP_INLINE_VISIBILITY
    206 locale::locale(const locale& __other, _Facet* __f)
    207 {
    208     __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
    209 }
    210 
    211 template <class _Facet>
    212 locale
    213 locale::combine(const locale& __other) const
    214 {
    215     if (!_VSTD::has_facet<_Facet>(__other))
    216         __throw_runtime_error("locale::combine: locale missing facet");
    217 
    218     return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
    219 }
    220 
    221 template <class _Facet>
    222 inline _LIBCPP_INLINE_VISIBILITY
    223 bool
    224 has_facet(const locale& __l)  _NOEXCEPT
    225 {
    226     return __l.has_facet(_Facet::id);
    227 }
    228 
    229 template <class _Facet>
    230 inline _LIBCPP_INLINE_VISIBILITY
    231 const _Facet&
    232 use_facet(const locale& __l)
    233 {
    234     return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
    235 }
    236 
    237 // template <class _CharT> class collate;
    238 
    239 template <class _CharT>
    240 class _LIBCPP_TEMPLATE_VIS collate
    241     : public locale::facet
    242 {
    243 public:
    244     typedef _CharT char_type;
    245     typedef basic_string<char_type> string_type;
    246 
    247     _LIBCPP_INLINE_VISIBILITY
    248     explicit collate(size_t __refs = 0)
    249         : locale::facet(__refs) {}
    250 
    251     _LIBCPP_INLINE_VISIBILITY
    252     int compare(const char_type* __lo1, const char_type* __hi1,
    253                 const char_type* __lo2, const char_type* __hi2) const
    254     {
    255         return do_compare(__lo1, __hi1, __lo2, __hi2);
    256     }
    257 
    258     _LIBCPP_INLINE_VISIBILITY
    259     string_type transform(const char_type* __lo, const char_type* __hi) const
    260     {
    261         return do_transform(__lo, __hi);
    262     }
    263 
    264     _LIBCPP_INLINE_VISIBILITY
    265     long hash(const char_type* __lo, const char_type* __hi) const
    266     {
    267         return do_hash(__lo, __hi);
    268     }
    269 
    270     static locale::id id;
    271 
    272 protected:
    273     ~collate();
    274     virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
    275                            const char_type* __lo2, const char_type* __hi2) const;
    276     virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
    277         {return string_type(__lo, __hi);}
    278     virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
    279 };
    280 
    281 template <class _CharT> locale::id collate<_CharT>::id;
    282 
    283 template <class _CharT>
    284 collate<_CharT>::~collate()
    285 {
    286 }
    287 
    288 template <class _CharT>
    289 int
    290 collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
    291                             const char_type* __lo2, const char_type* __hi2) const
    292 {
    293     for (; __lo2 != __hi2; ++__lo1, ++__lo2)
    294     {
    295         if (__lo1 == __hi1 || *__lo1 < *__lo2)
    296             return -1;
    297         if (*__lo2 < *__lo1)
    298             return 1;
    299     }
    300     return __lo1 != __hi1;
    301 }
    302 
    303 template <class _CharT>
    304 long
    305 collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
    306 {
    307     size_t __h = 0;
    308     const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
    309     const size_t __mask = size_t(0xF) << (__sr + 4);
    310     for(const char_type* __p = __lo; __p != __hi; ++__p)
    311     {
    312         __h = (__h << 4) + static_cast<size_t>(*__p);
    313         size_t __g = __h & __mask;
    314         __h ^= __g | (__g >> __sr);
    315     }
    316     return static_cast<long>(__h);
    317 }
    318 
    319 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<char>)
    320 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>)
    321 
    322 // template <class CharT> class collate_byname;
    323 
    324 template <class _CharT> class _LIBCPP_TEMPLATE_VIS collate_byname;
    325 
    326 template <>
    327 class _LIBCPP_TYPE_VIS collate_byname<char>
    328     : public collate<char>
    329 {
    330     locale_t __l;
    331 public:
    332     typedef char char_type;
    333     typedef basic_string<char_type> string_type;
    334 
    335     explicit collate_byname(const char* __n, size_t __refs = 0);
    336     explicit collate_byname(const string& __n, size_t __refs = 0);
    337 
    338 protected:
    339     ~collate_byname();
    340     virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
    341                            const char_type* __lo2, const char_type* __hi2) const;
    342     virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
    343 };
    344 
    345 template <>
    346 class _LIBCPP_TYPE_VIS collate_byname<wchar_t>
    347     : public collate<wchar_t>
    348 {
    349     locale_t __l;
    350 public:
    351     typedef wchar_t char_type;
    352     typedef basic_string<char_type> string_type;
    353 
    354     explicit collate_byname(const char* __n, size_t __refs = 0);
    355     explicit collate_byname(const string& __n, size_t __refs = 0);
    356 
    357 protected:
    358     ~collate_byname();
    359 
    360     virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
    361                            const char_type* __lo2, const char_type* __hi2) const;
    362     virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
    363 };
    364 
    365 template <class _CharT, class _Traits, class _Allocator>
    366 bool
    367 locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
    368                    const basic_string<_CharT, _Traits, _Allocator>& __y) const
    369 {
    370     return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
    371                                        __x.data(), __x.data() + __x.size(),
    372                                        __y.data(), __y.data() + __y.size()) < 0;
    373 }
    374 
    375 // template <class charT> class ctype
    376 
    377 class _LIBCPP_TYPE_VIS ctype_base
    378 {
    379 public:
    380 #if defined(__GLIBC__)
    381     typedef unsigned short mask;
    382     static const mask space  = _ISspace;
    383     static const mask print  = _ISprint;
    384     static const mask cntrl  = _IScntrl;
    385     static const mask upper  = _ISupper;
    386     static const mask lower  = _ISlower;
    387     static const mask alpha  = _ISalpha;
    388     static const mask digit  = _ISdigit;
    389     static const mask punct  = _ISpunct;
    390     static const mask xdigit = _ISxdigit;
    391     static const mask blank  = _ISblank;
    392 #elif defined(_LIBCPP_MSVCRT_LIKE)
    393     typedef unsigned short mask;
    394     static const mask space  = _SPACE;
    395     static const mask print  = _BLANK|_PUNCT|_ALPHA|_DIGIT;
    396     static const mask cntrl  = _CONTROL;
    397     static const mask upper  = _UPPER;
    398     static const mask lower  = _LOWER;
    399     static const mask alpha  = _ALPHA;
    400     static const mask digit  = _DIGIT;
    401     static const mask punct  = _PUNCT;
    402     static const mask xdigit = _HEX;
    403     static const mask blank  = _BLANK;
    404 # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
    405 #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
    406 # ifdef __APPLE__
    407     typedef __uint32_t mask;
    408 # elif defined(__FreeBSD__)
    409     typedef unsigned long mask;
    410 # elif defined(__EMSCRIPTEN__) || defined(__NetBSD__)
    411     typedef unsigned short mask;
    412 # endif
    413     static const mask space  = _CTYPE_S;
    414     static const mask print  = _CTYPE_R;
    415     static const mask cntrl  = _CTYPE_C;
    416     static const mask upper  = _CTYPE_U;
    417     static const mask lower  = _CTYPE_L;
    418     static const mask alpha  = _CTYPE_A;
    419     static const mask digit  = _CTYPE_D;
    420     static const mask punct  = _CTYPE_P;
    421     static const mask xdigit = _CTYPE_X;
    422 
    423 # if defined(__NetBSD__)
    424     static const mask blank  = _CTYPE_BL;
    425 # else
    426     static const mask blank  = _CTYPE_B;
    427 # endif
    428 #elif defined(__sun__) || defined(_AIX)
    429     typedef unsigned int mask;
    430     static const mask space  = _ISSPACE;
    431     static const mask print  = _ISPRINT;
    432     static const mask cntrl  = _ISCNTRL;
    433     static const mask upper  = _ISUPPER;
    434     static const mask lower  = _ISLOWER;
    435     static const mask alpha  = _ISALPHA;
    436     static const mask digit  = _ISDIGIT;
    437     static const mask punct  = _ISPUNCT;
    438     static const mask xdigit = _ISXDIGIT;
    439     static const mask blank  = _ISBLANK;
    440 #elif defined(_NEWLIB_VERSION)
    441     // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
    442     typedef char mask;
    443     static const mask space  = _S;
    444     static const mask print  = _P | _U | _L | _N | _B;
    445     static const mask cntrl  = _C;
    446     static const mask upper  = _U;
    447     static const mask lower  = _L;
    448     static const mask alpha  = _U | _L;
    449     static const mask digit  = _N;
    450     static const mask punct  = _P;
    451     static const mask xdigit = _X | _N;
    452     static const mask blank  = _B;
    453 # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
    454 # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
    455 # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
    456 #else
    457     typedef unsigned long mask;
    458     static const mask space  = 1<<0;
    459     static const mask print  = 1<<1;
    460     static const mask cntrl  = 1<<2;
    461     static const mask upper  = 1<<3;
    462     static const mask lower  = 1<<4;
    463     static const mask alpha  = 1<<5;
    464     static const mask digit  = 1<<6;
    465     static const mask punct  = 1<<7;
    466     static const mask xdigit = 1<<8;
    467     static const mask blank  = 1<<9;
    468 #endif
    469     static const mask alnum  = alpha | digit;
    470     static const mask graph  = alnum | punct;
    471 
    472     _LIBCPP_INLINE_VISIBILITY ctype_base() {}
    473 };
    474 
    475 template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype;
    476 
    477 template <>
    478 class _LIBCPP_TYPE_VIS ctype<wchar_t>
    479     : public locale::facet,
    480       public ctype_base
    481 {
    482 public:
    483     typedef wchar_t char_type;
    484 
    485     _LIBCPP_INLINE_VISIBILITY
    486     explicit ctype(size_t __refs = 0)
    487         : locale::facet(__refs) {}
    488 
    489     _LIBCPP_INLINE_VISIBILITY
    490     bool is(mask __m, char_type __c) const
    491     {
    492         return do_is(__m, __c);
    493     }
    494 
    495     _LIBCPP_INLINE_VISIBILITY
    496     const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
    497     {
    498         return do_is(__low, __high, __vec);
    499     }
    500 
    501     _LIBCPP_INLINE_VISIBILITY
    502     const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
    503     {
    504         return do_scan_is(__m, __low, __high);
    505     }
    506 
    507     _LIBCPP_INLINE_VISIBILITY
    508     const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
    509     {
    510         return do_scan_not(__m, __low, __high);
    511     }
    512 
    513     _LIBCPP_INLINE_VISIBILITY
    514     char_type toupper(char_type __c) const
    515     {
    516         return do_toupper(__c);
    517     }
    518 
    519     _LIBCPP_INLINE_VISIBILITY
    520     const char_type* toupper(char_type* __low, const char_type* __high) const
    521     {
    522         return do_toupper(__low, __high);
    523     }
    524 
    525     _LIBCPP_INLINE_VISIBILITY
    526     char_type tolower(char_type __c) const
    527     {
    528         return do_tolower(__c);
    529     }
    530 
    531     _LIBCPP_INLINE_VISIBILITY
    532     const char_type* tolower(char_type* __low, const char_type* __high) const
    533     {
    534         return do_tolower(__low, __high);
    535     }
    536 
    537     _LIBCPP_INLINE_VISIBILITY
    538     char_type widen(char __c) const
    539     {
    540         return do_widen(__c);
    541     }
    542 
    543     _LIBCPP_INLINE_VISIBILITY
    544     const char* widen(const char* __low, const char* __high, char_type* __to) const
    545     {
    546         return do_widen(__low, __high, __to);
    547     }
    548 
    549     _LIBCPP_INLINE_VISIBILITY
    550     char narrow(char_type __c, char __dfault) const
    551     {
    552         return do_narrow(__c, __dfault);
    553     }
    554 
    555     _LIBCPP_INLINE_VISIBILITY
    556     const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
    557     {
    558         return do_narrow(__low, __high, __dfault, __to);
    559     }
    560 
    561     static locale::id id;
    562 
    563 protected:
    564     ~ctype();
    565     virtual bool do_is(mask __m, char_type __c) const;
    566     virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
    567     virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
    568     virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
    569     virtual char_type do_toupper(char_type) const;
    570     virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
    571     virtual char_type do_tolower(char_type) const;
    572     virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
    573     virtual char_type do_widen(char) const;
    574     virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
    575     virtual char do_narrow(char_type, char __dfault) const;
    576     virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
    577 };
    578 
    579 template <>
    580 class _LIBCPP_TYPE_VIS ctype<char>
    581     : public locale::facet, public ctype_base
    582 {
    583     const mask* __tab_;
    584     bool        __del_;
    585 public:
    586     typedef char char_type;
    587 
    588     explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
    589 
    590     _LIBCPP_INLINE_VISIBILITY
    591     bool is(mask __m, char_type __c) const
    592     {
    593         return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false;
    594     }
    595 
    596     _LIBCPP_INLINE_VISIBILITY
    597     const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
    598     {
    599         for (; __low != __high; ++__low, ++__vec)
    600             *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;
    601         return __low;
    602     }
    603 
    604     _LIBCPP_INLINE_VISIBILITY
    605     const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
    606     {
    607         for (; __low != __high; ++__low)
    608             if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))
    609                 break;
    610         return __low;
    611     }
    612 
    613     _LIBCPP_INLINE_VISIBILITY
    614     const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
    615     {
    616         for (; __low != __high; ++__low)
    617             if (!(isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m)))
    618                 break;
    619         return __low;
    620     }
    621 
    622     _LIBCPP_INLINE_VISIBILITY
    623     char_type toupper(char_type __c) const
    624     {
    625         return do_toupper(__c);
    626     }
    627 
    628     _LIBCPP_INLINE_VISIBILITY
    629     const char_type* toupper(char_type* __low, const char_type* __high) const
    630     {
    631         return do_toupper(__low, __high);
    632     }
    633 
    634     _LIBCPP_INLINE_VISIBILITY
    635     char_type tolower(char_type __c) const
    636     {
    637         return do_tolower(__c);
    638     }
    639 
    640     _LIBCPP_INLINE_VISIBILITY
    641     const char_type* tolower(char_type* __low, const char_type* __high) const
    642     {
    643         return do_tolower(__low, __high);
    644     }
    645 
    646     _LIBCPP_INLINE_VISIBILITY
    647     char_type widen(char __c) const
    648     {
    649         return do_widen(__c);
    650     }
    651 
    652     _LIBCPP_INLINE_VISIBILITY
    653     const char* widen(const char* __low, const char* __high, char_type* __to) const
    654     {
    655         return do_widen(__low, __high, __to);
    656     }
    657 
    658     _LIBCPP_INLINE_VISIBILITY
    659     char narrow(char_type __c, char __dfault) const
    660     {
    661         return do_narrow(__c, __dfault);
    662     }
    663 
    664     _LIBCPP_INLINE_VISIBILITY
    665     const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
    666     {
    667         return do_narrow(__low, __high, __dfault, __to);
    668     }
    669 
    670     static locale::id id;
    671 
    672 #ifdef _CACHED_RUNES
    673     static const size_t table_size = _CACHED_RUNES;
    674 #else
    675     static const size_t table_size = 256;  // FIXME: Don't hardcode this.
    676 #endif
    677     _LIBCPP_INLINE_VISIBILITY const mask* table() const  _NOEXCEPT {return __tab_;}
    678     static const mask* classic_table()  _NOEXCEPT;
    679 #if defined(__GLIBC__) || defined(__EMSCRIPTEN__)
    680     static const int* __classic_upper_table() _NOEXCEPT;
    681     static const int* __classic_lower_table() _NOEXCEPT;
    682 #endif
    683 #if defined(__NetBSD__)
    684     static const short* __classic_upper_table() _NOEXCEPT;
    685     static const short* __classic_lower_table() _NOEXCEPT;
    686 #endif
    687 
    688 protected:
    689     ~ctype();
    690     virtual char_type do_toupper(char_type __c) const;
    691     virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
    692     virtual char_type do_tolower(char_type __c) const;
    693     virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
    694     virtual char_type do_widen(char __c) const;
    695     virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
    696     virtual char do_narrow(char_type __c, char __dfault) const;
    697     virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
    698 };
    699 
    700 // template <class CharT> class ctype_byname;
    701 
    702 template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype_byname;
    703 
    704 template <>
    705 class _LIBCPP_TYPE_VIS ctype_byname<char>
    706     : public ctype<char>
    707 {
    708     locale_t __l;
    709 
    710 public:
    711     explicit ctype_byname(const char*, size_t = 0);
    712     explicit ctype_byname(const string&, size_t = 0);
    713 
    714 protected:
    715     ~ctype_byname();
    716     virtual char_type do_toupper(char_type) const;
    717     virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
    718     virtual char_type do_tolower(char_type) const;
    719     virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
    720 };
    721 
    722 template <>
    723 class _LIBCPP_TYPE_VIS ctype_byname<wchar_t>
    724     : public ctype<wchar_t>
    725 {
    726     locale_t __l;
    727 
    728 public:
    729     explicit ctype_byname(const char*, size_t = 0);
    730     explicit ctype_byname(const string&, size_t = 0);
    731 
    732 protected:
    733     ~ctype_byname();
    734     virtual bool do_is(mask __m, char_type __c) const;
    735     virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
    736     virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
    737     virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
    738     virtual char_type do_toupper(char_type) const;
    739     virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
    740     virtual char_type do_tolower(char_type) const;
    741     virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
    742     virtual char_type do_widen(char) const;
    743     virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
    744     virtual char do_narrow(char_type, char __dfault) const;
    745     virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
    746 };
    747 
    748 template <class _CharT>
    749 inline _LIBCPP_INLINE_VISIBILITY
    750 bool
    751 isspace(_CharT __c, const locale& __loc)
    752 {
    753     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
    754 }
    755 
    756 template <class _CharT>
    757 inline _LIBCPP_INLINE_VISIBILITY
    758 bool
    759 isprint(_CharT __c, const locale& __loc)
    760 {
    761     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
    762 }
    763 
    764 template <class _CharT>
    765 inline _LIBCPP_INLINE_VISIBILITY
    766 bool
    767 iscntrl(_CharT __c, const locale& __loc)
    768 {
    769     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
    770 }
    771 
    772 template <class _CharT>
    773 inline _LIBCPP_INLINE_VISIBILITY
    774 bool
    775 isupper(_CharT __c, const locale& __loc)
    776 {
    777     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
    778 }
    779 
    780 template <class _CharT>
    781 inline _LIBCPP_INLINE_VISIBILITY
    782 bool
    783 islower(_CharT __c, const locale& __loc)
    784 {
    785     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
    786 }
    787 
    788 template <class _CharT>
    789 inline _LIBCPP_INLINE_VISIBILITY
    790 bool
    791 isalpha(_CharT __c, const locale& __loc)
    792 {
    793     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
    794 }
    795 
    796 template <class _CharT>
    797 inline _LIBCPP_INLINE_VISIBILITY
    798 bool
    799 isdigit(_CharT __c, const locale& __loc)
    800 {
    801     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
    802 }
    803 
    804 template <class _CharT>
    805 inline _LIBCPP_INLINE_VISIBILITY
    806 bool
    807 ispunct(_CharT __c, const locale& __loc)
    808 {
    809     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
    810 }
    811 
    812 template <class _CharT>
    813 inline _LIBCPP_INLINE_VISIBILITY
    814 bool
    815 isxdigit(_CharT __c, const locale& __loc)
    816 {
    817     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
    818 }
    819 
    820 template <class _CharT>
    821 inline _LIBCPP_INLINE_VISIBILITY
    822 bool
    823 isalnum(_CharT __c, const locale& __loc)
    824 {
    825     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
    826 }
    827 
    828 template <class _CharT>
    829 inline _LIBCPP_INLINE_VISIBILITY
    830 bool
    831 isgraph(_CharT __c, const locale& __loc)
    832 {
    833     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
    834 }
    835 
    836 template <class _CharT>
    837 inline _LIBCPP_INLINE_VISIBILITY
    838 _CharT
    839 toupper(_CharT __c, const locale& __loc)
    840 {
    841     return use_facet<ctype<_CharT> >(__loc).toupper(__c);
    842 }
    843 
    844 template <class _CharT>
    845 inline _LIBCPP_INLINE_VISIBILITY
    846 _CharT
    847 tolower(_CharT __c, const locale& __loc)
    848 {
    849     return use_facet<ctype<_CharT> >(__loc).tolower(__c);
    850 }
    851 
    852 // codecvt_base
    853 
    854 class _LIBCPP_TYPE_VIS codecvt_base
    855 {
    856 public:
    857     _LIBCPP_INLINE_VISIBILITY codecvt_base() {}
    858     enum result {ok, partial, error, noconv};
    859 };
    860 
    861 // template <class internT, class externT, class stateT> class codecvt;
    862 
    863 template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TEMPLATE_VIS codecvt;
    864 
    865 // template <> class codecvt<char, char, mbstate_t>
    866 
    867 template <>
    868 class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t>
    869     : public locale::facet,
    870       public codecvt_base
    871 {
    872 public:
    873     typedef char      intern_type;
    874     typedef char      extern_type;
    875     typedef mbstate_t state_type;
    876 
    877     _LIBCPP_INLINE_VISIBILITY
    878     explicit codecvt(size_t __refs = 0)
    879         : locale::facet(__refs) {}
    880 
    881     _LIBCPP_INLINE_VISIBILITY
    882     result out(state_type& __st,
    883                const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
    884                extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
    885     {
    886         return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
    887     }
    888 
    889     _LIBCPP_INLINE_VISIBILITY
    890     result unshift(state_type& __st,
    891                    extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
    892     {
    893         return do_unshift(__st, __to, __to_end, __to_nxt);
    894     }
    895 
    896     _LIBCPP_INLINE_VISIBILITY
    897     result in(state_type& __st,
    898               const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
    899               intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
    900     {
    901         return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
    902     }
    903 
    904     _LIBCPP_INLINE_VISIBILITY
    905     int encoding() const  _NOEXCEPT
    906     {
    907         return do_encoding();
    908     }
    909 
    910     _LIBCPP_INLINE_VISIBILITY
    911     bool always_noconv() const  _NOEXCEPT
    912     {
    913         return do_always_noconv();
    914     }
    915 
    916     _LIBCPP_INLINE_VISIBILITY
    917     int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
    918     {
    919         return do_length(__st, __frm, __end, __mx);
    920     }
    921 
    922     _LIBCPP_INLINE_VISIBILITY
    923     int max_length() const  _NOEXCEPT
    924     {
    925         return do_max_length();
    926     }
    927 
    928     static locale::id id;
    929 
    930 protected:
    931     _LIBCPP_INLINE_VISIBILITY
    932     explicit codecvt(const char*, size_t __refs = 0)
    933         : locale::facet(__refs) {}
    934 
    935     ~codecvt();
    936 
    937     virtual result do_out(state_type& __st,
    938                           const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
    939                           extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
    940     virtual result do_in(state_type& __st,
    941                          const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
    942                          intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
    943     virtual result do_unshift(state_type& __st,
    944                               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
    945     virtual int do_encoding() const  _NOEXCEPT;
    946     virtual bool do_always_noconv() const  _NOEXCEPT;
    947     virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
    948     virtual int do_max_length() const  _NOEXCEPT;
    949 };
    950 
    951 // template <> class codecvt<wchar_t, char, mbstate_t>
    952 
    953 template <>
    954 class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t>
    955     : public locale::facet,
    956       public codecvt_base
    957 {
    958     locale_t __l;
    959 public:
    960     typedef wchar_t   intern_type;
    961     typedef char      extern_type;
    962     typedef mbstate_t state_type;
    963 
    964     explicit codecvt(size_t __refs = 0);
    965 
    966     _LIBCPP_INLINE_VISIBILITY
    967     result out(state_type& __st,
    968                const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
    969                extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
    970     {
    971         return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
    972     }
    973 
    974     _LIBCPP_INLINE_VISIBILITY
    975     result unshift(state_type& __st,
    976                    extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
    977     {
    978         return do_unshift(__st, __to, __to_end, __to_nxt);
    979     }
    980 
    981     _LIBCPP_INLINE_VISIBILITY
    982     result in(state_type& __st,
    983               const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
    984               intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
    985     {
    986         return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
    987     }
    988 
    989     _LIBCPP_INLINE_VISIBILITY
    990     int encoding() const  _NOEXCEPT
    991     {
    992         return do_encoding();
    993     }
    994 
    995     _LIBCPP_INLINE_VISIBILITY
    996     bool always_noconv() const  _NOEXCEPT
    997     {
    998         return do_always_noconv();
    999     }
   1000 
   1001     _LIBCPP_INLINE_VISIBILITY
   1002     int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
   1003     {
   1004         return do_length(__st, __frm, __end, __mx);
   1005     }
   1006 
   1007     _LIBCPP_INLINE_VISIBILITY
   1008     int max_length() const  _NOEXCEPT
   1009     {
   1010         return do_max_length();
   1011     }
   1012 
   1013     static locale::id id;
   1014 
   1015 protected:
   1016     explicit codecvt(const char*, size_t __refs = 0);
   1017 
   1018     ~codecvt();
   1019 
   1020     virtual result do_out(state_type& __st,
   1021                           const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
   1022                           extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
   1023     virtual result do_in(state_type& __st,
   1024                          const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
   1025                          intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
   1026     virtual result do_unshift(state_type& __st,
   1027                               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
   1028     virtual int do_encoding() const  _NOEXCEPT;
   1029     virtual bool do_always_noconv() const  _NOEXCEPT;
   1030     virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
   1031     virtual int do_max_length() const  _NOEXCEPT;
   1032 };
   1033 
   1034 // template <> class codecvt<char16_t, char, mbstate_t>
   1035 
   1036 template <>
   1037 class _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t>
   1038     : public locale::facet,
   1039       public codecvt_base
   1040 {
   1041 public:
   1042     typedef char16_t  intern_type;
   1043     typedef char      extern_type;
   1044     typedef mbstate_t state_type;
   1045 
   1046     _LIBCPP_INLINE_VISIBILITY
   1047     explicit codecvt(size_t __refs = 0)
   1048         : locale::facet(__refs) {}
   1049 
   1050     _LIBCPP_INLINE_VISIBILITY
   1051     result out(state_type& __st,
   1052                const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
   1053                extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
   1054     {
   1055         return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
   1056     }
   1057 
   1058     _LIBCPP_INLINE_VISIBILITY
   1059     result unshift(state_type& __st,
   1060                    extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
   1061     {
   1062         return do_unshift(__st, __to, __to_end, __to_nxt);
   1063     }
   1064 
   1065     _LIBCPP_INLINE_VISIBILITY
   1066     result in(state_type& __st,
   1067               const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
   1068               intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
   1069     {
   1070         return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
   1071     }
   1072 
   1073     _LIBCPP_INLINE_VISIBILITY
   1074     int encoding() const  _NOEXCEPT
   1075     {
   1076         return do_encoding();
   1077     }
   1078 
   1079     _LIBCPP_INLINE_VISIBILITY
   1080     bool always_noconv() const  _NOEXCEPT
   1081     {
   1082         return do_always_noconv();
   1083     }
   1084 
   1085     _LIBCPP_INLINE_VISIBILITY
   1086     int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
   1087     {
   1088         return do_length(__st, __frm, __end, __mx);
   1089     }
   1090 
   1091     _LIBCPP_INLINE_VISIBILITY
   1092     int max_length() const  _NOEXCEPT
   1093     {
   1094         return do_max_length();
   1095     }
   1096 
   1097     static locale::id id;
   1098 
   1099 protected:
   1100     _LIBCPP_INLINE_VISIBILITY
   1101     explicit codecvt(const char*, size_t __refs = 0)
   1102         : locale::facet(__refs) {}
   1103 
   1104     ~codecvt();
   1105 
   1106     virtual result do_out(state_type& __st,
   1107                           const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
   1108                           extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
   1109     virtual result do_in(state_type& __st,
   1110                          const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
   1111                          intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
   1112     virtual result do_unshift(state_type& __st,
   1113                               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
   1114     virtual int do_encoding() const  _NOEXCEPT;
   1115     virtual bool do_always_noconv() const  _NOEXCEPT;
   1116     virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
   1117     virtual int do_max_length() const  _NOEXCEPT;
   1118 };
   1119 
   1120 // template <> class codecvt<char32_t, char, mbstate_t>
   1121 
   1122 template <>
   1123 class _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t>
   1124     : public locale::facet,
   1125       public codecvt_base
   1126 {
   1127 public:
   1128     typedef char32_t  intern_type;
   1129     typedef char      extern_type;
   1130     typedef mbstate_t state_type;
   1131 
   1132     _LIBCPP_INLINE_VISIBILITY
   1133     explicit codecvt(size_t __refs = 0)
   1134         : locale::facet(__refs) {}
   1135 
   1136     _LIBCPP_INLINE_VISIBILITY
   1137     result out(state_type& __st,
   1138                const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
   1139                extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
   1140     {
   1141         return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
   1142     }
   1143 
   1144     _LIBCPP_INLINE_VISIBILITY
   1145     result unshift(state_type& __st,
   1146                    extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
   1147     {
   1148         return do_unshift(__st, __to, __to_end, __to_nxt);
   1149     }
   1150 
   1151     _LIBCPP_INLINE_VISIBILITY
   1152     result in(state_type& __st,
   1153               const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
   1154               intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
   1155     {
   1156         return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
   1157     }
   1158 
   1159     _LIBCPP_INLINE_VISIBILITY
   1160     int encoding() const  _NOEXCEPT
   1161     {
   1162         return do_encoding();
   1163     }
   1164 
   1165     _LIBCPP_INLINE_VISIBILITY
   1166     bool always_noconv() const  _NOEXCEPT
   1167     {
   1168         return do_always_noconv();
   1169     }
   1170 
   1171     _LIBCPP_INLINE_VISIBILITY
   1172     int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
   1173     {
   1174         return do_length(__st, __frm, __end, __mx);
   1175     }
   1176 
   1177     _LIBCPP_INLINE_VISIBILITY
   1178     int max_length() const  _NOEXCEPT
   1179     {
   1180         return do_max_length();
   1181     }
   1182 
   1183     static locale::id id;
   1184 
   1185 protected:
   1186     _LIBCPP_INLINE_VISIBILITY
   1187     explicit codecvt(const char*, size_t __refs = 0)
   1188         : locale::facet(__refs) {}
   1189 
   1190     ~codecvt();
   1191 
   1192     virtual result do_out(state_type& __st,
   1193                           const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
   1194                           extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
   1195     virtual result do_in(state_type& __st,
   1196                          const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
   1197                          intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
   1198     virtual result do_unshift(state_type& __st,
   1199                               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
   1200     virtual int do_encoding() const  _NOEXCEPT;
   1201     virtual bool do_always_noconv() const  _NOEXCEPT;
   1202     virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
   1203     virtual int do_max_length() const  _NOEXCEPT;
   1204 };
   1205 
   1206 // template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
   1207 
   1208 template <class _InternT, class _ExternT, class _StateT>
   1209 class _LIBCPP_TEMPLATE_VIS codecvt_byname
   1210     : public codecvt<_InternT, _ExternT, _StateT>
   1211 {
   1212 public:
   1213     _LIBCPP_INLINE_VISIBILITY
   1214     explicit codecvt_byname(const char* __nm, size_t __refs = 0)
   1215         : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
   1216     _LIBCPP_INLINE_VISIBILITY
   1217     explicit codecvt_byname(const string& __nm, size_t __refs = 0)
   1218         : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
   1219 protected:
   1220     ~codecvt_byname();
   1221 };
   1222 
   1223 template <class _InternT, class _ExternT, class _StateT>
   1224 codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
   1225 {
   1226 }
   1227 
   1228 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>)
   1229 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>)
   1230 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)
   1231 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)
   1232 
   1233 _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
   1234 
   1235 template <size_t _Np>
   1236 struct __narrow_to_utf8
   1237 {
   1238     template <class _OutputIterator, class _CharT>
   1239     _OutputIterator
   1240     operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
   1241 };
   1242 
   1243 template <>
   1244 struct __narrow_to_utf8<8>
   1245 {
   1246     template <class _OutputIterator, class _CharT>
   1247     _LIBCPP_INLINE_VISIBILITY
   1248     _OutputIterator
   1249     operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
   1250     {
   1251         for (; __wb < __we; ++__wb, ++__s)
   1252             *__s = *__wb;
   1253         return __s;
   1254     }
   1255 };
   1256 
   1257 template <>
   1258 struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16>
   1259     : public codecvt<char16_t, char, mbstate_t>
   1260 {
   1261     _LIBCPP_INLINE_VISIBILITY
   1262     __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
   1263 
   1264     _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
   1265 
   1266     template <class _OutputIterator, class _CharT>
   1267     _LIBCPP_INLINE_VISIBILITY
   1268     _OutputIterator
   1269     operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
   1270     {
   1271         result __r = ok;
   1272         mbstate_t __mb;
   1273         while (__wb < __we && __r != error)
   1274         {
   1275             const int __sz = 32;
   1276             char __buf[__sz];
   1277             char* __bn;
   1278             const char16_t* __wn = (const char16_t*)__wb;
   1279             __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
   1280                          __buf, __buf+__sz, __bn);
   1281             if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
   1282                 __throw_runtime_error("locale not supported");
   1283             for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
   1284                 *__s = *__p;
   1285             __wb = (const _CharT*)__wn;
   1286         }
   1287         return __s;
   1288     }
   1289 };
   1290 
   1291 template <>
   1292 struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32>
   1293     : public codecvt<char32_t, char, mbstate_t>
   1294 {
   1295     _LIBCPP_INLINE_VISIBILITY
   1296     __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
   1297 
   1298     _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8();
   1299 
   1300     template <class _OutputIterator, class _CharT>
   1301     _LIBCPP_INLINE_VISIBILITY
   1302     _OutputIterator
   1303     operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
   1304     {
   1305         result __r = ok;
   1306         mbstate_t __mb;
   1307         while (__wb < __we && __r != error)
   1308         {
   1309             const int __sz = 32;
   1310             char __buf[__sz];
   1311             char* __bn;
   1312             const char32_t* __wn = (const char32_t*)__wb;
   1313             __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
   1314                          __buf, __buf+__sz, __bn);
   1315             if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
   1316                 __throw_runtime_error("locale not supported");
   1317             for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
   1318                 *__s = *__p;
   1319             __wb = (const _CharT*)__wn;
   1320         }
   1321         return __s;
   1322     }
   1323 };
   1324 
   1325 template <size_t _Np>
   1326 struct __widen_from_utf8
   1327 {
   1328     template <class _OutputIterator>
   1329     _OutputIterator
   1330     operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
   1331 };
   1332 
   1333 template <>
   1334 struct __widen_from_utf8<8>
   1335 {
   1336     template <class _OutputIterator>
   1337     _LIBCPP_INLINE_VISIBILITY
   1338     _OutputIterator
   1339     operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
   1340     {
   1341         for (; __nb < __ne; ++__nb, ++__s)
   1342             *__s = *__nb;
   1343         return __s;
   1344     }
   1345 };
   1346 
   1347 template <>
   1348 struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16>
   1349     : public codecvt<char16_t, char, mbstate_t>
   1350 {
   1351     _LIBCPP_INLINE_VISIBILITY
   1352     __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
   1353 
   1354     _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
   1355 
   1356     template <class _OutputIterator>
   1357     _LIBCPP_INLINE_VISIBILITY
   1358     _OutputIterator
   1359     operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
   1360     {
   1361         result __r = ok;
   1362         mbstate_t __mb;
   1363         while (__nb < __ne && __r != error)
   1364         {
   1365             const int __sz = 32;
   1366             char16_t __buf[__sz];
   1367             char16_t* __bn;
   1368             const char* __nn = __nb;
   1369             __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
   1370                         __buf, __buf+__sz, __bn);
   1371             if (__r == codecvt_base::error || __nn == __nb)
   1372                 __throw_runtime_error("locale not supported");
   1373             for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
   1374                 *__s = (wchar_t)*__p;
   1375             __nb = __nn;
   1376         }
   1377         return __s;
   1378     }
   1379 };
   1380 
   1381 template <>
   1382 struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32>
   1383     : public codecvt<char32_t, char, mbstate_t>
   1384 {
   1385     _LIBCPP_INLINE_VISIBILITY
   1386     __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
   1387 
   1388     _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8();
   1389 
   1390     template <class _OutputIterator>
   1391     _LIBCPP_INLINE_VISIBILITY
   1392     _OutputIterator
   1393     operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
   1394     {
   1395         result __r = ok;
   1396         mbstate_t __mb;
   1397         while (__nb < __ne && __r != error)
   1398         {
   1399             const int __sz = 32;
   1400             char32_t __buf[__sz];
   1401             char32_t* __bn;
   1402             const char* __nn = __nb;
   1403             __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
   1404                         __buf, __buf+__sz, __bn);
   1405             if (__r == codecvt_base::error || __nn == __nb)
   1406                 __throw_runtime_error("locale not supported");
   1407             for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
   1408                 *__s = (wchar_t)*__p;
   1409             __nb = __nn;
   1410         }
   1411         return __s;
   1412     }
   1413 };
   1414 
   1415 // template <class charT> class numpunct
   1416 
   1417 template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct;
   1418 
   1419 template <>
   1420 class _LIBCPP_TYPE_VIS numpunct<char>
   1421     : public locale::facet
   1422 {
   1423 public:
   1424     typedef char char_type;
   1425     typedef basic_string<char_type> string_type;
   1426 
   1427     explicit numpunct(size_t __refs = 0);
   1428 
   1429     _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
   1430     _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
   1431     _LIBCPP_INLINE_VISIBILITY string grouping() const         {return do_grouping();}
   1432     _LIBCPP_INLINE_VISIBILITY string_type truename() const    {return do_truename();}
   1433     _LIBCPP_INLINE_VISIBILITY string_type falsename() const   {return do_falsename();}
   1434 
   1435     static locale::id id;
   1436 
   1437 protected:
   1438     ~numpunct();
   1439     virtual char_type do_decimal_point() const;
   1440     virtual char_type do_thousands_sep() const;
   1441     virtual string do_grouping() const;
   1442     virtual string_type do_truename() const;
   1443     virtual string_type do_falsename() const;
   1444 
   1445     char_type __decimal_point_;
   1446     char_type __thousands_sep_;
   1447     string __grouping_;
   1448 };
   1449 
   1450 template <>
   1451 class _LIBCPP_TYPE_VIS numpunct<wchar_t>
   1452     : public locale::facet
   1453 {
   1454 public:
   1455     typedef wchar_t char_type;
   1456     typedef basic_string<char_type> string_type;
   1457 
   1458     explicit numpunct(size_t __refs = 0);
   1459 
   1460     _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();}
   1461     _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();}
   1462     _LIBCPP_INLINE_VISIBILITY string grouping() const         {return do_grouping();}
   1463     _LIBCPP_INLINE_VISIBILITY string_type truename() const    {return do_truename();}
   1464     _LIBCPP_INLINE_VISIBILITY string_type falsename() const   {return do_falsename();}
   1465 
   1466     static locale::id id;
   1467 
   1468 protected:
   1469     ~numpunct();
   1470     virtual char_type do_decimal_point() const;
   1471     virtual char_type do_thousands_sep() const;
   1472     virtual string do_grouping() const;
   1473     virtual string_type do_truename() const;
   1474     virtual string_type do_falsename() const;
   1475 
   1476     char_type __decimal_point_;
   1477     char_type __thousands_sep_;
   1478     string __grouping_;
   1479 };
   1480 
   1481 // template <class charT> class numpunct_byname
   1482 
   1483 template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct_byname;
   1484 
   1485 template <>
   1486 class _LIBCPP_TYPE_VIS numpunct_byname<char>
   1487 : public numpunct<char>
   1488 {
   1489 public:
   1490     typedef char char_type;
   1491     typedef basic_string<char_type> string_type;
   1492 
   1493     explicit numpunct_byname(const char* __nm, size_t __refs = 0);
   1494     explicit numpunct_byname(const string& __nm, size_t __refs = 0);
   1495 
   1496 protected:
   1497     ~numpunct_byname();
   1498 
   1499 private:
   1500     void __init(const char*);
   1501 };
   1502 
   1503 template <>
   1504 class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t>
   1505 : public numpunct<wchar_t>
   1506 {
   1507 public:
   1508     typedef wchar_t char_type;
   1509     typedef basic_string<char_type> string_type;
   1510 
   1511     explicit numpunct_byname(const char* __nm, size_t __refs = 0);
   1512     explicit numpunct_byname(const string& __nm, size_t __refs = 0);
   1513 
   1514 protected:
   1515     ~numpunct_byname();
   1516 
   1517 private:
   1518     void __init(const char*);
   1519 };
   1520 
   1521 _LIBCPP_END_NAMESPACE_STD
   1522 
   1523 #endif  // _LIBCPP___LOCALE
   1524