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