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