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