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