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