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