[rtsan] Remove mkfifoat interceptor (#116997)
[llvm-project.git] / libcxx / include / __locale
blobb675e01bac81e5206c8681c7706a8915f8440b03
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 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___LOCALE
11 #define _LIBCPP___LOCALE
13 #include <__config>
14 #include <__locale_dir/locale_base_api.h>
15 #include <__memory/shared_count.h>
16 #include <__mutex/once_flag.h>
17 #include <__type_traits/make_unsigned.h>
18 #include <__utility/no_destroy.h>
19 #include <__utility/private_constructor_tag.h>
20 #include <cctype>
21 #include <clocale>
22 #include <cstdint>
23 #include <cstdlib>
24 #include <string>
26 // Some platforms require more includes than others. Keep the includes on all plaforms for now.
27 #include <cstddef>
28 #include <cstring>
30 #if _LIBCPP_HAS_WIDE_CHARACTERS
31 #  include <cwchar>
32 #else
33 #  include <__std_mbstate_t.h>
34 #endif
36 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
37 #  pragma GCC system_header
38 #endif
40 _LIBCPP_BEGIN_NAMESPACE_STD
42 class _LIBCPP_EXPORTED_FROM_ABI locale;
44 template <class _Facet>
45 _LIBCPP_HIDE_FROM_ABI bool has_facet(const locale&) _NOEXCEPT;
47 template <class _Facet>
48 _LIBCPP_HIDE_FROM_ABI const _Facet& use_facet(const locale&);
50 class _LIBCPP_EXPORTED_FROM_ABI locale {
51 public:
52   // locale is essentially a shared_ptr that doesn't support weak_ptrs and never got a move constructor.
53   using __trivially_relocatable = locale;
55   // types:
56   class _LIBCPP_EXPORTED_FROM_ABI facet;
57   class _LIBCPP_EXPORTED_FROM_ABI id;
59   typedef int category;
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;
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);
77   ~locale();
79   const locale& operator=(const locale&) _NOEXCEPT;
81   template <class _Facet>
82   _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS locale combine(const locale&) const;
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;
94   // global locale objects:
95   static locale global(const locale&);
96   static const locale& classic();
98 private:
99   class __imp;
100   __imp* __locale_;
102   template <class>
103   friend struct __no_destroy;
104   _LIBCPP_HIDE_FROM_ABI explicit locale(__private_constructor_tag, __imp* __loc) : __locale_(__loc) {}
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;
111   template <class _Facet>
112   friend bool has_facet(const locale&) _NOEXCEPT;
113   template <class _Facet>
114   friend const _Facet& use_facet(const locale&);
117 class _LIBCPP_EXPORTED_FROM_ABI locale::facet : public __shared_count {
118 protected:
119   _LIBCPP_HIDE_FROM_ABI explicit facet(size_t __refs = 0) : __shared_count(static_cast<long>(__refs) - 1) {}
121   ~facet() override;
123   //    facet(const facet&) = delete;     // effectively done in __shared_count
124   //    void operator=(const facet&) = delete;
126 private:
127   void __on_zero_shared() _NOEXCEPT override;
130 class _LIBCPP_EXPORTED_FROM_ABI locale::id {
131   once_flag __flag_;
132   int32_t __id_;
134   static int32_t __next_id;
136 public:
137   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR id() : __id_(0) {}
138   void operator=(const id&) = delete;
139   id(const id&)             = delete;
141 public: // only needed for tests
142   long __get();
144   friend class locale;
145   friend class locale::__imp;
148 template <class _Facet>
149 inline _LIBCPP_HIDE_FROM_ABI locale::locale(const locale& __other, _Facet* __f) {
150   __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
153 template <class _Facet>
154 locale locale::combine(const locale& __other) const {
155   if (!std::has_facet<_Facet>(__other))
156     __throw_runtime_error("locale::combine: locale missing facet");
158   return locale(*this, &const_cast<_Facet&>(std::use_facet<_Facet>(__other)));
161 template <class _Facet>
162 inline _LIBCPP_HIDE_FROM_ABI bool has_facet(const locale& __l) _NOEXCEPT {
163   return __l.has_facet(_Facet::id);
166 template <class _Facet>
167 inline _LIBCPP_HIDE_FROM_ABI const _Facet& use_facet(const locale& __l) {
168   return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
171 // template <class _CharT> class collate;
173 template <class _CharT>
174 class _LIBCPP_TEMPLATE_VIS collate : public locale::facet {
175 public:
176   typedef _CharT char_type;
177   typedef basic_string<char_type> string_type;
179   _LIBCPP_HIDE_FROM_ABI explicit collate(size_t __refs = 0) : locale::facet(__refs) {}
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   }
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   }
193   _LIBCPP_HIDE_FROM_ABI long hash(const char_type* __lo, const char_type* __hi) const { return do_hash(__lo, __hi); }
195   static locale::id id;
197 protected:
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;
207 template <class _CharT>
208 locale::id collate<_CharT>::id;
210 template <class _CharT>
211 collate<_CharT>::~collate() {}
213 template <class _CharT>
214 int 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;
225 template <class _CharT>
226 long 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);
238 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<char>;
239 #if _LIBCPP_HAS_WIDE_CHARACTERS
240 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>;
241 #endif
243 // template <class CharT> class collate_byname;
245 template <class _CharT>
246 class _LIBCPP_TEMPLATE_VIS collate_byname;
248 template <>
249 class _LIBCPP_EXPORTED_FROM_ABI collate_byname<char> : public collate<char> {
250   __locale::__locale_t __l_;
252 public:
253   typedef char char_type;
254   typedef basic_string<char_type> string_type;
256   explicit collate_byname(const char* __n, size_t __refs = 0);
257   explicit collate_byname(const string& __n, size_t __refs = 0);
259 protected:
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;
266 #if _LIBCPP_HAS_WIDE_CHARACTERS
267 template <>
268 class _LIBCPP_EXPORTED_FROM_ABI collate_byname<wchar_t> : public collate<wchar_t> {
269   __locale::__locale_t __l_;
271 public:
272   typedef wchar_t char_type;
273   typedef basic_string<char_type> string_type;
275   explicit collate_byname(const char* __n, size_t __refs = 0);
276   explicit collate_byname(const string& __n, size_t __refs = 0);
278 protected:
279   ~collate_byname() override;
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;
285 #endif
287 template <class _CharT, class _Traits, class _Allocator>
288 bool 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;
294 // template <class charT> class ctype
296 class _LIBCPP_EXPORTED_FROM_ABI ctype_base {
297 public:
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;
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;
442   _LIBCPP_HIDE_FROM_ABI ctype_base() {}
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");
449 template <class _CharT>
450 class _LIBCPP_TEMPLATE_VIS ctype;
452 #if _LIBCPP_HAS_WIDE_CHARACTERS
453 template <>
454 class _LIBCPP_EXPORTED_FROM_ABI ctype<wchar_t> : public locale::facet, public ctype_base {
455 public:
456   typedef wchar_t char_type;
458   _LIBCPP_HIDE_FROM_ABI explicit ctype(size_t __refs = 0) : locale::facet(__refs) {}
460   _LIBCPP_HIDE_FROM_ABI bool is(mask __m, char_type __c) const { return do_is(__m, __c); }
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   }
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   }
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   }
474   _LIBCPP_HIDE_FROM_ABI char_type toupper(char_type __c) const { return do_toupper(__c); }
476   _LIBCPP_HIDE_FROM_ABI const char_type* toupper(char_type* __low, const char_type* __high) const {
477     return do_toupper(__low, __high);
478   }
480   _LIBCPP_HIDE_FROM_ABI char_type tolower(char_type __c) const { return do_tolower(__c); }
482   _LIBCPP_HIDE_FROM_ABI const char_type* tolower(char_type* __low, const char_type* __high) const {
483     return do_tolower(__low, __high);
484   }
486   _LIBCPP_HIDE_FROM_ABI char_type widen(char __c) const { return do_widen(__c); }
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   }
492   _LIBCPP_HIDE_FROM_ABI char narrow(char_type __c, char __dfault) const { return do_narrow(__c, __dfault); }
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   }
499   static locale::id id;
501 protected:
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;
517 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
519 template <>
520 class _LIBCPP_EXPORTED_FROM_ABI ctype<char> : public locale::facet, public ctype_base {
521   const mask* __tab_;
522   bool __del_;
524 public:
525   typedef char char_type;
527   explicit ctype(const mask* __tab = nullptr, bool __del = false, size_t __refs = 0);
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   }
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   }
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   }
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   }
553   _LIBCPP_HIDE_FROM_ABI char_type toupper(char_type __c) const { return do_toupper(__c); }
555   _LIBCPP_HIDE_FROM_ABI const char_type* toupper(char_type* __low, const char_type* __high) const {
556     return do_toupper(__low, __high);
557   }
559   _LIBCPP_HIDE_FROM_ABI char_type tolower(char_type __c) const { return do_tolower(__c); }
561   _LIBCPP_HIDE_FROM_ABI const char_type* tolower(char_type* __low, const char_type* __high) const {
562     return do_tolower(__low, __high);
563   }
565   _LIBCPP_HIDE_FROM_ABI char_type widen(char __c) const { return do_widen(__c); }
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   }
571   _LIBCPP_HIDE_FROM_ABI char narrow(char_type __c, char __dfault) const { return do_narrow(__c, __dfault); }
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   }
578   static locale::id id;
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
600 protected:
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;
612 // template <class CharT> class ctype_byname;
614 template <class _CharT>
615 class _LIBCPP_TEMPLATE_VIS ctype_byname;
617 template <>
618 class _LIBCPP_EXPORTED_FROM_ABI ctype_byname<char> : public ctype<char> {
619   __locale::__locale_t __l_;
621 public:
622   explicit ctype_byname(const char*, size_t = 0);
623   explicit ctype_byname(const string&, size_t = 0);
625 protected:
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;
633 #if _LIBCPP_HAS_WIDE_CHARACTERS
634 template <>
635 class _LIBCPP_EXPORTED_FROM_ABI ctype_byname<wchar_t> : public ctype<wchar_t> {
636   __locale::__locale_t __l_;
638 public:
639   explicit ctype_byname(const char*, size_t = 0);
640   explicit ctype_byname(const string&, size_t = 0);
642 protected:
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;
658 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
660 template <class _CharT>
661 inline _LIBCPP_HIDE_FROM_ABI bool isspace(_CharT __c, const locale& __loc) {
662   return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
665 template <class _CharT>
666 inline _LIBCPP_HIDE_FROM_ABI bool isprint(_CharT __c, const locale& __loc) {
667   return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
670 template <class _CharT>
671 inline _LIBCPP_HIDE_FROM_ABI bool iscntrl(_CharT __c, const locale& __loc) {
672   return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
675 template <class _CharT>
676 inline _LIBCPP_HIDE_FROM_ABI bool isupper(_CharT __c, const locale& __loc) {
677   return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
680 template <class _CharT>
681 inline _LIBCPP_HIDE_FROM_ABI bool islower(_CharT __c, const locale& __loc) {
682   return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
685 template <class _CharT>
686 inline _LIBCPP_HIDE_FROM_ABI bool isalpha(_CharT __c, const locale& __loc) {
687   return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
690 template <class _CharT>
691 inline _LIBCPP_HIDE_FROM_ABI bool isdigit(_CharT __c, const locale& __loc) {
692   return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
695 template <class _CharT>
696 inline _LIBCPP_HIDE_FROM_ABI bool ispunct(_CharT __c, const locale& __loc) {
697   return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
700 template <class _CharT>
701 inline _LIBCPP_HIDE_FROM_ABI bool isxdigit(_CharT __c, const locale& __loc) {
702   return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
705 template <class _CharT>
706 inline _LIBCPP_HIDE_FROM_ABI bool isalnum(_CharT __c, const locale& __loc) {
707   return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
710 template <class _CharT>
711 inline _LIBCPP_HIDE_FROM_ABI bool isgraph(_CharT __c, const locale& __loc) {
712   return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
715 template <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);
720 template <class _CharT>
721 inline _LIBCPP_HIDE_FROM_ABI _CharT toupper(_CharT __c, const locale& __loc) {
722   return std::use_facet<ctype<_CharT> >(__loc).toupper(__c);
725 template <class _CharT>
726 inline _LIBCPP_HIDE_FROM_ABI _CharT tolower(_CharT __c, const locale& __loc) {
727   return std::use_facet<ctype<_CharT> >(__loc).tolower(__c);
730 // codecvt_base
732 class _LIBCPP_EXPORTED_FROM_ABI codecvt_base {
733 public:
734   _LIBCPP_HIDE_FROM_ABI codecvt_base() {}
735   enum result { ok, partial, error, noconv };
738 // template <class internT, class externT, class stateT> class codecvt;
740 template <class _InternT, class _ExternT, class _StateT>
741 class _LIBCPP_TEMPLATE_VIS codecvt;
743 // template <> class codecvt<char, char, mbstate_t>
745 template <>
746 class _LIBCPP_EXPORTED_FROM_ABI codecvt<char, char, mbstate_t> : public locale::facet, public codecvt_base {
747 public:
748   typedef char intern_type;
749   typedef char extern_type;
750   typedef mbstate_t state_type;
752   _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
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   }
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   }
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   }
781   _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
783   _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
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   }
790   _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
792   static locale::id id;
794 protected:
795   _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {}
797   ~codecvt() override;
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;
822 // template <> class codecvt<wchar_t, char, mbstate_t>
824 #if _LIBCPP_HAS_WIDE_CHARACTERS
825 template <>
826 class _LIBCPP_EXPORTED_FROM_ABI codecvt<wchar_t, char, mbstate_t> : public locale::facet, public codecvt_base {
827   __locale::__locale_t __l_;
829 public:
830   typedef wchar_t intern_type;
831   typedef char extern_type;
832   typedef mbstate_t state_type;
834   explicit codecvt(size_t __refs = 0);
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   }
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   }
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   }
863   _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
865   _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
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   }
872   _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
874   static locale::id id;
876 protected:
877   explicit codecvt(const char*, size_t __refs = 0);
879   ~codecvt() override;
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;
903 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
905 // template <> class codecvt<char16_t, char, mbstate_t> // deprecated in C++20
907 template <>
908 class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXPORTED_FROM_ABI codecvt<char16_t, char, mbstate_t>
909     : public locale::facet, public codecvt_base {
910 public:
911   typedef char16_t intern_type;
912   typedef char extern_type;
913   typedef mbstate_t state_type;
915   _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
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   }
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   }
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   }
944   _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
946   _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
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   }
953   _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
955   static locale::id id;
957 protected:
958   _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {}
960   ~codecvt() override;
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;
985 #if _LIBCPP_HAS_CHAR8_T
987 // template <> class codecvt<char16_t, char8_t, mbstate_t> // C++20
989 template <>
990 class _LIBCPP_EXPORTED_FROM_ABI codecvt<char16_t, char8_t, mbstate_t> : public locale::facet, public codecvt_base {
991 public:
992   typedef char16_t intern_type;
993   typedef char8_t extern_type;
994   typedef mbstate_t state_type;
996   _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
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   }
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   }
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   }
1025   _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
1027   _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
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   }
1034   _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
1036   static locale::id id;
1038 protected:
1039   _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {}
1041   ~codecvt() override;
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;
1066 #endif
1068 // template <> class codecvt<char32_t, char, mbstate_t> // deprecated in C++20
1070 template <>
1071 class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXPORTED_FROM_ABI codecvt<char32_t, char, mbstate_t>
1072     : public locale::facet, public codecvt_base {
1073 public:
1074   typedef char32_t intern_type;
1075   typedef char extern_type;
1076   typedef mbstate_t state_type;
1078   _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
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   }
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   }
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   }
1107   _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
1109   _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
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   }
1116   _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
1118   static locale::id id;
1120 protected:
1121   _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {}
1123   ~codecvt() override;
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;
1148 #if _LIBCPP_HAS_CHAR8_T
1150 // template <> class codecvt<char32_t, char8_t, mbstate_t> // C++20
1152 template <>
1153 class _LIBCPP_EXPORTED_FROM_ABI codecvt<char32_t, char8_t, mbstate_t> : public locale::facet, public codecvt_base {
1154 public:
1155   typedef char32_t intern_type;
1156   typedef char8_t extern_type;
1157   typedef mbstate_t state_type;
1159   _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
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   }
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   }
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   }
1188   _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
1190   _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
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   }
1197   _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
1199   static locale::id id;
1201 protected:
1202   _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {}
1204   ~codecvt() override;
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;
1229 #endif
1231 // template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1233 template <class _InternT, class _ExternT, class _StateT>
1234 class _LIBCPP_TEMPLATE_VIS codecvt_byname : public codecvt<_InternT, _ExternT, _StateT> {
1235 public:
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) {}
1241 protected:
1242   ~codecvt_byname() override;
1245 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1246 template <class _InternT, class _ExternT, class _StateT>
1247 codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname() {}
1248 _LIBCPP_SUPPRESS_DEPRECATED_POP
1250 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>;
1251 #if _LIBCPP_HAS_WIDE_CHARACTERS
1252 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>;
1253 #endif
1254 extern template class _LIBCPP_DEPRECATED_IN_CXX20
1255 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>; // deprecated in C++20
1256 extern template class _LIBCPP_DEPRECATED_IN_CXX20
1257 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>; // deprecated in C++20
1258 #if _LIBCPP_HAS_CHAR8_T
1259 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char8_t, mbstate_t>; // C++20
1260 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char8_t, mbstate_t>; // C++20
1261 #endif
1263 template <size_t _Np>
1264 struct __narrow_to_utf8 {
1265   template <class _OutputIterator, class _CharT>
1266   _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1269 template <>
1270 struct __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   }
1279 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1280 template <>
1281 struct _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
1285   ~__narrow_to_utf8() override;
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   }
1307 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1308 template <>
1309 struct _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
1313   ~__narrow_to_utf8() override;
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   }
1335 template <size_t _Np>
1336 struct __widen_from_utf8 {
1337   template <class _OutputIterator>
1338   _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1341 template <>
1342 struct __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   }
1351 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1352 template <>
1353 struct _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
1357   ~__widen_from_utf8() override;
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   }
1379 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1380 template <>
1381 struct _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
1385   ~__widen_from_utf8() override;
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   }
1407 // template <class charT> class numpunct
1409 template <class _CharT>
1410 class _LIBCPP_TEMPLATE_VIS numpunct;
1412 template <>
1413 class _LIBCPP_EXPORTED_FROM_ABI numpunct<char> : public locale::facet {
1414 public:
1415   typedef char char_type;
1416   typedef basic_string<char_type> string_type;
1418   explicit numpunct(size_t __refs = 0);
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(); }
1426   static locale::id id;
1428 protected:
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;
1436   char_type __decimal_point_;
1437   char_type __thousands_sep_;
1438   string __grouping_;
1441 #if _LIBCPP_HAS_WIDE_CHARACTERS
1442 template <>
1443 class _LIBCPP_EXPORTED_FROM_ABI numpunct<wchar_t> : public locale::facet {
1444 public:
1445   typedef wchar_t char_type;
1446   typedef basic_string<char_type> string_type;
1448   explicit numpunct(size_t __refs = 0);
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(); }
1456   static locale::id id;
1458 protected:
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;
1466   char_type __decimal_point_;
1467   char_type __thousands_sep_;
1468   string __grouping_;
1470 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
1472 // template <class charT> class numpunct_byname
1474 template <class _CharT>
1475 class _LIBCPP_TEMPLATE_VIS numpunct_byname;
1477 template <>
1478 class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<char> : public numpunct<char> {
1479 public:
1480   typedef char char_type;
1481   typedef basic_string<char_type> string_type;
1483   explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1484   explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1486 protected:
1487   ~numpunct_byname() override;
1489 private:
1490   void __init(const char*);
1493 #if _LIBCPP_HAS_WIDE_CHARACTERS
1494 template <>
1495 class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<wchar_t> : public numpunct<wchar_t> {
1496 public:
1497   typedef wchar_t char_type;
1498   typedef basic_string<char_type> string_type;
1500   explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1501   explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1503 protected:
1504   ~numpunct_byname() override;
1506 private:
1507   void __init(const char*);
1509 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
1511 _LIBCPP_END_NAMESPACE_STD
1513 #endif // _LIBCPP___LOCALE