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