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