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