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