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