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