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