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