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