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