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