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