master
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, __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, __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(*__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(*__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(*__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
593protected:
594 ~ctype() override;
595 virtual char_type do_toupper(char_type __c) const;
596 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
597 virtual char_type do_tolower(char_type __c) const;
598 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
599 virtual char_type do_widen(char __c) const;
600 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
601 virtual char do_narrow(char_type __c, char __dfault) const;
602 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
603};
604
605// template <class CharT> class ctype_byname;
606
607template <class _CharT>
608class ctype_byname;
609
610template <>
611class _LIBCPP_EXPORTED_FROM_ABI ctype_byname<char> : public ctype<char> {
612 __locale::__locale_t __l_;
613
614public:
615 explicit ctype_byname(const char*, size_t = 0);
616 explicit ctype_byname(const string&, size_t = 0);
617
618protected:
619 ~ctype_byname() override;
620 char_type do_toupper(char_type) const override;
621 const char_type* do_toupper(char_type* __low, const char_type* __high) const override;
622 char_type do_tolower(char_type) const override;
623 const char_type* do_tolower(char_type* __low, const char_type* __high) const override;
624};
625
626# if _LIBCPP_HAS_WIDE_CHARACTERS
627template <>
628class _LIBCPP_EXPORTED_FROM_ABI ctype_byname<wchar_t> : public ctype<wchar_t> {
629 __locale::__locale_t __l_;
630
631public:
632 explicit ctype_byname(const char*, size_t = 0);
633 explicit ctype_byname(const string&, size_t = 0);
634
635protected:
636 ~ctype_byname() override;
637 bool do_is(mask __m, char_type __c) const override;
638 const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const override;
639 const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const override;
640 const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const override;
641 char_type do_toupper(char_type) const override;
642 const char_type* do_toupper(char_type* __low, const char_type* __high) const override;
643 char_type do_tolower(char_type) const override;
644 const char_type* do_tolower(char_type* __low, const char_type* __high) const override;
645 char_type do_widen(char) const override;
646 const char* do_widen(const char* __low, const char* __high, char_type* __dest) const override;
647 char do_narrow(char_type, char __dfault) const override;
648 const char_type*
649 do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const override;
650};
651# endif // _LIBCPP_HAS_WIDE_CHARACTERS
652
653template <class _CharT>
654inline _LIBCPP_HIDE_FROM_ABI bool isspace(_CharT __c, const locale& __loc) {
655 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
656}
657
658template <class _CharT>
659inline _LIBCPP_HIDE_FROM_ABI bool isprint(_CharT __c, const locale& __loc) {
660 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
661}
662
663template <class _CharT>
664inline _LIBCPP_HIDE_FROM_ABI bool iscntrl(_CharT __c, const locale& __loc) {
665 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
666}
667
668template <class _CharT>
669inline _LIBCPP_HIDE_FROM_ABI bool isupper(_CharT __c, const locale& __loc) {
670 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
671}
672
673template <class _CharT>
674inline _LIBCPP_HIDE_FROM_ABI bool islower(_CharT __c, const locale& __loc) {
675 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
676}
677
678template <class _CharT>
679inline _LIBCPP_HIDE_FROM_ABI bool isalpha(_CharT __c, const locale& __loc) {
680 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
681}
682
683template <class _CharT>
684inline _LIBCPP_HIDE_FROM_ABI bool isdigit(_CharT __c, const locale& __loc) {
685 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
686}
687
688template <class _CharT>
689inline _LIBCPP_HIDE_FROM_ABI bool ispunct(_CharT __c, const locale& __loc) {
690 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
691}
692
693template <class _CharT>
694inline _LIBCPP_HIDE_FROM_ABI bool isxdigit(_CharT __c, const locale& __loc) {
695 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
696}
697
698template <class _CharT>
699inline _LIBCPP_HIDE_FROM_ABI bool isalnum(_CharT __c, const locale& __loc) {
700 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
701}
702
703template <class _CharT>
704inline _LIBCPP_HIDE_FROM_ABI bool isgraph(_CharT __c, const locale& __loc) {
705 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
706}
707
708template <class _CharT>
709_LIBCPP_HIDE_FROM_ABI bool isblank(_CharT __c, const locale& __loc) {
710 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::blank, __c);
711}
712
713template <class _CharT>
714inline _LIBCPP_HIDE_FROM_ABI _CharT toupper(_CharT __c, const locale& __loc) {
715 return std::use_facet<ctype<_CharT> >(__loc).toupper(__c);
716}
717
718template <class _CharT>
719inline _LIBCPP_HIDE_FROM_ABI _CharT tolower(_CharT __c, const locale& __loc) {
720 return std::use_facet<ctype<_CharT> >(__loc).tolower(__c);
721}
722
723// codecvt_base
724
725class _LIBCPP_EXPORTED_FROM_ABI codecvt_base {
726public:
727 _LIBCPP_HIDE_FROM_ABI codecvt_base() {}
728 enum result { ok, partial, error, noconv };
729};
730
731// template <class internT, class externT, class stateT> class codecvt;
732
733template <class _InternT, class _ExternT, class _StateT>
734class codecvt;
735
736// template <> class codecvt<char, char, mbstate_t>
737
738template <>
739class _LIBCPP_EXPORTED_FROM_ABI codecvt<char, char, mbstate_t> : public locale::facet, public codecvt_base {
740public:
741 typedef char intern_type;
742 typedef char extern_type;
743 typedef mbstate_t state_type;
744
745 _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
746
747 _LIBCPP_HIDE_FROM_ABI result
748 out(state_type& __st,
749 const intern_type* __frm,
750 const intern_type* __frm_end,
751 const intern_type*& __frm_nxt,
752 extern_type* __to,
753 extern_type* __to_end,
754 extern_type*& __to_nxt) const {
755 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
756 }
757
758 _LIBCPP_HIDE_FROM_ABI result
759 unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const {
760 return do_unshift(__st, __to, __to_end, __to_nxt);
761 }
762
763 _LIBCPP_HIDE_FROM_ABI result
764 in(state_type& __st,
765 const extern_type* __frm,
766 const extern_type* __frm_end,
767 const extern_type*& __frm_nxt,
768 intern_type* __to,
769 intern_type* __to_end,
770 intern_type*& __to_nxt) const {
771 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
772 }
773
774 _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
775
776 _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
777
778 _LIBCPP_HIDE_FROM_ABI int
779 length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const {
780 return do_length(__st, __frm, __end, __mx);
781 }
782
783 _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
784
785 static locale::id id;
786
787protected:
788 _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {}
789
790 ~codecvt() override;
791
792 virtual result
793 do_out(state_type& __st,
794 const intern_type* __frm,
795 const intern_type* __frm_end,
796 const intern_type*& __frm_nxt,
797 extern_type* __to,
798 extern_type* __to_end,
799 extern_type*& __to_nxt) const;
800 virtual result
801 do_in(state_type& __st,
802 const extern_type* __frm,
803 const extern_type* __frm_end,
804 const extern_type*& __frm_nxt,
805 intern_type* __to,
806 intern_type* __to_end,
807 intern_type*& __to_nxt) const;
808 virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
809 virtual int do_encoding() const _NOEXCEPT;
810 virtual bool do_always_noconv() const _NOEXCEPT;
811 virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
812 virtual int do_max_length() const _NOEXCEPT;
813};
814
815// template <> class codecvt<wchar_t, char, mbstate_t>
816
817# if _LIBCPP_HAS_WIDE_CHARACTERS
818template <>
819class _LIBCPP_EXPORTED_FROM_ABI codecvt<wchar_t, char, mbstate_t> : public locale::facet, public codecvt_base {
820 __locale::__locale_t __l_;
821
822public:
823 typedef wchar_t intern_type;
824 typedef char extern_type;
825 typedef mbstate_t state_type;
826
827 explicit codecvt(size_t __refs = 0);
828
829 _LIBCPP_HIDE_FROM_ABI result
830 out(state_type& __st,
831 const intern_type* __frm,
832 const intern_type* __frm_end,
833 const intern_type*& __frm_nxt,
834 extern_type* __to,
835 extern_type* __to_end,
836 extern_type*& __to_nxt) const {
837 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
838 }
839
840 _LIBCPP_HIDE_FROM_ABI result
841 unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const {
842 return do_unshift(__st, __to, __to_end, __to_nxt);
843 }
844
845 _LIBCPP_HIDE_FROM_ABI result
846 in(state_type& __st,
847 const extern_type* __frm,
848 const extern_type* __frm_end,
849 const extern_type*& __frm_nxt,
850 intern_type* __to,
851 intern_type* __to_end,
852 intern_type*& __to_nxt) const {
853 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
854 }
855
856 _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
857
858 _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
859
860 _LIBCPP_HIDE_FROM_ABI int
861 length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const {
862 return do_length(__st, __frm, __end, __mx);
863 }
864
865 _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
866
867 static locale::id id;
868
869protected:
870 explicit codecvt(const char*, size_t __refs = 0);
871
872 ~codecvt() override;
873
874 virtual result
875 do_out(state_type& __st,
876 const intern_type* __frm,
877 const intern_type* __frm_end,
878 const intern_type*& __frm_nxt,
879 extern_type* __to,
880 extern_type* __to_end,
881 extern_type*& __to_nxt) const;
882 virtual result
883 do_in(state_type& __st,
884 const extern_type* __frm,
885 const extern_type* __frm_end,
886 const extern_type*& __frm_nxt,
887 intern_type* __to,
888 intern_type* __to_end,
889 intern_type*& __to_nxt) const;
890 virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
891 virtual int do_encoding() const _NOEXCEPT;
892 virtual bool do_always_noconv() const _NOEXCEPT;
893 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
894 virtual int do_max_length() const _NOEXCEPT;
895};
896# endif // _LIBCPP_HAS_WIDE_CHARACTERS
897
898// template <> class codecvt<char16_t, char, mbstate_t> // deprecated in C++20
899
900template <>
901class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXPORTED_FROM_ABI codecvt<char16_t, char, mbstate_t>
902 : public locale::facet, public codecvt_base {
903public:
904 typedef char16_t intern_type;
905 typedef char extern_type;
906 typedef mbstate_t state_type;
907
908 _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
909
910 _LIBCPP_HIDE_FROM_ABI result
911 out(state_type& __st,
912 const intern_type* __frm,
913 const intern_type* __frm_end,
914 const intern_type*& __frm_nxt,
915 extern_type* __to,
916 extern_type* __to_end,
917 extern_type*& __to_nxt) const {
918 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
919 }
920
921 _LIBCPP_HIDE_FROM_ABI result
922 unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const {
923 return do_unshift(__st, __to, __to_end, __to_nxt);
924 }
925
926 _LIBCPP_HIDE_FROM_ABI result
927 in(state_type& __st,
928 const extern_type* __frm,
929 const extern_type* __frm_end,
930 const extern_type*& __frm_nxt,
931 intern_type* __to,
932 intern_type* __to_end,
933 intern_type*& __to_nxt) const {
934 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
935 }
936
937 _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
938
939 _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
940
941 _LIBCPP_HIDE_FROM_ABI int
942 length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const {
943 return do_length(__st, __frm, __end, __mx);
944 }
945
946 _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
947
948 static locale::id id;
949
950protected:
951 _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {}
952
953 ~codecvt() override;
954
955 virtual result
956 do_out(state_type& __st,
957 const intern_type* __frm,
958 const intern_type* __frm_end,
959 const intern_type*& __frm_nxt,
960 extern_type* __to,
961 extern_type* __to_end,
962 extern_type*& __to_nxt) const;
963 virtual result
964 do_in(state_type& __st,
965 const extern_type* __frm,
966 const extern_type* __frm_end,
967 const extern_type*& __frm_nxt,
968 intern_type* __to,
969 intern_type* __to_end,
970 intern_type*& __to_nxt) const;
971 virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
972 virtual int do_encoding() const _NOEXCEPT;
973 virtual bool do_always_noconv() const _NOEXCEPT;
974 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
975 virtual int do_max_length() const _NOEXCEPT;
976};
977
978# if _LIBCPP_HAS_CHAR8_T
979
980// template <> class codecvt<char16_t, char8_t, mbstate_t> // C++20
981
982template <>
983class _LIBCPP_EXPORTED_FROM_ABI codecvt<char16_t, char8_t, mbstate_t> : public locale::facet, public codecvt_base {
984public:
985 typedef char16_t intern_type;
986 typedef char8_t extern_type;
987 typedef mbstate_t state_type;
988
989 _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
990
991 _LIBCPP_HIDE_FROM_ABI result
992 out(state_type& __st,
993 const intern_type* __frm,
994 const intern_type* __frm_end,
995 const intern_type*& __frm_nxt,
996 extern_type* __to,
997 extern_type* __to_end,
998 extern_type*& __to_nxt) const {
999 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1000 }
1001
1002 _LIBCPP_HIDE_FROM_ABI result
1003 unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const {
1004 return do_unshift(__st, __to, __to_end, __to_nxt);
1005 }
1006
1007 _LIBCPP_HIDE_FROM_ABI result
1008 in(state_type& __st,
1009 const extern_type* __frm,
1010 const extern_type* __frm_end,
1011 const extern_type*& __frm_nxt,
1012 intern_type* __to,
1013 intern_type* __to_end,
1014 intern_type*& __to_nxt) const {
1015 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1016 }
1017
1018 _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
1019
1020 _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
1021
1022 _LIBCPP_HIDE_FROM_ABI int
1023 length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const {
1024 return do_length(__st, __frm, __end, __mx);
1025 }
1026
1027 _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
1028
1029 static locale::id id;
1030
1031protected:
1032 _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {}
1033
1034 ~codecvt() override;
1035
1036 virtual result
1037 do_out(state_type& __st,
1038 const intern_type* __frm,
1039 const intern_type* __frm_end,
1040 const intern_type*& __frm_nxt,
1041 extern_type* __to,
1042 extern_type* __to_end,
1043 extern_type*& __to_nxt) const;
1044 virtual result
1045 do_in(state_type& __st,
1046 const extern_type* __frm,
1047 const extern_type* __frm_end,
1048 const extern_type*& __frm_nxt,
1049 intern_type* __to,
1050 intern_type* __to_end,
1051 intern_type*& __to_nxt) const;
1052 virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1053 virtual int do_encoding() const _NOEXCEPT;
1054 virtual bool do_always_noconv() const _NOEXCEPT;
1055 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1056 virtual int do_max_length() const _NOEXCEPT;
1057};
1058
1059# endif
1060
1061// template <> class codecvt<char32_t, char, mbstate_t> // deprecated in C++20
1062
1063template <>
1064class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXPORTED_FROM_ABI codecvt<char32_t, char, mbstate_t>
1065 : public locale::facet, public codecvt_base {
1066public:
1067 typedef char32_t intern_type;
1068 typedef char extern_type;
1069 typedef mbstate_t state_type;
1070
1071 _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
1072
1073 _LIBCPP_HIDE_FROM_ABI result
1074 out(state_type& __st,
1075 const intern_type* __frm,
1076 const intern_type* __frm_end,
1077 const intern_type*& __frm_nxt,
1078 extern_type* __to,
1079 extern_type* __to_end,
1080 extern_type*& __to_nxt) const {
1081 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1082 }
1083
1084 _LIBCPP_HIDE_FROM_ABI result
1085 unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const {
1086 return do_unshift(__st, __to, __to_end, __to_nxt);
1087 }
1088
1089 _LIBCPP_HIDE_FROM_ABI result
1090 in(state_type& __st,
1091 const extern_type* __frm,
1092 const extern_type* __frm_end,
1093 const extern_type*& __frm_nxt,
1094 intern_type* __to,
1095 intern_type* __to_end,
1096 intern_type*& __to_nxt) const {
1097 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1098 }
1099
1100 _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
1101
1102 _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
1103
1104 _LIBCPP_HIDE_FROM_ABI int
1105 length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const {
1106 return do_length(__st, __frm, __end, __mx);
1107 }
1108
1109 _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
1110
1111 static locale::id id;
1112
1113protected:
1114 _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {}
1115
1116 ~codecvt() override;
1117
1118 virtual result
1119 do_out(state_type& __st,
1120 const intern_type* __frm,
1121 const intern_type* __frm_end,
1122 const intern_type*& __frm_nxt,
1123 extern_type* __to,
1124 extern_type* __to_end,
1125 extern_type*& __to_nxt) const;
1126 virtual result
1127 do_in(state_type& __st,
1128 const extern_type* __frm,
1129 const extern_type* __frm_end,
1130 const extern_type*& __frm_nxt,
1131 intern_type* __to,
1132 intern_type* __to_end,
1133 intern_type*& __to_nxt) const;
1134 virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1135 virtual int do_encoding() const _NOEXCEPT;
1136 virtual bool do_always_noconv() const _NOEXCEPT;
1137 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1138 virtual int do_max_length() const _NOEXCEPT;
1139};
1140
1141# if _LIBCPP_HAS_CHAR8_T
1142
1143// template <> class codecvt<char32_t, char8_t, mbstate_t> // C++20
1144
1145template <>
1146class _LIBCPP_EXPORTED_FROM_ABI codecvt<char32_t, char8_t, mbstate_t> : public locale::facet, public codecvt_base {
1147public:
1148 typedef char32_t intern_type;
1149 typedef char8_t extern_type;
1150 typedef mbstate_t state_type;
1151
1152 _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
1153
1154 _LIBCPP_HIDE_FROM_ABI result
1155 out(state_type& __st,
1156 const intern_type* __frm,
1157 const intern_type* __frm_end,
1158 const intern_type*& __frm_nxt,
1159 extern_type* __to,
1160 extern_type* __to_end,
1161 extern_type*& __to_nxt) const {
1162 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1163 }
1164
1165 _LIBCPP_HIDE_FROM_ABI result
1166 unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const {
1167 return do_unshift(__st, __to, __to_end, __to_nxt);
1168 }
1169
1170 _LIBCPP_HIDE_FROM_ABI result
1171 in(state_type& __st,
1172 const extern_type* __frm,
1173 const extern_type* __frm_end,
1174 const extern_type*& __frm_nxt,
1175 intern_type* __to,
1176 intern_type* __to_end,
1177 intern_type*& __to_nxt) const {
1178 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1179 }
1180
1181 _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
1182
1183 _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
1184
1185 _LIBCPP_HIDE_FROM_ABI int
1186 length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const {
1187 return do_length(__st, __frm, __end, __mx);
1188 }
1189
1190 _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
1191
1192 static locale::id id;
1193
1194protected:
1195 _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {}
1196
1197 ~codecvt() override;
1198
1199 virtual result
1200 do_out(state_type& __st,
1201 const intern_type* __frm,
1202 const intern_type* __frm_end,
1203 const intern_type*& __frm_nxt,
1204 extern_type* __to,
1205 extern_type* __to_end,
1206 extern_type*& __to_nxt) const;
1207 virtual result
1208 do_in(state_type& __st,
1209 const extern_type* __frm,
1210 const extern_type* __frm_end,
1211 const extern_type*& __frm_nxt,
1212 intern_type* __to,
1213 intern_type* __to_end,
1214 intern_type*& __to_nxt) const;
1215 virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1216 virtual int do_encoding() const _NOEXCEPT;
1217 virtual bool do_always_noconv() const _NOEXCEPT;
1218 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1219 virtual int do_max_length() const _NOEXCEPT;
1220};
1221
1222# endif
1223
1224// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1225
1226template <class _InternT, class _ExternT, class _StateT>
1227class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT> {
1228public:
1229 _LIBCPP_HIDE_FROM_ABI explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1230 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
1231 _LIBCPP_HIDE_FROM_ABI explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1232 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1233
1234protected:
1235 ~codecvt_byname() override;
1236};
1237
1238_LIBCPP_SUPPRESS_DEPRECATED_PUSH
1239template <class _InternT, class _ExternT, class _StateT>
1240codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname() {}
1241_LIBCPP_SUPPRESS_DEPRECATED_POP
1242
1243extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>;
1244# if _LIBCPP_HAS_WIDE_CHARACTERS
1245extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>;
1246# endif
1247extern template class _LIBCPP_DEPRECATED_IN_CXX20
1248_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>; // deprecated in C++20
1249extern template class _LIBCPP_DEPRECATED_IN_CXX20
1250_LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>; // deprecated in C++20
1251# if _LIBCPP_HAS_CHAR8_T
1252extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char8_t, mbstate_t>; // C++20
1253extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char8_t, mbstate_t>; // C++20
1254# endif
1255
1256template <size_t _Np>
1257struct __narrow_to_utf8 {
1258 template <class _OutputIterator, class _CharT>
1259 _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1260};
1261
1262template <>
1263struct __narrow_to_utf8<8> {
1264 template <class _OutputIterator, class _CharT>
1265 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const {
1266 for (; __wb < __we; ++__wb, ++__s)
1267 *__s = *__wb;
1268 return __s;
1269 }
1270};
1271
1272_LIBCPP_SUPPRESS_DEPRECATED_PUSH
1273template <>
1274struct _LIBCPP_EXPORTED_FROM_ABI __narrow_to_utf8<16> : public codecvt<char16_t, char, mbstate_t> {
1275 _LIBCPP_HIDE_FROM_ABI __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1276 _LIBCPP_SUPPRESS_DEPRECATED_POP
1277
1278 ~__narrow_to_utf8() override;
1279
1280 template <class _OutputIterator, class _CharT>
1281 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const {
1282 result __r = ok;
1283 mbstate_t __mb;
1284 while (__wb < __we && __r != error) {
1285 const int __sz = 32;
1286 char __buf[__sz];
1287 char* __bn;
1288 const char16_t* __wn = (const char16_t*)__wb;
1289 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn, __buf, __buf + __sz, __bn);
1290 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1291 std::__throw_runtime_error("locale not supported");
1292 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1293 *__s = *__p;
1294 __wb = (const _CharT*)__wn;
1295 }
1296 return __s;
1297 }
1298};
1299
1300_LIBCPP_SUPPRESS_DEPRECATED_PUSH
1301template <>
1302struct _LIBCPP_EXPORTED_FROM_ABI __narrow_to_utf8<32> : public codecvt<char32_t, char, mbstate_t> {
1303 _LIBCPP_HIDE_FROM_ABI __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1304 _LIBCPP_SUPPRESS_DEPRECATED_POP
1305
1306 ~__narrow_to_utf8() override;
1307
1308 template <class _OutputIterator, class _CharT>
1309 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const {
1310 result __r = ok;
1311 mbstate_t __mb;
1312 while (__wb < __we && __r != error) {
1313 const int __sz = 32;
1314 char __buf[__sz];
1315 char* __bn;
1316 const char32_t* __wn = (const char32_t*)__wb;
1317 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn, __buf, __buf + __sz, __bn);
1318 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1319 std::__throw_runtime_error("locale not supported");
1320 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1321 *__s = *__p;
1322 __wb = (const _CharT*)__wn;
1323 }
1324 return __s;
1325 }
1326};
1327
1328template <size_t _Np>
1329struct __widen_from_utf8 {
1330 template <class _OutputIterator>
1331 _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1332};
1333
1334template <>
1335struct __widen_from_utf8<8> {
1336 template <class _OutputIterator>
1337 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const {
1338 for (; __nb < __ne; ++__nb, ++__s)
1339 *__s = *__nb;
1340 return __s;
1341 }
1342};
1343
1344_LIBCPP_SUPPRESS_DEPRECATED_PUSH
1345template <>
1346struct _LIBCPP_EXPORTED_FROM_ABI __widen_from_utf8<16> : public codecvt<char16_t, char, mbstate_t> {
1347 _LIBCPP_HIDE_FROM_ABI __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1348 _LIBCPP_SUPPRESS_DEPRECATED_POP
1349
1350 ~__widen_from_utf8() override;
1351
1352 template <class _OutputIterator>
1353 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const {
1354 result __r = ok;
1355 mbstate_t __mb;
1356 while (__nb < __ne && __r != error) {
1357 const int __sz = 32;
1358 char16_t __buf[__sz];
1359 char16_t* __bn;
1360 const char* __nn = __nb;
1361 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb + __sz : __ne, __nn, __buf, __buf + __sz, __bn);
1362 if (__r == codecvt_base::error || __nn == __nb)
1363 std::__throw_runtime_error("locale not supported");
1364 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1365 *__s = *__p;
1366 __nb = __nn;
1367 }
1368 return __s;
1369 }
1370};
1371
1372_LIBCPP_SUPPRESS_DEPRECATED_PUSH
1373template <>
1374struct _LIBCPP_EXPORTED_FROM_ABI __widen_from_utf8<32> : public codecvt<char32_t, char, mbstate_t> {
1375 _LIBCPP_HIDE_FROM_ABI __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1376 _LIBCPP_SUPPRESS_DEPRECATED_POP
1377
1378 ~__widen_from_utf8() override;
1379
1380 template <class _OutputIterator>
1381 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const {
1382 result __r = ok;
1383 mbstate_t __mb;
1384 while (__nb < __ne && __r != error) {
1385 const int __sz = 32;
1386 char32_t __buf[__sz];
1387 char32_t* __bn;
1388 const char* __nn = __nb;
1389 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb + __sz : __ne, __nn, __buf, __buf + __sz, __bn);
1390 if (__r == codecvt_base::error || __nn == __nb)
1391 std::__throw_runtime_error("locale not supported");
1392 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1393 *__s = *__p;
1394 __nb = __nn;
1395 }
1396 return __s;
1397 }
1398};
1399
1400// template <class charT> class numpunct
1401
1402template <class _CharT>
1403class numpunct;
1404
1405template <>
1406class _LIBCPP_EXPORTED_FROM_ABI numpunct<char> : public locale::facet {
1407public:
1408 typedef char char_type;
1409 typedef basic_string<char_type> string_type;
1410
1411 explicit numpunct(size_t __refs = 0);
1412
1413 _LIBCPP_HIDE_FROM_ABI char_type decimal_point() const { return do_decimal_point(); }
1414 _LIBCPP_HIDE_FROM_ABI char_type thousands_sep() const { return do_thousands_sep(); }
1415 _LIBCPP_HIDE_FROM_ABI string grouping() const { return do_grouping(); }
1416 _LIBCPP_HIDE_FROM_ABI string_type truename() const { return do_truename(); }
1417 _LIBCPP_HIDE_FROM_ABI string_type falsename() const { return do_falsename(); }
1418
1419 static locale::id id;
1420
1421protected:
1422 ~numpunct() override;
1423 virtual char_type do_decimal_point() const;
1424 virtual char_type do_thousands_sep() const;
1425 virtual string do_grouping() const;
1426 virtual string_type do_truename() const;
1427 virtual string_type do_falsename() const;
1428
1429 char_type __decimal_point_;
1430 char_type __thousands_sep_;
1431 string __grouping_;
1432};
1433
1434# if _LIBCPP_HAS_WIDE_CHARACTERS
1435template <>
1436class _LIBCPP_EXPORTED_FROM_ABI numpunct<wchar_t> : public locale::facet {
1437public:
1438 typedef wchar_t char_type;
1439 typedef basic_string<char_type> string_type;
1440
1441 explicit numpunct(size_t __refs = 0);
1442
1443 _LIBCPP_HIDE_FROM_ABI char_type decimal_point() const { return do_decimal_point(); }
1444 _LIBCPP_HIDE_FROM_ABI char_type thousands_sep() const { return do_thousands_sep(); }
1445 _LIBCPP_HIDE_FROM_ABI string grouping() const { return do_grouping(); }
1446 _LIBCPP_HIDE_FROM_ABI string_type truename() const { return do_truename(); }
1447 _LIBCPP_HIDE_FROM_ABI string_type falsename() const { return do_falsename(); }
1448
1449 static locale::id id;
1450
1451protected:
1452 ~numpunct() override;
1453 virtual char_type do_decimal_point() const;
1454 virtual char_type do_thousands_sep() const;
1455 virtual string do_grouping() const;
1456 virtual string_type do_truename() const;
1457 virtual string_type do_falsename() const;
1458
1459 char_type __decimal_point_;
1460 char_type __thousands_sep_;
1461 string __grouping_;
1462};
1463# endif // _LIBCPP_HAS_WIDE_CHARACTERS
1464
1465// template <class charT> class numpunct_byname
1466
1467template <class _CharT>
1468class numpunct_byname;
1469
1470template <>
1471class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<char> : public numpunct<char> {
1472public:
1473 typedef char char_type;
1474 typedef basic_string<char_type> string_type;
1475
1476 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1477 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1478
1479protected:
1480 ~numpunct_byname() override;
1481
1482private:
1483 void __init(const char*);
1484};
1485
1486# if _LIBCPP_HAS_WIDE_CHARACTERS
1487template <>
1488class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<wchar_t> : public numpunct<wchar_t> {
1489public:
1490 typedef wchar_t char_type;
1491 typedef basic_string<char_type> string_type;
1492
1493 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1494 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1495
1496protected:
1497 ~numpunct_byname() override;
1498
1499private:
1500 void __init(const char*);
1501};
1502# endif // _LIBCPP_HAS_WIDE_CHARACTERS
1503
1504_LIBCPP_END_NAMESPACE_STD
1505
1506#endif // _LIBCPP_HAS_LOCALIZATION
1507
1508#endif // _LIBCPP___LOCALE