]> CyberLeo.Net >> Repos - FreeBSD/releng/9.1.git/blob - contrib/libc++/include/__locale
Fix Denial of Service vulnerability in named(8). [13:07]
[FreeBSD/releng/9.1.git] / contrib / libc++ / include / __locale
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__ || __sun__)
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
34 class locale;
35
36 template <class _Facet> bool has_facet(const locale&) _NOEXCEPT;
37 template <class _Facet> const _Facet& use_facet(const locale&);
38
39 class _LIBCPP_VISIBLE locale
40 {
41 public:
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
86 private:
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
99 class _LIBCPP_VISIBLE locale::facet
100     : public __shared_count
101 {
102 protected:
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;
111 private:
112     virtual void __on_zero_shared() _NOEXCEPT;
113 };
114
115 class _LIBCPP_VISIBLE locale::id
116 {
117     once_flag      __flag_;
118     int32_t        __id_;
119
120     static int32_t __next_id;
121 public:
122     _LIBCPP_INLINE_VISIBILITY id() {}
123 private:
124     void __init();
125     void operator=(const id&); // = delete;
126     id(const id&); // = delete;
127 public:  // only needed for tests
128     long __get();
129
130     friend class locale;
131     friend class locale::__imp;
132 };
133
134 template <class _Facet>
135 inline _LIBCPP_INLINE_VISIBILITY
136 locale::locale(const locale& __other, _Facet* __f)
137 {
138     __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
139 }
140
141 template <class _Facet>
142 locale
143 locale::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
152 template <class _Facet>
153 inline _LIBCPP_INLINE_VISIBILITY
154 bool
155 has_facet(const locale& __l)  _NOEXCEPT
156 {
157     return __l.has_facet(_Facet::id);
158 }
159
160 template <class _Facet>
161 inline _LIBCPP_INLINE_VISIBILITY
162 const _Facet&
163 use_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
170 template <class _CharT>
171 class _LIBCPP_VISIBLE collate
172     : public locale::facet
173 {
174 public:
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
203 protected:
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
212 template <class _CharT> locale::id collate<_CharT>::id;
213
214 template <class _CharT>
215 collate<_CharT>::~collate()
216 {
217 }
218
219 template <class _CharT>
220 int
221 collate<_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
234 template <class _CharT>
235 long
236 collate<_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) + static_cast<size_t>(*__p);
244         size_t __g = __h & __mask;
245         __h ^= __g | (__g >> __sr);
246     }
247     return static_cast<long>(__h);
248 }
249
250 extern template class _LIBCPP_VISIBLE collate<char>;
251 extern template class _LIBCPP_VISIBLE collate<wchar_t>;
252
253 // template <class CharT> class collate_byname;
254
255 template <class _CharT> class _LIBCPP_VISIBLE collate_byname;
256
257 template <>
258 class _LIBCPP_VISIBLE collate_byname<char>
259     : public collate<char>
260 {
261     locale_t __l;
262 public:
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
269 protected:
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
276 template <>
277 class _LIBCPP_VISIBLE collate_byname<wchar_t>
278     : public collate<wchar_t>
279 {
280     locale_t __l;
281 public:
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
288 protected:
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
296 template <class _CharT, class _Traits, class _Allocator>
297 bool
298 locale::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
308 class _LIBCPP_VISIBLE ctype_base
309 {
310 public:
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 #elif __sun__
352     typedef unsigned int mask;
353     static const mask space  = _ISSPACE;
354     static const mask print  = _ISPRINT;
355     static const mask cntrl  = _ISCNTRL;
356     static const mask upper  = _ISUPPER;
357     static const mask lower  = _ISLOWER;
358     static const mask alpha  = _ISALPHA;
359     static const mask digit  = _ISDIGIT;
360     static const mask punct  = _ISPUNCT;
361     static const mask xdigit = _ISXDIGIT;
362     static const mask blank  = _ISBLANK;
363 #else  // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || __sun__
364     typedef unsigned long mask;
365     static const mask space  = 1<<0;
366     static const mask print  = 1<<1;
367     static const mask cntrl  = 1<<2;
368     static const mask upper  = 1<<3;
369     static const mask lower  = 1<<4;
370     static const mask alpha  = 1<<5;
371     static const mask digit  = 1<<6;
372     static const mask punct  = 1<<7;
373     static const mask xdigit = 1<<8;
374     static const mask blank  = 1<<9;
375 #endif  // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__
376     static const mask alnum  = alpha | digit;
377     static const mask graph  = alnum | punct;
378
379     _LIBCPP_ALWAYS_INLINE ctype_base() {}
380 };
381
382 template <class _CharT> class _LIBCPP_VISIBLE ctype;
383
384 template <>
385 class _LIBCPP_VISIBLE ctype<wchar_t>
386     : public locale::facet,
387       public ctype_base
388 {
389 public:
390     typedef wchar_t char_type;
391
392     _LIBCPP_ALWAYS_INLINE
393     explicit ctype(size_t __refs = 0)
394         : locale::facet(__refs) {}
395
396     _LIBCPP_ALWAYS_INLINE
397     bool is(mask __m, char_type __c) const
398     {
399         return do_is(__m, __c);
400     }
401
402     _LIBCPP_ALWAYS_INLINE
403     const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
404     {
405         return do_is(__low, __high, __vec);
406     }
407
408     _LIBCPP_ALWAYS_INLINE
409     const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const
410     {
411         return do_scan_is(__m, __low, __high);
412     }
413
414     _LIBCPP_ALWAYS_INLINE
415     const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
416     {
417         return do_scan_not(__m, __low, __high);
418     }
419
420     _LIBCPP_ALWAYS_INLINE
421     char_type toupper(char_type __c) const
422     {
423         return do_toupper(__c);
424     }
425
426     _LIBCPP_ALWAYS_INLINE
427     const char_type* toupper(char_type* __low, const char_type* __high) const
428     {
429         return do_toupper(__low, __high);
430     }
431
432     _LIBCPP_ALWAYS_INLINE
433     char_type tolower(char_type __c) const
434     {
435         return do_tolower(__c);
436     }
437
438     _LIBCPP_ALWAYS_INLINE
439     const char_type* tolower(char_type* __low, const char_type* __high) const
440     {
441         return do_tolower(__low, __high);
442     }
443
444     _LIBCPP_ALWAYS_INLINE
445     char_type widen(char __c) const
446     {
447         return do_widen(__c);
448     }
449
450     _LIBCPP_ALWAYS_INLINE
451     const char* widen(const char* __low, const char* __high, char_type* __to) const
452     {
453         return do_widen(__low, __high, __to);
454     }
455
456     _LIBCPP_ALWAYS_INLINE
457     char narrow(char_type __c, char __dfault) const
458     {
459         return do_narrow(__c, __dfault);
460     }
461
462     _LIBCPP_ALWAYS_INLINE
463     const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
464     {
465         return do_narrow(__low, __high, __dfault, __to);
466     }
467
468     static locale::id id;
469
470 protected:
471     ~ctype();
472     virtual bool do_is(mask __m, char_type __c) const;
473     virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
474     virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
475     virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
476     virtual char_type do_toupper(char_type) const;
477     virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
478     virtual char_type do_tolower(char_type) const;
479     virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
480     virtual char_type do_widen(char) const;
481     virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
482     virtual char do_narrow(char_type, char __dfault) const;
483     virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
484 };
485
486 template <>
487 class _LIBCPP_VISIBLE ctype<char>
488     : public locale::facet, public ctype_base
489 {
490     const mask* __tab_;
491     bool        __del_;
492 public:
493     typedef char char_type;
494
495     explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0);
496
497     _LIBCPP_ALWAYS_INLINE
498     bool is(mask __m, char_type __c) const
499     {
500         return isascii(__c) ? __tab_[static_cast<int>(__c)] & __m : false;
501     }
502
503     _LIBCPP_ALWAYS_INLINE
504     const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const
505     {
506         for (; __low != __high; ++__low, ++__vec)
507             *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;
508         return __low;
509     }
510
511     _LIBCPP_ALWAYS_INLINE
512     const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const
513     {
514         for (; __low != __high; ++__low)
515             if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))
516                 break;
517         return __low;
518     }
519
520     _LIBCPP_ALWAYS_INLINE
521     const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const
522     {
523         for (; __low != __high; ++__low)
524             if (!(isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m)))
525                 break;
526         return __low;
527     }
528
529     _LIBCPP_ALWAYS_INLINE
530     char_type toupper(char_type __c) const
531     {
532         return do_toupper(__c);
533     }
534
535     _LIBCPP_ALWAYS_INLINE
536     const char_type* toupper(char_type* __low, const char_type* __high) const
537     {
538         return do_toupper(__low, __high);
539     }
540
541     _LIBCPP_ALWAYS_INLINE
542     char_type tolower(char_type __c) const
543     {
544         return do_tolower(__c);
545     }
546
547     _LIBCPP_ALWAYS_INLINE
548     const char_type* tolower(char_type* __low, const char_type* __high) const
549     {
550         return do_tolower(__low, __high);
551     }
552
553     _LIBCPP_ALWAYS_INLINE
554     char_type widen(char __c) const
555     {
556         return do_widen(__c);
557     }
558
559     _LIBCPP_ALWAYS_INLINE
560     const char* widen(const char* __low, const char* __high, char_type* __to) const
561     {
562         return do_widen(__low, __high, __to);
563     }
564
565     _LIBCPP_ALWAYS_INLINE
566     char narrow(char_type __c, char __dfault) const
567     {
568         return do_narrow(__c, __dfault);
569     }
570
571     _LIBCPP_ALWAYS_INLINE
572     const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const
573     {
574         return do_narrow(__low, __high, __dfault, __to);
575     }
576
577     static locale::id id;
578
579 #ifdef _CACHED_RUNES
580     static const size_t table_size = _CACHED_RUNES;
581 #else
582     static const size_t table_size = 256;  // FIXME: Don't hardcode this.
583 #endif
584     _LIBCPP_ALWAYS_INLINE const mask* table() const  _NOEXCEPT {return __tab_;}
585     static const mask* classic_table()  _NOEXCEPT;
586 #if defined(__GLIBC__)
587     static const int* __classic_upper_table() _NOEXCEPT;
588     static const int* __classic_lower_table() _NOEXCEPT;
589 #endif
590
591 protected:
592     ~ctype();
593     virtual char_type do_toupper(char_type __c) const;
594     virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
595     virtual char_type do_tolower(char_type __c) const;
596     virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
597     virtual char_type do_widen(char __c) const;
598     virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
599     virtual char do_narrow(char_type __c, char __dfault) const;
600     virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
601 };
602
603 // template <class CharT> class ctype_byname;
604
605 template <class _CharT> class _LIBCPP_VISIBLE ctype_byname;
606
607 template <>
608 class _LIBCPP_VISIBLE ctype_byname<char>
609     : public ctype<char>
610 {
611     locale_t __l;
612
613 public:
614     explicit ctype_byname(const char*, size_t = 0);
615     explicit ctype_byname(const string&, size_t = 0);
616
617 protected:
618     ~ctype_byname();
619     virtual char_type do_toupper(char_type) const;
620     virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
621     virtual char_type do_tolower(char_type) const;
622     virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
623 };
624
625 template <>
626 class _LIBCPP_VISIBLE ctype_byname<wchar_t>
627     : public ctype<wchar_t>
628 {
629     locale_t __l;
630
631 public:
632     explicit ctype_byname(const char*, size_t = 0);
633     explicit ctype_byname(const string&, size_t = 0);
634
635 protected:
636     ~ctype_byname();
637     virtual bool do_is(mask __m, char_type __c) const;
638     virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
639     virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
640     virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
641     virtual char_type do_toupper(char_type) const;
642     virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
643     virtual char_type do_tolower(char_type) const;
644     virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
645     virtual char_type do_widen(char) const;
646     virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
647     virtual char do_narrow(char_type, char __dfault) const;
648     virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
649 };
650
651 template <class _CharT>
652 inline _LIBCPP_INLINE_VISIBILITY
653 bool
654 isspace(_CharT __c, const locale& __loc)
655 {
656     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
657 }
658
659 template <class _CharT>
660 inline _LIBCPP_INLINE_VISIBILITY
661 bool
662 isprint(_CharT __c, const locale& __loc)
663 {
664     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
665 }
666
667 template <class _CharT>
668 inline _LIBCPP_INLINE_VISIBILITY
669 bool
670 iscntrl(_CharT __c, const locale& __loc)
671 {
672     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
673 }
674
675 template <class _CharT>
676 inline _LIBCPP_INLINE_VISIBILITY
677 bool
678 isupper(_CharT __c, const locale& __loc)
679 {
680     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
681 }
682
683 template <class _CharT>
684 inline _LIBCPP_INLINE_VISIBILITY
685 bool
686 islower(_CharT __c, const locale& __loc)
687 {
688     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
689 }
690
691 template <class _CharT>
692 inline _LIBCPP_INLINE_VISIBILITY
693 bool
694 isalpha(_CharT __c, const locale& __loc)
695 {
696     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
697 }
698
699 template <class _CharT>
700 inline _LIBCPP_INLINE_VISIBILITY
701 bool
702 isdigit(_CharT __c, const locale& __loc)
703 {
704     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
705 }
706
707 template <class _CharT>
708 inline _LIBCPP_INLINE_VISIBILITY
709 bool
710 ispunct(_CharT __c, const locale& __loc)
711 {
712     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
713 }
714
715 template <class _CharT>
716 inline _LIBCPP_INLINE_VISIBILITY
717 bool
718 isxdigit(_CharT __c, const locale& __loc)
719 {
720     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
721 }
722
723 template <class _CharT>
724 inline _LIBCPP_INLINE_VISIBILITY
725 bool
726 isalnum(_CharT __c, const locale& __loc)
727 {
728     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
729 }
730
731 template <class _CharT>
732 inline _LIBCPP_INLINE_VISIBILITY
733 bool
734 isgraph(_CharT __c, const locale& __loc)
735 {
736     return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
737 }
738
739 template <class _CharT>
740 inline _LIBCPP_INLINE_VISIBILITY
741 _CharT
742 toupper(_CharT __c, const locale& __loc)
743 {
744     return use_facet<ctype<_CharT> >(__loc).toupper(__c);
745 }
746
747 template <class _CharT>
748 inline _LIBCPP_INLINE_VISIBILITY
749 _CharT
750 tolower(_CharT __c, const locale& __loc)
751 {
752     return use_facet<ctype<_CharT> >(__loc).tolower(__c);
753 }
754
755 // codecvt_base
756
757 class _LIBCPP_VISIBLE codecvt_base
758 {
759 public:
760     _LIBCPP_ALWAYS_INLINE codecvt_base() {}
761     enum result {ok, partial, error, noconv};
762 };
763
764 // template <class internT, class externT, class stateT> class codecvt;
765
766 template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_VISIBLE codecvt;
767
768 // template <> class codecvt<char, char, mbstate_t>
769
770 template <>
771 class _LIBCPP_VISIBLE codecvt<char, char, mbstate_t>
772     : public locale::facet,
773       public codecvt_base
774 {
775 public:
776     typedef char      intern_type;
777     typedef char      extern_type;
778     typedef mbstate_t state_type;
779
780     _LIBCPP_ALWAYS_INLINE
781     explicit codecvt(size_t __refs = 0)
782         : locale::facet(__refs) {}
783
784     _LIBCPP_ALWAYS_INLINE
785     result out(state_type& __st,
786                const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
787                extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
788     {
789         return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
790     }
791
792     _LIBCPP_ALWAYS_INLINE
793     result unshift(state_type& __st,
794                    extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
795     {
796         return do_unshift(__st, __to, __to_end, __to_nxt);
797     }
798
799     _LIBCPP_ALWAYS_INLINE
800     result in(state_type& __st,
801               const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
802               intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
803     {
804         return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
805     }
806
807     _LIBCPP_ALWAYS_INLINE
808     int encoding() const  _NOEXCEPT
809     {
810         return do_encoding();
811     }
812
813     _LIBCPP_ALWAYS_INLINE
814     bool always_noconv() const  _NOEXCEPT
815     {
816         return do_always_noconv();
817     }
818
819     _LIBCPP_ALWAYS_INLINE
820     int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
821     {
822         return do_length(__st, __frm, __end, __mx);
823     }
824
825     _LIBCPP_ALWAYS_INLINE
826     int max_length() const  _NOEXCEPT
827     {
828         return do_max_length();
829     }
830
831     static locale::id id;
832
833 protected:
834     _LIBCPP_ALWAYS_INLINE
835     explicit codecvt(const char*, size_t __refs = 0)
836         : locale::facet(__refs) {}
837
838     ~codecvt();
839
840     virtual result do_out(state_type& __st,
841                           const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
842                           extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
843     virtual result do_in(state_type& __st,
844                          const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
845                          intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
846     virtual result do_unshift(state_type& __st,
847                               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
848     virtual int do_encoding() const  _NOEXCEPT;
849     virtual bool do_always_noconv() const  _NOEXCEPT;
850     virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
851     virtual int do_max_length() const  _NOEXCEPT;
852 };
853
854 // template <> class codecvt<wchar_t, char, mbstate_t>
855
856 template <>
857 class _LIBCPP_VISIBLE codecvt<wchar_t, char, mbstate_t>
858     : public locale::facet,
859       public codecvt_base
860 {
861     locale_t __l;
862 public:
863     typedef wchar_t   intern_type;
864     typedef char      extern_type;
865     typedef mbstate_t state_type;
866
867     explicit codecvt(size_t __refs = 0);
868
869     _LIBCPP_ALWAYS_INLINE
870     result out(state_type& __st,
871                const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
872                extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
873     {
874         return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
875     }
876
877     _LIBCPP_ALWAYS_INLINE
878     result unshift(state_type& __st,
879                    extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
880     {
881         return do_unshift(__st, __to, __to_end, __to_nxt);
882     }
883
884     _LIBCPP_ALWAYS_INLINE
885     result in(state_type& __st,
886               const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
887               intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
888     {
889         return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
890     }
891
892     _LIBCPP_ALWAYS_INLINE
893     int encoding() const  _NOEXCEPT
894     {
895         return do_encoding();
896     }
897
898     _LIBCPP_ALWAYS_INLINE
899     bool always_noconv() const  _NOEXCEPT
900     {
901         return do_always_noconv();
902     }
903
904     _LIBCPP_ALWAYS_INLINE
905     int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
906     {
907         return do_length(__st, __frm, __end, __mx);
908     }
909
910     _LIBCPP_ALWAYS_INLINE
911     int max_length() const  _NOEXCEPT
912     {
913         return do_max_length();
914     }
915
916     static locale::id id;
917
918 protected:
919     explicit codecvt(const char*, size_t __refs = 0);
920
921     ~codecvt();
922
923     virtual result do_out(state_type& __st,
924                           const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
925                           extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
926     virtual result do_in(state_type& __st,
927                          const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
928                          intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
929     virtual result do_unshift(state_type& __st,
930                               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
931     virtual int do_encoding() const  _NOEXCEPT;
932     virtual bool do_always_noconv() const  _NOEXCEPT;
933     virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
934     virtual int do_max_length() const  _NOEXCEPT;
935 };
936
937 // template <> class codecvt<char16_t, char, mbstate_t>
938
939 template <>
940 class _LIBCPP_VISIBLE codecvt<char16_t, char, mbstate_t>
941     : public locale::facet,
942       public codecvt_base
943 {
944 public:
945     typedef char16_t  intern_type;
946     typedef char      extern_type;
947     typedef mbstate_t state_type;
948
949     _LIBCPP_ALWAYS_INLINE
950     explicit codecvt(size_t __refs = 0)
951         : locale::facet(__refs) {}
952
953     _LIBCPP_ALWAYS_INLINE
954     result out(state_type& __st,
955                const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
956                extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
957     {
958         return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
959     }
960
961     _LIBCPP_ALWAYS_INLINE
962     result unshift(state_type& __st,
963                    extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
964     {
965         return do_unshift(__st, __to, __to_end, __to_nxt);
966     }
967
968     _LIBCPP_ALWAYS_INLINE
969     result in(state_type& __st,
970               const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
971               intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
972     {
973         return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
974     }
975
976     _LIBCPP_ALWAYS_INLINE
977     int encoding() const  _NOEXCEPT
978     {
979         return do_encoding();
980     }
981
982     _LIBCPP_ALWAYS_INLINE
983     bool always_noconv() const  _NOEXCEPT
984     {
985         return do_always_noconv();
986     }
987
988     _LIBCPP_ALWAYS_INLINE
989     int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
990     {
991         return do_length(__st, __frm, __end, __mx);
992     }
993
994     _LIBCPP_ALWAYS_INLINE
995     int max_length() const  _NOEXCEPT
996     {
997         return do_max_length();
998     }
999
1000     static locale::id id;
1001
1002 protected:
1003     _LIBCPP_ALWAYS_INLINE
1004     explicit codecvt(const char*, size_t __refs = 0)
1005         : locale::facet(__refs) {}
1006
1007     ~codecvt();
1008
1009     virtual result do_out(state_type& __st,
1010                           const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1011                           extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1012     virtual result do_in(state_type& __st,
1013                          const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1014                          intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1015     virtual result do_unshift(state_type& __st,
1016                               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1017     virtual int do_encoding() const  _NOEXCEPT;
1018     virtual bool do_always_noconv() const  _NOEXCEPT;
1019     virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1020     virtual int do_max_length() const  _NOEXCEPT;
1021 };
1022
1023 // template <> class codecvt<char32_t, char, mbstate_t>
1024
1025 template <>
1026 class _LIBCPP_VISIBLE codecvt<char32_t, char, mbstate_t>
1027     : public locale::facet,
1028       public codecvt_base
1029 {
1030 public:
1031     typedef char32_t  intern_type;
1032     typedef char      extern_type;
1033     typedef mbstate_t state_type;
1034
1035     _LIBCPP_ALWAYS_INLINE
1036     explicit codecvt(size_t __refs = 0)
1037         : locale::facet(__refs) {}
1038
1039     _LIBCPP_ALWAYS_INLINE
1040     result out(state_type& __st,
1041                const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1042                extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1043     {
1044         return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1045     }
1046
1047     _LIBCPP_ALWAYS_INLINE
1048     result unshift(state_type& __st,
1049                    extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const
1050     {
1051         return do_unshift(__st, __to, __to_end, __to_nxt);
1052     }
1053
1054     _LIBCPP_ALWAYS_INLINE
1055     result in(state_type& __st,
1056               const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1057               intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const
1058     {
1059         return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1060     }
1061
1062     _LIBCPP_ALWAYS_INLINE
1063     int encoding() const  _NOEXCEPT
1064     {
1065         return do_encoding();
1066     }
1067
1068     _LIBCPP_ALWAYS_INLINE
1069     bool always_noconv() const  _NOEXCEPT
1070     {
1071         return do_always_noconv();
1072     }
1073
1074     _LIBCPP_ALWAYS_INLINE
1075     int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const
1076     {
1077         return do_length(__st, __frm, __end, __mx);
1078     }
1079
1080     _LIBCPP_ALWAYS_INLINE
1081     int max_length() const  _NOEXCEPT
1082     {
1083         return do_max_length();
1084     }
1085
1086     static locale::id id;
1087
1088 protected:
1089     _LIBCPP_ALWAYS_INLINE
1090     explicit codecvt(const char*, size_t __refs = 0)
1091         : locale::facet(__refs) {}
1092
1093     ~codecvt();
1094
1095     virtual result do_out(state_type& __st,
1096                           const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt,
1097                           extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1098     virtual result do_in(state_type& __st,
1099                          const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt,
1100                          intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const;
1101     virtual result do_unshift(state_type& __st,
1102                               extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1103     virtual int do_encoding() const  _NOEXCEPT;
1104     virtual bool do_always_noconv() const  _NOEXCEPT;
1105     virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1106     virtual int do_max_length() const  _NOEXCEPT;
1107 };
1108
1109 // template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1110
1111 template <class _InternT, class _ExternT, class _StateT>
1112 class _LIBCPP_VISIBLE codecvt_byname
1113     : public codecvt<_InternT, _ExternT, _StateT>
1114 {
1115 public:
1116     _LIBCPP_ALWAYS_INLINE
1117     explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1118         : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
1119     _LIBCPP_ALWAYS_INLINE
1120     explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1121         : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1122 protected:
1123     ~codecvt_byname();
1124 };
1125
1126 template <class _InternT, class _ExternT, class _StateT>
1127 codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname()
1128 {
1129 }
1130
1131 extern template class codecvt_byname<char, char, mbstate_t>;
1132 extern template class codecvt_byname<wchar_t, char, mbstate_t>;
1133 extern template class codecvt_byname<char16_t, char, mbstate_t>;
1134 extern template class codecvt_byname<char32_t, char, mbstate_t>;
1135
1136 _LIBCPP_VISIBLE void __throw_runtime_error(const char*);
1137
1138 template <size_t _Np>
1139 struct __narrow_to_utf8
1140 {
1141     template <class _OutputIterator, class _CharT>
1142     _OutputIterator
1143     operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1144 };
1145
1146 template <>
1147 struct __narrow_to_utf8<8>
1148 {
1149     template <class _OutputIterator, class _CharT>
1150     _LIBCPP_ALWAYS_INLINE
1151     _OutputIterator
1152     operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1153     {
1154         for (; __wb < __we; ++__wb, ++__s)
1155             *__s = *__wb;
1156         return __s;
1157     }
1158 };
1159
1160 template <>
1161 struct __narrow_to_utf8<16>
1162     : public codecvt<char16_t, char, mbstate_t>
1163 {
1164     _LIBCPP_ALWAYS_INLINE
1165     __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1166
1167     ~__narrow_to_utf8();
1168
1169     template <class _OutputIterator, class _CharT>
1170     _LIBCPP_ALWAYS_INLINE
1171     _OutputIterator
1172     operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1173     {
1174         result __r = ok;
1175         mbstate_t __mb;
1176         while (__wb < __we && __r != error)
1177         {
1178             const int __sz = 32;
1179             char __buf[__sz];
1180             char* __bn;
1181             const char16_t* __wn = (const char16_t*)__wb;
1182             __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn,
1183                          __buf, __buf+__sz, __bn);
1184             if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1185                 __throw_runtime_error("locale not supported");
1186             for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1187                 *__s = *__p;
1188             __wb = (const _CharT*)__wn;
1189         }
1190         return __s;
1191     }
1192 };
1193
1194 template <>
1195 struct __narrow_to_utf8<32>
1196     : public codecvt<char32_t, char, mbstate_t>
1197 {
1198     _LIBCPP_ALWAYS_INLINE
1199     __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1200
1201     ~__narrow_to_utf8();
1202
1203     template <class _OutputIterator, class _CharT>
1204     _LIBCPP_ALWAYS_INLINE
1205     _OutputIterator
1206     operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const
1207     {
1208         result __r = ok;
1209         mbstate_t __mb;
1210         while (__wb < __we && __r != error)
1211         {
1212             const int __sz = 32;
1213             char __buf[__sz];
1214             char* __bn;
1215             const char32_t* __wn = (const char32_t*)__wb;
1216             __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn,
1217                          __buf, __buf+__sz, __bn);
1218             if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1219                 __throw_runtime_error("locale not supported");
1220             for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1221                 *__s = *__p;
1222             __wb = (const _CharT*)__wn;
1223         }
1224         return __s;
1225     }
1226 };
1227
1228 template <size_t _Np>
1229 struct __widen_from_utf8
1230 {
1231     template <class _OutputIterator>
1232     _OutputIterator
1233     operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1234 };
1235
1236 template <>
1237 struct __widen_from_utf8<8>
1238 {
1239     template <class _OutputIterator>
1240     _LIBCPP_ALWAYS_INLINE
1241     _OutputIterator
1242     operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1243     {
1244         for (; __nb < __ne; ++__nb, ++__s)
1245             *__s = *__nb;
1246         return __s;
1247     }
1248 };
1249
1250 template <>
1251 struct __widen_from_utf8<16>
1252     : public codecvt<char16_t, char, mbstate_t>
1253 {
1254     _LIBCPP_ALWAYS_INLINE
1255     __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1256
1257     ~__widen_from_utf8();
1258
1259     template <class _OutputIterator>
1260     _LIBCPP_ALWAYS_INLINE
1261     _OutputIterator
1262     operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1263     {
1264         result __r = ok;
1265         mbstate_t __mb;
1266         while (__nb < __ne && __r != error)
1267         {
1268             const int __sz = 32;
1269             char16_t __buf[__sz];
1270             char16_t* __bn;
1271             const char* __nn = __nb;
1272             __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1273                         __buf, __buf+__sz, __bn);
1274             if (__r == codecvt_base::error || __nn == __nb)
1275                 __throw_runtime_error("locale not supported");
1276             for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1277                 *__s = (wchar_t)*__p;
1278             __nb = __nn;
1279         }
1280         return __s;
1281     }
1282 };
1283
1284 template <>
1285 struct __widen_from_utf8<32>
1286     : public codecvt<char32_t, char, mbstate_t>
1287 {
1288     _LIBCPP_ALWAYS_INLINE
1289     __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1290
1291     ~__widen_from_utf8();
1292
1293     template <class _OutputIterator>
1294     _LIBCPP_ALWAYS_INLINE
1295     _OutputIterator
1296     operator()(_OutputIterator __s, const char* __nb, const char* __ne) const
1297     {
1298         result __r = ok;
1299         mbstate_t __mb;
1300         while (__nb < __ne && __r != error)
1301         {
1302             const int __sz = 32;
1303             char32_t __buf[__sz];
1304             char32_t* __bn;
1305             const char* __nn = __nb;
1306             __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn,
1307                         __buf, __buf+__sz, __bn);
1308             if (__r == codecvt_base::error || __nn == __nb)
1309                 __throw_runtime_error("locale not supported");
1310             for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1311                 *__s = (wchar_t)*__p;
1312             __nb = __nn;
1313         }
1314         return __s;
1315     }
1316 };
1317
1318 // template <class charT> class numpunct
1319
1320 template <class _CharT> class _LIBCPP_VISIBLE numpunct;
1321
1322 template <>
1323 class _LIBCPP_VISIBLE numpunct<char>
1324     : public locale::facet
1325 {
1326 public:
1327     typedef char char_type;
1328     typedef basic_string<char_type> string_type;
1329
1330     explicit numpunct(size_t __refs = 0);
1331
1332     _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1333     _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1334     _LIBCPP_ALWAYS_INLINE string grouping() const         {return do_grouping();}
1335     _LIBCPP_ALWAYS_INLINE string_type truename() const    {return do_truename();}
1336     _LIBCPP_ALWAYS_INLINE string_type falsename() const   {return do_falsename();}
1337
1338     static locale::id id;
1339
1340 protected:
1341     ~numpunct();
1342     virtual char_type do_decimal_point() const;
1343     virtual char_type do_thousands_sep() const;
1344     virtual string do_grouping() const;
1345     virtual string_type do_truename() const;
1346     virtual string_type do_falsename() const;
1347
1348     char_type __decimal_point_;
1349     char_type __thousands_sep_;
1350     string __grouping_;
1351 };
1352
1353 template <>
1354 class _LIBCPP_VISIBLE numpunct<wchar_t>
1355     : public locale::facet
1356 {
1357 public:
1358     typedef wchar_t char_type;
1359     typedef basic_string<char_type> string_type;
1360
1361     explicit numpunct(size_t __refs = 0);
1362
1363     _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();}
1364     _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();}
1365     _LIBCPP_ALWAYS_INLINE string grouping() const         {return do_grouping();}
1366     _LIBCPP_ALWAYS_INLINE string_type truename() const    {return do_truename();}
1367     _LIBCPP_ALWAYS_INLINE string_type falsename() const   {return do_falsename();}
1368
1369     static locale::id id;
1370
1371 protected:
1372     ~numpunct();
1373     virtual char_type do_decimal_point() const;
1374     virtual char_type do_thousands_sep() const;
1375     virtual string do_grouping() const;
1376     virtual string_type do_truename() const;
1377     virtual string_type do_falsename() const;
1378
1379     char_type __decimal_point_;
1380     char_type __thousands_sep_;
1381     string __grouping_;
1382 };
1383
1384 // template <class charT> class numpunct_byname
1385
1386 template <class charT> class _LIBCPP_VISIBLE numpunct_byname;
1387
1388 template <>
1389 class _LIBCPP_VISIBLE numpunct_byname<char>
1390 : public numpunct<char>
1391 {
1392 public:
1393     typedef char char_type;
1394     typedef basic_string<char_type> string_type;
1395
1396     explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1397     explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1398
1399 protected:
1400     ~numpunct_byname();
1401
1402 private:
1403     void __init(const char*);
1404 };
1405
1406 template <>
1407 class _LIBCPP_VISIBLE numpunct_byname<wchar_t>
1408 : public numpunct<wchar_t>
1409 {
1410 public:
1411     typedef wchar_t char_type;
1412     typedef basic_string<char_type> string_type;
1413
1414     explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1415     explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1416
1417 protected:
1418     ~numpunct_byname();
1419
1420 private:
1421     void __init(const char*);
1422 };
1423
1424 _LIBCPP_END_NAMESPACE_STD
1425
1426 #endif  // _LIBCPP___LOCALE