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