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