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