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