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(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun__)) || defined(__EMSCRIPTEN__) || defined(__IBMCPP__)
     27 # include <xlocale.h>
     28 #endif  // _WIN32 || __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__ || __EMSCRIPTEN__ || __IBMCPP__
     29 
     30 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
     31 #pragma GCC system_header
     32 #endif
     33 
     34 _LIBCPP_BEGIN_NAMESPACE_STD
     35 
     36 class _LIBCPP_TYPE_VIS locale;
     37 
     38 template <class _Facet>
     39 _LIBCPP_INLINE_VISIBILITY
     40 bool
     41 has_facet(const locale&) _NOEXCEPT;
     42 
     43 template <class _Facet>
     44 _LIBCPP_INLINE_VISIBILITY
     45 const _Facet&
     46 use_facet(const locale&);
     47 
     48 class _LIBCPP_TYPE_VIS locale
     49 {
     50 public:
     51     // types:
     52     class _LIBCPP_TYPE_VIS facet;
     53     class _LIBCPP_TYPE_VIS id;
     54 
     55     typedef int category;
     56     static const category // values assigned here are for exposition only
     57         none     = 0,
     58         collate  = LC_COLLATE_MASK,
     59         ctype    = LC_CTYPE_MASK,
     60         monetary = LC_MONETARY_MASK,
     61         numeric  = LC_NUMERIC_MASK,
     62         time     = LC_TIME_MASK,
     63         messages = LC_MESSAGES_MASK,
     64         all = collate | ctype | monetary | numeric | time | messages;
     65 
     66     // construct/copy/destroy:
     67     locale()  _NOEXCEPT;
     68     locale(const locale&)  _NOEXCEPT;
     69     explicit locale(const char*);
     70     explicit locale(const string&);
     71     locale(const locale&, const char*, category);
     72     locale(const locale&, const string&, category);
     73     template <class _Facet>
     74         _LIBCPP_INLINE_VISIBILITY locale(const locale&, _Facet*);
     75     locale(const locale&, const locale&, category);
     76 
     77     ~locale();
     78 
     79     const locale& operator=(const locale&)  _NOEXCEPT;
     80 
     81     template <class _Facet> locale combine(const locale&) const;
     82 
     83     // locale operations:
     84     string name() const;
     85     bool operator==(const locale&) const;
     86     bool operator!=(const locale& __y) const {return !(*this == __y);}
     87     template <class _CharT, class _Traits, class _Allocator>
     88       bool operator()(const basic_string<_CharT, _Traits, _Allocator>&,
     89                       const basic_string<_CharT, _Traits, _Allocator>&) const;
     90 
     91     // global locale objects:
     92     static locale global(const locale&);
     93     static const locale& classic();
     94 
     95 private:
     96     class __imp;
     97     __imp* __locale_;
     98 
     99     void __install_ctor(const locale&, facet*, long);
    100     static locale& __global();
    101     bool has_facet(id&) const;
    102     const facet* use_facet(id&) const;
    103 
    104     template <class _Facet> friend bool has_facet(const locale&)  _NOEXCEPT;
    105     template <class _Facet> friend const _Facet& use_facet(const locale&);
    106 };
    107 
    108 class _LIBCPP_TYPE_VIS locale::facet
    109     : public __shared_count
    110 {
    111 protected:
    112     _LIBCPP_INLINE_VISIBILITY
    113     explicit facet(size_t __refs = 0)
    114         : __shared_count(static_cast<long>(__refs)-1) {}
    115 
    116     virtual ~facet();
    117 
    118 //    facet(const facet&) = delete;     // effectively done in __shared_count
    119 //    void operator=(const facet&) = delete;
    120 private:
    121     virtual void __on_zero_shared() _NOEXCEPT;
    122 };
    123 
    124 class _LIBCPP_TYPE_VIS locale::id
    125 {
    126     once_flag      __flag_;
    127     int32_t        __id_;
    128 
    129     static int32_t __next_id;
    130 public:
    131     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {}
    132 private:
    133     void __init();
    134     void operator=(const id&); // = delete;
    135     id(const id&); // = delete;
    136 public:  // only needed for tests
    137     long __get();
    138 
    139     friend class locale;
    140     friend class locale::__imp;
    141 };
    142 
    143 template <class _Facet>
    144 inline _LIBCPP_INLINE_VISIBILITY
    145 locale::locale(const locale& __other, _Facet* __f)
    146 {
    147     __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
    148 }
    149 
    150 template <class _Facet>
    151 locale
    152 locale::combine(const locale& __other) const
    153 {
    154 #ifndef _LIBCPP_NO_EXCEPTIONS
    155     if (!_VSTD::has_facet<_Facet>(__other))
    156         throw runtime_error("locale::combine: locale missing facet");
    157 #endif  // _LIBCPP_NO_EXCEPTIONS
    158     return locale(*this, &const_cast<_Facet&>(_VSTD::use_facet<_Facet>(__other)));
    159 }
    160 
    161 template <class _Facet>
    162 inline _LIBCPP_INLINE_VISIBILITY
    163 bool
    164 has_facet(const locale& __l)  _NOEXCEPT
    165 {
    166     return __l.has_facet(_Facet::id);
    167 }
    168 
    169 template <class _Facet>
    170 inline _LIBCPP_INLINE_VISIBILITY
    171 const _Facet&
    172 use_facet(const locale& __l)
    173 {
    174     return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
    175 }
    176 
    177 // template <class _CharT> class collate;
    178 
    179 template <class _CharT>
    180 class _LIBCPP_TYPE_VIS_ONLY collate
    181     : public locale::facet
    182 {
    183 public:
    184     typedef _CharT char_type;
    185     typedef basic_string<char_type> string_type;
    186 
    187     _LIBCPP_INLINE_VISIBILITY
    188     explicit collate(size_t __refs = 0)
    189         : locale::facet(__refs) {}
    190 
    191     _LIBCPP_INLINE_VISIBILITY
    192     int compare(const char_type* __lo1, const char_type* __hi1,
    193                 const char_type* __lo2, const char_type* __hi2) const
    194     {
    195         return do_compare(__lo1, __hi1, __lo2, __hi2);
    196     }
    197 
    198     _LIBCPP_INLINE_VISIBILITY
    199     string_type transform(const char_type* __lo, const char_type* __hi) const
    200     {
    201         return do_transform(__lo, __hi);
    202     }
    203 
    204     _LIBCPP_INLINE_VISIBILITY
    205     long hash(const char_type* __lo, const char_type* __hi) const
    206     {
    207         return do_hash(__lo, __hi);
    208     }
    209 
    210     static locale::id id;
    211 
    212 protected:
    213     ~collate();
    214     virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
    215                            const char_type* __lo2, const char_type* __hi2) const;
    216     virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const
    217         {return string_type(__lo, __hi);}
    218     virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
    219 };
    220 
    221 template <class _CharT> locale::id collate<_CharT>::id;
    222 
    223 template <class _CharT>
    224 collate<_CharT>::~collate()
    225 {
    226 }
    227 
    228 template <class _CharT>
    229 int
    230 collate<_CharT>::do_compare(const char_type* __lo1, const char_type* __hi1,
    231                             const char_type* __lo2, const char_type* __hi2) const
    232 {
    233     for (; __lo2 != __hi2; ++__lo1, ++__lo2)
    234     {
    235         if (__lo1 == __hi1 || *__lo1 < *__lo2)
    236             return -1;
    237         if (*__lo2 < *__lo1)
    238             return 1;
    239     }
    240     return __lo1 != __hi1;
    241 }
    242 
    243 template <class _CharT>
    244 long
    245 collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const
    246 {
    247     size_t __h = 0;
    248     const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
    249     const size_t __mask = size_t(0xF) << (__sr + 4);
    250     for(const char_type* __p = __lo; __p != __hi; ++__p)
    251     {
    252         __h = (__h << 4) + static_cast<size_t>(*__p);
    253         size_t __g = __h & __mask;
    254         __h ^= __g | (__g >> __sr);
    255     }
    256     return static_cast<long>(__h);
    257 }
    258 
    259 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<char>)
    260 _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_TYPE_VIS collate<wchar_t>)
    261 
    262 // template <class CharT> class collate_byname;
    263 
    264 template <class _CharT> class _LIBCPP_TYPE_VIS_ONLY collate_byname;
    265 
    266 template <>
    267 class _LIBCPP_TYPE_VIS collate_byname<char>
    268     : public collate<char>
    269 {
    270     locale_t __l;
    271 public:
    272     typedef char char_type;
    273     typedef basic_string<char_type> string_type;
    274 
    275     explicit collate_byname(const char* __n, size_t __refs = 0);
    276     explicit collate_byname(const string& __n, size_t __refs = 0);
    277 
    278 protected:
    279     ~collate_byname();
    280     virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
    281                            const char_type* __lo2, const char_type* __hi2) const;
    282     virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
    283 };
    284 
    285 template <>
    286 class _LIBCPP_TYPE_VIS collate_byname<wchar_t>
    287     : public collate<wchar_t>
    288 {
    289     locale_t __l;
    290 public:
    291     typedef wchar_t char_type;
    292     typedef basic_string<char_type> string_type;
    293 
    294     explicit collate_byname(const char* __n, size_t __refs = 0);
    295     explicit collate_byname(const string& __n, size_t __refs = 0);
    296 
    297 protected:
    298     ~collate_byname();
    299 
    300     virtual int do_compare(const char_type* __lo1, const char_type* __hi1,
    301                            const char_type* __lo2, const char_type* __hi2) const;
    302     virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const;
    303 };
    304 
    305 template <class _CharT, class _Traits, class _Allocator>
    306 bool
    307 locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
    308                    const basic_string<_CharT, _Traits, _Allocator>& __y) const
    309 {
    310     return _VSTD::use_facet<_VSTD::collate<_CharT> >(*this).compare(
    311                                        __x.data(), __x.data() + __x.size(),
    312                                        __y.data(), __y.data() + __y.size()) < 0;
    313 }
    314 
    315 // template <class charT> class ctype
    316 
    317 class _LIBCPP_TYPE_VIS ctype_base
    318 {
    319 public:
    320 #ifdef __GLIBC__
    321     typedef unsigned short mask;
    322     static const mask space  = _ISspace;
    323     static const mask print  = _ISprint;
    324     static const mask cntrl  = _IScntrl;
    325     static const mask upper  = _ISupper;
    326     static const mask lower  = _ISlower;
    327     static const mask alpha  = _ISalpha;
    328     static const mask digit  = _ISdigit;
    329     static const mask punct  = _ISpunct;
    330     static const mask xdigit = _ISxdigit;
    331     static const mask blank  = _ISblank;
    332 #elif defined(_WIN32)
    333     typedef unsigned short mask;
    334     static const mask space  = _SPACE;
    335     static const mask print  = _BLANK|_PUNCT|_ALPHA|_DIGIT;
    336     static const mask cntrl  = _CONTROL;
    337     static const mask upper  = _UPPER;
    338     static const mask lower  = _LOWER;
    339     static const mask alpha  = _ALPHA;
    340     static const mask digit  = _DIGIT;
    341     static const mask punct  = _PUNCT;
    342     static const mask xdigit = _HEX;
    343     static const mask blank  = _BLANK;
    344 #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
    345 #ifdef __APPLE__
    346     typedef __uint32_t mask;
    347 #elif defined(__FreeBSD__)
    348     typedef unsigned long mask;
    349 #elif defined(__EMSCRIPTEN__) ||  defined(__NetBSD__)
    350     typedef unsigned short mask;
    351 #endif
    352     static const mask space  = _CTYPE_S;
    353     static const mask print  = _CTYPE_R;
    354     static const mask cntrl  = _CTYPE_C;
    355     static const mask upper  = _CTYPE_U;
    356     static const mask lower  = _CTYPE_L;
    357     static const mask alpha  = _CTYPE_A;
    358     static const mask digit  = _CTYPE_D;
    359     static const mask punct  = _CTYPE_P;
    360     static const mask xdigit = _CTYPE_X;
    361 # if defined(__NetBSD__)
    362     static const mask blank  = _CTYPE_BL;
    363 # else
    364     static const mask blank  = _CTYPE_B;
    365 # endif
    366 #elif defined(__sun__) || defined(_AIX)
    367     typedef unsigned int mask;
    368     static const mask space  = _ISSPACE;
    369     static const mask print  = _ISPRINT;
    370     static const mask cntrl  = _ISCNTRL;
    371     static const mask upper  = _ISUPPER;
    372     static const mask lower  = _ISLOWER;
    373     static const mask alpha  = _ISALPHA;
    374     static const mask digit  = _ISDIGIT;
    375     static const mask punct  = _ISPUNCT;
    376     static const mask xdigit = _ISXDIGIT;
    377     static const mask blank  = _ISBLANK;
    378 #elif defined(__ANDROID__)
    379 # if !defined(_U)
    380 #   if !defined(_CTYPE_U)
    381 #    error Bionic header ctype.h does not define either _U nor _CTYPE_U
    382 #   endif
    383 #   define _U _CTYPE_U
    384 #   define _L _CTYPE_L
    385 #   define _N _CTYPE_N
    386 #   define _S _CTYPE_S
    387 #   define _P _CTYPE_P
    388 #   define _C _CTYPE_C
    389 #   define _X _CTYPE_X
    390 #   define _B _CTYPE_B
    391 # endif
    392     typedef unsigned short mask;
    393     static const mask space  = _S;
    394     static const mask print  = _P | _U | _L | _N | _B;
    395     static const mask cntrl  = _C;
    396     static const mask upper  = _U;
    397     static const mask lower  = _L;
    398     static const mask alpha  = _U | _L;
    399     static const mask digit  = _N;
    400     static const mask punct  = _P;
    401     static const mask xdigit = _N | _X;
    402     // See src/support/android/locale_android.cpp for details!
    403     static const mask blank  = 0x100;
    404 #else  // __ANDROID__
    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  // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || __EMSCRIPTEN__ || __sun__ || __ANDROID__
    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