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