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