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