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