2 //===----------------------------------------------------------------------===//
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
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___LOCALE
11 #define _LIBCPP___LOCALE
14 #include <__locale_dir/locale_base_api.h>
15 #include <__memory/shared_count.h>
16 #include <__mutex/once_flag.h>
17 #include <__type_traits/make_unsigned.h>
18 #include <__utility/no_destroy.h>
19 #include <__utility/private_constructor_tag.h>
26 // Some platforms require more includes than others. Keep the includes on all plaforms for now.
30 #if _LIBCPP_HAS_WIDE_CHARACTERS
33 # include <__std_mbstate_t.h>
36 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
37 # pragma GCC system_header
40 _LIBCPP_BEGIN_NAMESPACE_STD
42 class _LIBCPP_EXPORTED_FROM_ABI locale;
44 template <class _Facet>
45 _LIBCPP_HIDE_FROM_ABI bool has_facet(const locale&) _NOEXCEPT;
47 template <class _Facet>
48 _LIBCPP_HIDE_FROM_ABI const _Facet& use_facet(const locale&);
50 class _LIBCPP_EXPORTED_FROM_ABI locale {
52 // locale is essentially a shared_ptr that doesn't support weak_ptrs and never got a move constructor.
53 using __trivially_relocatable = locale;
56 class _LIBCPP_EXPORTED_FROM_ABI facet;
57 class _LIBCPP_EXPORTED_FROM_ABI id;
61 static const category // values assigned here are for exposition only
63 collate = LC_COLLATE_MASK, ctype = LC_CTYPE_MASK, monetary = LC_MONETARY_MASK, numeric = LC_NUMERIC_MASK,
64 time = LC_TIME_MASK, messages = LC_MESSAGES_MASK, all = collate | ctype | monetary | numeric | time | messages;
66 // construct/copy/destroy:
68 locale(const locale&) _NOEXCEPT;
69 explicit locale(const char*);
70 explicit locale(const string&);
71 locale(const locale&, const char*, category);
72 locale(const locale&, const string&, category);
73 template <class _Facet>
74 _LIBCPP_HIDE_FROM_ABI locale(const locale&, _Facet*);
75 locale(const locale&, const locale&, category);
79 const locale& operator=(const locale&) _NOEXCEPT;
81 template <class _Facet>
82 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS locale combine(const locale&) const;
86 bool operator==(const locale&) const;
87 #if _LIBCPP_STD_VER <= 17
88 _LIBCPP_HIDE_FROM_ABI bool operator!=(const locale& __y) const { return !(*this == __y); }
90 template <class _CharT, class _Traits, class _Allocator>
91 _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS bool
92 operator()(const basic_string<_CharT, _Traits, _Allocator>&, const basic_string<_CharT, _Traits, _Allocator>&) const;
94 // global locale objects:
95 static locale global(const locale&);
96 static const locale& classic();
103 friend struct __no_destroy;
104 _LIBCPP_HIDE_FROM_ABI explicit locale(__private_constructor_tag, __imp* __loc) : __locale_(__loc) {}
106 void __install_ctor(const locale&, facet*, long);
107 static locale& __global();
108 bool has_facet(id&) const;
109 const facet* use_facet(id&) const;
111 template <class _Facet>
112 friend bool has_facet(const locale&) _NOEXCEPT;
113 template <class _Facet>
114 friend const _Facet& use_facet(const locale&);
117 class _LIBCPP_EXPORTED_FROM_ABI locale::facet : public __shared_count {
119 _LIBCPP_HIDE_FROM_ABI explicit facet(size_t __refs = 0) : __shared_count(static_cast<long>(__refs) - 1) {}
123 // facet(const facet&) = delete; // effectively done in __shared_count
124 // void operator=(const facet&) = delete;
127 void __on_zero_shared() _NOEXCEPT override;
130 class _LIBCPP_EXPORTED_FROM_ABI locale::id {
134 static int32_t __next_id;
137 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR id() : __id_(0) {}
138 void operator=(const id&) = delete;
139 id(const id&) = delete;
141 public: // only needed for tests
145 friend class locale::__imp;
148 template <class _Facet>
149 inline _LIBCPP_HIDE_FROM_ABI locale::locale(const locale& __other, _Facet* __f) {
150 __install_ctor(__other, __f, __f ? __f->id.__get() : 0);
153 template <class _Facet>
154 locale locale::combine(const locale& __other) const {
155 if (!std::has_facet<_Facet>(__other))
156 __throw_runtime_error("locale::combine: locale missing facet");
158 return locale(*this, &const_cast<_Facet&>(std::use_facet<_Facet>(__other)));
161 template <class _Facet>
162 inline _LIBCPP_HIDE_FROM_ABI bool has_facet(const locale& __l) _NOEXCEPT {
163 return __l.has_facet(_Facet::id);
166 template <class _Facet>
167 inline _LIBCPP_HIDE_FROM_ABI const _Facet& use_facet(const locale& __l) {
168 return static_cast<const _Facet&>(*__l.use_facet(_Facet::id));
171 // template <class _CharT> class collate;
173 template <class _CharT>
174 class _LIBCPP_TEMPLATE_VIS collate : public locale::facet {
176 typedef _CharT char_type;
177 typedef basic_string<char_type> string_type;
179 _LIBCPP_HIDE_FROM_ABI explicit collate(size_t __refs = 0) : locale::facet(__refs) {}
181 _LIBCPP_HIDE_FROM_ABI int
182 compare(const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const {
183 return do_compare(__lo1, __hi1, __lo2, __hi2);
186 // FIXME(EricWF): The _LIBCPP_ALWAYS_INLINE is needed on Windows to work
187 // around a dllimport bug that expects an external instantiation.
188 _LIBCPP_HIDE_FROM_ABI _LIBCPP_ALWAYS_INLINE string_type
189 transform(const char_type* __lo, const char_type* __hi) const {
190 return do_transform(__lo, __hi);
193 _LIBCPP_HIDE_FROM_ABI long hash(const char_type* __lo, const char_type* __hi) const { return do_hash(__lo, __hi); }
195 static locale::id id;
200 do_compare(const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const;
201 virtual string_type do_transform(const char_type* __lo, const char_type* __hi) const {
202 return string_type(__lo, __hi);
204 virtual long do_hash(const char_type* __lo, const char_type* __hi) const;
207 template <class _CharT>
208 locale::id collate<_CharT>::id;
210 template <class _CharT>
211 collate<_CharT>::~collate() {}
213 template <class _CharT>
214 int collate<_CharT>::do_compare(
215 const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const {
216 for (; __lo2 != __hi2; ++__lo1, ++__lo2) {
217 if (__lo1 == __hi1 || *__lo1 < *__lo2)
222 return __lo1 != __hi1;
225 template <class _CharT>
226 long collate<_CharT>::do_hash(const char_type* __lo, const char_type* __hi) const {
228 const size_t __sr = __CHAR_BIT__ * sizeof(size_t) - 8;
229 const size_t __mask = size_t(0xF) << (__sr + 4);
230 for (const char_type* __p = __lo; __p != __hi; ++__p) {
231 __h = (__h << 4) + static_cast<size_t>(*__p);
232 size_t __g = __h & __mask;
233 __h ^= __g | (__g >> __sr);
235 return static_cast<long>(__h);
238 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<char>;
239 #if _LIBCPP_HAS_WIDE_CHARACTERS
240 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<wchar_t>;
243 // template <class CharT> class collate_byname;
245 template <class _CharT>
246 class _LIBCPP_TEMPLATE_VIS collate_byname;
249 class _LIBCPP_EXPORTED_FROM_ABI collate_byname<char> : public collate<char> {
250 __locale::__locale_t __l_;
253 typedef char char_type;
254 typedef basic_string<char_type> string_type;
256 explicit collate_byname(const char* __n, size_t __refs = 0);
257 explicit collate_byname(const string& __n, size_t __refs = 0);
260 ~collate_byname() override;
262 const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const override;
263 string_type do_transform(const char_type* __lo, const char_type* __hi) const override;
266 #if _LIBCPP_HAS_WIDE_CHARACTERS
268 class _LIBCPP_EXPORTED_FROM_ABI collate_byname<wchar_t> : public collate<wchar_t> {
269 __locale::__locale_t __l_;
272 typedef wchar_t char_type;
273 typedef basic_string<char_type> string_type;
275 explicit collate_byname(const char* __n, size_t __refs = 0);
276 explicit collate_byname(const string& __n, size_t __refs = 0);
279 ~collate_byname() override;
282 const char_type* __lo1, const char_type* __hi1, const char_type* __lo2, const char_type* __hi2) const override;
283 string_type do_transform(const char_type* __lo, const char_type* __hi) const override;
287 template <class _CharT, class _Traits, class _Allocator>
288 bool locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
289 const basic_string<_CharT, _Traits, _Allocator>& __y) const {
290 return std::use_facet<std::collate<_CharT> >(*this).compare(
291 __x.data(), __x.data() + __x.size(), __y.data(), __y.data() + __y.size()) < 0;
294 // template <class charT> class ctype
296 class _LIBCPP_EXPORTED_FROM_ABI ctype_base {
298 #if defined(_LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE)
299 typedef unsigned long mask;
300 static const mask space = 1 << 0;
301 static const mask print = 1 << 1;
302 static const mask cntrl = 1 << 2;
303 static const mask upper = 1 << 3;
304 static const mask lower = 1 << 4;
305 static const mask alpha = 1 << 5;
306 static const mask digit = 1 << 6;
307 static const mask punct = 1 << 7;
308 static const mask xdigit = 1 << 8;
309 static const mask blank = 1 << 9;
310 # if defined(__BIONIC__)
311 // Historically this was a part of regex_traits rather than ctype_base. The
312 // historical value of the constant is preserved for ABI compatibility.
313 static const mask __regex_word = 0x8000;
315 static const mask __regex_word = 1 << 10;
316 # endif // defined(__BIONIC__)
317 #elif defined(__GLIBC__)
318 typedef unsigned short mask;
319 static const mask space = _ISspace;
320 static const mask print = _ISprint;
321 static const mask cntrl = _IScntrl;
322 static const mask upper = _ISupper;
323 static const mask lower = _ISlower;
324 static const mask alpha = _ISalpha;
325 static const mask digit = _ISdigit;
326 static const mask punct = _ISpunct;
327 static const mask xdigit = _ISxdigit;
328 static const mask blank = _ISblank;
329 # if defined(__mips__) || (BYTE_ORDER == BIG_ENDIAN)
330 static const mask __regex_word = static_cast<mask>(_ISbit(15));
332 static const mask __regex_word = 0x80;
334 #elif defined(_LIBCPP_MSVCRT_LIKE)
335 typedef unsigned short mask;
336 static const mask space = _SPACE;
337 static const mask print = _BLANK | _PUNCT | _ALPHA | _DIGIT;
338 static const mask cntrl = _CONTROL;
339 static const mask upper = _UPPER;
340 static const mask lower = _LOWER;
341 static const mask alpha = _ALPHA;
342 static const mask digit = _DIGIT;
343 static const mask punct = _PUNCT;
344 static const mask xdigit = _HEX;
345 static const mask blank = _BLANK;
346 static const mask __regex_word = 0x4000; // 0x8000 and 0x0100 and 0x00ff are used
347 # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
348 # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
349 #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
351 typedef __uint32_t mask;
352 # elif defined(__FreeBSD__)
353 typedef unsigned long mask;
354 # elif defined(__NetBSD__)
355 typedef unsigned short mask;
357 static const mask space = _CTYPE_S;
358 static const mask print = _CTYPE_R;
359 static const mask cntrl = _CTYPE_C;
360 static const mask upper = _CTYPE_U;
361 static const mask lower = _CTYPE_L;
362 static const mask alpha = _CTYPE_A;
363 static const mask digit = _CTYPE_D;
364 static const mask punct = _CTYPE_P;
365 static const mask xdigit = _CTYPE_X;
367 # if defined(__NetBSD__)
368 static const mask blank = _CTYPE_BL;
369 // NetBSD defines classes up to 0x2000
370 // see sys/ctype_bits.h, _CTYPE_Q
371 static const mask __regex_word = 0x8000;
373 static const mask blank = _CTYPE_B;
374 static const mask __regex_word = 0x80;
377 typedef unsigned int mask;
378 static const mask space = _ISSPACE;
379 static const mask print = _ISPRINT;
380 static const mask cntrl = _ISCNTRL;
381 static const mask upper = _ISUPPER;
382 static const mask lower = _ISLOWER;
383 static const mask alpha = _ISALPHA;
384 static const mask digit = _ISDIGIT;
385 static const mask punct = _ISPUNCT;
386 static const mask xdigit = _ISXDIGIT;
387 static const mask blank = _ISBLANK;
388 static const mask __regex_word = 0x8000;
389 #elif defined(_NEWLIB_VERSION)
390 // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h.
392 // In case char is signed, static_cast is needed to avoid warning on
393 // positive value becomming negative.
394 static const mask space = static_cast<mask>(_S);
395 static const mask print = static_cast<mask>(_P | _U | _L | _N | _B);
396 static const mask cntrl = static_cast<mask>(_C);
397 static const mask upper = static_cast<mask>(_U);
398 static const mask lower = static_cast<mask>(_L);
399 static const mask alpha = static_cast<mask>(_U | _L);
400 static const mask digit = static_cast<mask>(_N);
401 static const mask punct = static_cast<mask>(_P);
402 static const mask xdigit = static_cast<mask>(_X | _N);
403 static const mask blank = static_cast<mask>(_B);
404 // mask is already fully saturated, use a different type in regex_type_traits.
405 static const unsigned short __regex_word = 0x100;
406 # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT
407 # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
408 # define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
409 #elif defined(__MVS__)
410 # if defined(__NATIVE_ASCII_F)
411 typedef unsigned int mask;
412 static const mask space = _ISSPACE_A;
413 static const mask print = _ISPRINT_A;
414 static const mask cntrl = _ISCNTRL_A;
415 static const mask upper = _ISUPPER_A;
416 static const mask lower = _ISLOWER_A;
417 static const mask alpha = _ISALPHA_A;
418 static const mask digit = _ISDIGIT_A;
419 static const mask punct = _ISPUNCT_A;
420 static const mask xdigit = _ISXDIGIT_A;
421 static const mask blank = _ISBLANK_A;
423 typedef unsigned short mask;
424 static const mask space = __ISSPACE;
425 static const mask print = __ISPRINT;
426 static const mask cntrl = __ISCNTRL;
427 static const mask upper = __ISUPPER;
428 static const mask lower = __ISLOWER;
429 static const mask alpha = __ISALPHA;
430 static const mask digit = __ISDIGIT;
431 static const mask punct = __ISPUNCT;
432 static const mask xdigit = __ISXDIGIT;
433 static const mask blank = __ISBLANK;
435 static const mask __regex_word = 0x8000;
437 # error unknown rune table for this platform -- do you mean to define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE?
439 static const mask alnum = alpha | digit;
440 static const mask graph = alnum | punct;
442 _LIBCPP_HIDE_FROM_ABI ctype_base() {}
444 static_assert((__regex_word & ~(std::make_unsigned<mask>::type)(space | print | cntrl | upper | lower | alpha |
445 digit | punct | xdigit | blank)) == __regex_word,
446 "__regex_word can't overlap other bits");
449 template <class _CharT>
450 class _LIBCPP_TEMPLATE_VIS ctype;
452 #if _LIBCPP_HAS_WIDE_CHARACTERS
454 class _LIBCPP_EXPORTED_FROM_ABI ctype<wchar_t> : public locale::facet, public ctype_base {
456 typedef wchar_t char_type;
458 _LIBCPP_HIDE_FROM_ABI explicit ctype(size_t __refs = 0) : locale::facet(__refs) {}
460 _LIBCPP_HIDE_FROM_ABI bool is(mask __m, char_type __c) const { return do_is(__m, __c); }
462 _LIBCPP_HIDE_FROM_ABI const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const {
463 return do_is(__low, __high, __vec);
466 _LIBCPP_HIDE_FROM_ABI const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const {
467 return do_scan_is(__m, __low, __high);
470 _LIBCPP_HIDE_FROM_ABI const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const {
471 return do_scan_not(__m, __low, __high);
474 _LIBCPP_HIDE_FROM_ABI char_type toupper(char_type __c) const { return do_toupper(__c); }
476 _LIBCPP_HIDE_FROM_ABI const char_type* toupper(char_type* __low, const char_type* __high) const {
477 return do_toupper(__low, __high);
480 _LIBCPP_HIDE_FROM_ABI char_type tolower(char_type __c) const { return do_tolower(__c); }
482 _LIBCPP_HIDE_FROM_ABI const char_type* tolower(char_type* __low, const char_type* __high) const {
483 return do_tolower(__low, __high);
486 _LIBCPP_HIDE_FROM_ABI char_type widen(char __c) const { return do_widen(__c); }
488 _LIBCPP_HIDE_FROM_ABI const char* widen(const char* __low, const char* __high, char_type* __to) const {
489 return do_widen(__low, __high, __to);
492 _LIBCPP_HIDE_FROM_ABI char narrow(char_type __c, char __dfault) const { return do_narrow(__c, __dfault); }
494 _LIBCPP_HIDE_FROM_ABI const char_type*
495 narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const {
496 return do_narrow(__low, __high, __dfault, __to);
499 static locale::id id;
503 virtual bool do_is(mask __m, char_type __c) const;
504 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const;
505 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const;
506 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const;
507 virtual char_type do_toupper(char_type) const;
508 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
509 virtual char_type do_tolower(char_type) const;
510 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
511 virtual char_type do_widen(char) const;
512 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const;
513 virtual char do_narrow(char_type, char __dfault) const;
514 virtual const char_type*
515 do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const;
517 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
520 class _LIBCPP_EXPORTED_FROM_ABI ctype<char> : public locale::facet, public ctype_base {
525 typedef char char_type;
527 explicit ctype(const mask* __tab = nullptr, bool __del = false, size_t __refs = 0);
529 _LIBCPP_HIDE_FROM_ABI bool is(mask __m, char_type __c) const {
530 return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) != 0 : false;
533 _LIBCPP_HIDE_FROM_ABI const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const {
534 for (; __low != __high; ++__low, ++__vec)
535 *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0;
539 _LIBCPP_HIDE_FROM_ABI const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const {
540 for (; __low != __high; ++__low)
541 if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))
546 _LIBCPP_HIDE_FROM_ABI const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const {
547 for (; __low != __high; ++__low)
548 if (!isascii(*__low) || !(__tab_[static_cast<int>(*__low)] & __m))
553 _LIBCPP_HIDE_FROM_ABI char_type toupper(char_type __c) const { return do_toupper(__c); }
555 _LIBCPP_HIDE_FROM_ABI const char_type* toupper(char_type* __low, const char_type* __high) const {
556 return do_toupper(__low, __high);
559 _LIBCPP_HIDE_FROM_ABI char_type tolower(char_type __c) const { return do_tolower(__c); }
561 _LIBCPP_HIDE_FROM_ABI const char_type* tolower(char_type* __low, const char_type* __high) const {
562 return do_tolower(__low, __high);
565 _LIBCPP_HIDE_FROM_ABI char_type widen(char __c) const { return do_widen(__c); }
567 _LIBCPP_HIDE_FROM_ABI const char* widen(const char* __low, const char* __high, char_type* __to) const {
568 return do_widen(__low, __high, __to);
571 _LIBCPP_HIDE_FROM_ABI char narrow(char_type __c, char __dfault) const { return do_narrow(__c, __dfault); }
573 _LIBCPP_HIDE_FROM_ABI const char*
574 narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const {
575 return do_narrow(__low, __high, __dfault, __to);
578 static locale::id id;
581 static const size_t table_size = _CACHED_RUNES;
583 static const size_t table_size = 256; // FIXME: Don't hardcode this.
585 _LIBCPP_HIDE_FROM_ABI const mask* table() const _NOEXCEPT { return __tab_; }
586 static const mask* classic_table() _NOEXCEPT;
587 #if defined(__GLIBC__) || defined(__EMSCRIPTEN__)
588 static const int* __classic_upper_table() _NOEXCEPT;
589 static const int* __classic_lower_table() _NOEXCEPT;
591 #if defined(__NetBSD__)
592 static const short* __classic_upper_table() _NOEXCEPT;
593 static const short* __classic_lower_table() _NOEXCEPT;
596 static const unsigned short* __classic_upper_table() _NOEXCEPT;
597 static const unsigned short* __classic_lower_table() _NOEXCEPT;
602 virtual char_type do_toupper(char_type __c) const;
603 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const;
604 virtual char_type do_tolower(char_type __c) const;
605 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const;
606 virtual char_type do_widen(char __c) const;
607 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const;
608 virtual char do_narrow(char_type __c, char __dfault) const;
609 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const;
612 // template <class CharT> class ctype_byname;
614 template <class _CharT>
615 class _LIBCPP_TEMPLATE_VIS ctype_byname;
618 class _LIBCPP_EXPORTED_FROM_ABI ctype_byname<char> : public ctype<char> {
619 __locale::__locale_t __l_;
622 explicit ctype_byname(const char*, size_t = 0);
623 explicit ctype_byname(const string&, size_t = 0);
626 ~ctype_byname() override;
627 char_type do_toupper(char_type) const override;
628 const char_type* do_toupper(char_type* __low, const char_type* __high) const override;
629 char_type do_tolower(char_type) const override;
630 const char_type* do_tolower(char_type* __low, const char_type* __high) const override;
633 #if _LIBCPP_HAS_WIDE_CHARACTERS
635 class _LIBCPP_EXPORTED_FROM_ABI ctype_byname<wchar_t> : public ctype<wchar_t> {
636 __locale::__locale_t __l_;
639 explicit ctype_byname(const char*, size_t = 0);
640 explicit ctype_byname(const string&, size_t = 0);
643 ~ctype_byname() override;
644 bool do_is(mask __m, char_type __c) const override;
645 const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const override;
646 const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const override;
647 const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const override;
648 char_type do_toupper(char_type) const override;
649 const char_type* do_toupper(char_type* __low, const char_type* __high) const override;
650 char_type do_tolower(char_type) const override;
651 const char_type* do_tolower(char_type* __low, const char_type* __high) const override;
652 char_type do_widen(char) const override;
653 const char* do_widen(const char* __low, const char* __high, char_type* __dest) const override;
654 char do_narrow(char_type, char __dfault) const override;
656 do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const override;
658 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
660 template <class _CharT>
661 inline _LIBCPP_HIDE_FROM_ABI bool isspace(_CharT __c, const locale& __loc) {
662 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c);
665 template <class _CharT>
666 inline _LIBCPP_HIDE_FROM_ABI bool isprint(_CharT __c, const locale& __loc) {
667 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c);
670 template <class _CharT>
671 inline _LIBCPP_HIDE_FROM_ABI bool iscntrl(_CharT __c, const locale& __loc) {
672 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c);
675 template <class _CharT>
676 inline _LIBCPP_HIDE_FROM_ABI bool isupper(_CharT __c, const locale& __loc) {
677 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c);
680 template <class _CharT>
681 inline _LIBCPP_HIDE_FROM_ABI bool islower(_CharT __c, const locale& __loc) {
682 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c);
685 template <class _CharT>
686 inline _LIBCPP_HIDE_FROM_ABI bool isalpha(_CharT __c, const locale& __loc) {
687 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c);
690 template <class _CharT>
691 inline _LIBCPP_HIDE_FROM_ABI bool isdigit(_CharT __c, const locale& __loc) {
692 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c);
695 template <class _CharT>
696 inline _LIBCPP_HIDE_FROM_ABI bool ispunct(_CharT __c, const locale& __loc) {
697 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c);
700 template <class _CharT>
701 inline _LIBCPP_HIDE_FROM_ABI bool isxdigit(_CharT __c, const locale& __loc) {
702 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c);
705 template <class _CharT>
706 inline _LIBCPP_HIDE_FROM_ABI bool isalnum(_CharT __c, const locale& __loc) {
707 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c);
710 template <class _CharT>
711 inline _LIBCPP_HIDE_FROM_ABI bool isgraph(_CharT __c, const locale& __loc) {
712 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c);
715 template <class _CharT>
716 _LIBCPP_HIDE_FROM_ABI bool isblank(_CharT __c, const locale& __loc) {
717 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::blank, __c);
720 template <class _CharT>
721 inline _LIBCPP_HIDE_FROM_ABI _CharT toupper(_CharT __c, const locale& __loc) {
722 return std::use_facet<ctype<_CharT> >(__loc).toupper(__c);
725 template <class _CharT>
726 inline _LIBCPP_HIDE_FROM_ABI _CharT tolower(_CharT __c, const locale& __loc) {
727 return std::use_facet<ctype<_CharT> >(__loc).tolower(__c);
732 class _LIBCPP_EXPORTED_FROM_ABI codecvt_base {
734 _LIBCPP_HIDE_FROM_ABI codecvt_base() {}
735 enum result { ok, partial, error, noconv };
738 // template <class internT, class externT, class stateT> class codecvt;
740 template <class _InternT, class _ExternT, class _StateT>
741 class _LIBCPP_TEMPLATE_VIS codecvt;
743 // template <> class codecvt<char, char, mbstate_t>
746 class _LIBCPP_EXPORTED_FROM_ABI codecvt<char, char, mbstate_t> : public locale::facet, public codecvt_base {
748 typedef char intern_type;
749 typedef char extern_type;
750 typedef mbstate_t state_type;
752 _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
754 _LIBCPP_HIDE_FROM_ABI result
755 out(state_type& __st,
756 const intern_type* __frm,
757 const intern_type* __frm_end,
758 const intern_type*& __frm_nxt,
760 extern_type* __to_end,
761 extern_type*& __to_nxt) const {
762 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
765 _LIBCPP_HIDE_FROM_ABI result
766 unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const {
767 return do_unshift(__st, __to, __to_end, __to_nxt);
770 _LIBCPP_HIDE_FROM_ABI result
772 const extern_type* __frm,
773 const extern_type* __frm_end,
774 const extern_type*& __frm_nxt,
776 intern_type* __to_end,
777 intern_type*& __to_nxt) const {
778 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
781 _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
783 _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
785 _LIBCPP_HIDE_FROM_ABI int
786 length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const {
787 return do_length(__st, __frm, __end, __mx);
790 _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
792 static locale::id id;
795 _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {}
800 do_out(state_type& __st,
801 const intern_type* __frm,
802 const intern_type* __frm_end,
803 const intern_type*& __frm_nxt,
805 extern_type* __to_end,
806 extern_type*& __to_nxt) const;
808 do_in(state_type& __st,
809 const extern_type* __frm,
810 const extern_type* __frm_end,
811 const extern_type*& __frm_nxt,
813 intern_type* __to_end,
814 intern_type*& __to_nxt) const;
815 virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
816 virtual int do_encoding() const _NOEXCEPT;
817 virtual bool do_always_noconv() const _NOEXCEPT;
818 virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
819 virtual int do_max_length() const _NOEXCEPT;
822 // template <> class codecvt<wchar_t, char, mbstate_t>
824 #if _LIBCPP_HAS_WIDE_CHARACTERS
826 class _LIBCPP_EXPORTED_FROM_ABI codecvt<wchar_t, char, mbstate_t> : public locale::facet, public codecvt_base {
827 __locale::__locale_t __l_;
830 typedef wchar_t intern_type;
831 typedef char extern_type;
832 typedef mbstate_t state_type;
834 explicit codecvt(size_t __refs = 0);
836 _LIBCPP_HIDE_FROM_ABI result
837 out(state_type& __st,
838 const intern_type* __frm,
839 const intern_type* __frm_end,
840 const intern_type*& __frm_nxt,
842 extern_type* __to_end,
843 extern_type*& __to_nxt) const {
844 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
847 _LIBCPP_HIDE_FROM_ABI result
848 unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const {
849 return do_unshift(__st, __to, __to_end, __to_nxt);
852 _LIBCPP_HIDE_FROM_ABI result
854 const extern_type* __frm,
855 const extern_type* __frm_end,
856 const extern_type*& __frm_nxt,
858 intern_type* __to_end,
859 intern_type*& __to_nxt) const {
860 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
863 _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
865 _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
867 _LIBCPP_HIDE_FROM_ABI int
868 length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const {
869 return do_length(__st, __frm, __end, __mx);
872 _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
874 static locale::id id;
877 explicit codecvt(const char*, size_t __refs = 0);
882 do_out(state_type& __st,
883 const intern_type* __frm,
884 const intern_type* __frm_end,
885 const intern_type*& __frm_nxt,
887 extern_type* __to_end,
888 extern_type*& __to_nxt) const;
890 do_in(state_type& __st,
891 const extern_type* __frm,
892 const extern_type* __frm_end,
893 const extern_type*& __frm_nxt,
895 intern_type* __to_end,
896 intern_type*& __to_nxt) const;
897 virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
898 virtual int do_encoding() const _NOEXCEPT;
899 virtual bool do_always_noconv() const _NOEXCEPT;
900 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
901 virtual int do_max_length() const _NOEXCEPT;
903 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
905 // template <> class codecvt<char16_t, char, mbstate_t> // deprecated in C++20
908 class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXPORTED_FROM_ABI codecvt<char16_t, char, mbstate_t>
909 : public locale::facet, public codecvt_base {
911 typedef char16_t intern_type;
912 typedef char extern_type;
913 typedef mbstate_t state_type;
915 _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
917 _LIBCPP_HIDE_FROM_ABI result
918 out(state_type& __st,
919 const intern_type* __frm,
920 const intern_type* __frm_end,
921 const intern_type*& __frm_nxt,
923 extern_type* __to_end,
924 extern_type*& __to_nxt) const {
925 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
928 _LIBCPP_HIDE_FROM_ABI result
929 unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const {
930 return do_unshift(__st, __to, __to_end, __to_nxt);
933 _LIBCPP_HIDE_FROM_ABI result
935 const extern_type* __frm,
936 const extern_type* __frm_end,
937 const extern_type*& __frm_nxt,
939 intern_type* __to_end,
940 intern_type*& __to_nxt) const {
941 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
944 _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
946 _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
948 _LIBCPP_HIDE_FROM_ABI int
949 length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const {
950 return do_length(__st, __frm, __end, __mx);
953 _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
955 static locale::id id;
958 _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {}
963 do_out(state_type& __st,
964 const intern_type* __frm,
965 const intern_type* __frm_end,
966 const intern_type*& __frm_nxt,
968 extern_type* __to_end,
969 extern_type*& __to_nxt) const;
971 do_in(state_type& __st,
972 const extern_type* __frm,
973 const extern_type* __frm_end,
974 const extern_type*& __frm_nxt,
976 intern_type* __to_end,
977 intern_type*& __to_nxt) const;
978 virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
979 virtual int do_encoding() const _NOEXCEPT;
980 virtual bool do_always_noconv() const _NOEXCEPT;
981 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
982 virtual int do_max_length() const _NOEXCEPT;
985 #if _LIBCPP_HAS_CHAR8_T
987 // template <> class codecvt<char16_t, char8_t, mbstate_t> // C++20
990 class _LIBCPP_EXPORTED_FROM_ABI codecvt<char16_t, char8_t, mbstate_t> : public locale::facet, public codecvt_base {
992 typedef char16_t intern_type;
993 typedef char8_t extern_type;
994 typedef mbstate_t state_type;
996 _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
998 _LIBCPP_HIDE_FROM_ABI result
999 out(state_type& __st,
1000 const intern_type* __frm,
1001 const intern_type* __frm_end,
1002 const intern_type*& __frm_nxt,
1004 extern_type* __to_end,
1005 extern_type*& __to_nxt) const {
1006 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1009 _LIBCPP_HIDE_FROM_ABI result
1010 unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const {
1011 return do_unshift(__st, __to, __to_end, __to_nxt);
1014 _LIBCPP_HIDE_FROM_ABI result
1015 in(state_type& __st,
1016 const extern_type* __frm,
1017 const extern_type* __frm_end,
1018 const extern_type*& __frm_nxt,
1020 intern_type* __to_end,
1021 intern_type*& __to_nxt) const {
1022 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1025 _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
1027 _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
1029 _LIBCPP_HIDE_FROM_ABI int
1030 length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const {
1031 return do_length(__st, __frm, __end, __mx);
1034 _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
1036 static locale::id id;
1039 _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {}
1041 ~codecvt() override;
1044 do_out(state_type& __st,
1045 const intern_type* __frm,
1046 const intern_type* __frm_end,
1047 const intern_type*& __frm_nxt,
1049 extern_type* __to_end,
1050 extern_type*& __to_nxt) const;
1052 do_in(state_type& __st,
1053 const extern_type* __frm,
1054 const extern_type* __frm_end,
1055 const extern_type*& __frm_nxt,
1057 intern_type* __to_end,
1058 intern_type*& __to_nxt) const;
1059 virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1060 virtual int do_encoding() const _NOEXCEPT;
1061 virtual bool do_always_noconv() const _NOEXCEPT;
1062 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1063 virtual int do_max_length() const _NOEXCEPT;
1068 // template <> class codecvt<char32_t, char, mbstate_t> // deprecated in C++20
1071 class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXPORTED_FROM_ABI codecvt<char32_t, char, mbstate_t>
1072 : public locale::facet, public codecvt_base {
1074 typedef char32_t intern_type;
1075 typedef char extern_type;
1076 typedef mbstate_t state_type;
1078 _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
1080 _LIBCPP_HIDE_FROM_ABI result
1081 out(state_type& __st,
1082 const intern_type* __frm,
1083 const intern_type* __frm_end,
1084 const intern_type*& __frm_nxt,
1086 extern_type* __to_end,
1087 extern_type*& __to_nxt) const {
1088 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1091 _LIBCPP_HIDE_FROM_ABI result
1092 unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const {
1093 return do_unshift(__st, __to, __to_end, __to_nxt);
1096 _LIBCPP_HIDE_FROM_ABI result
1097 in(state_type& __st,
1098 const extern_type* __frm,
1099 const extern_type* __frm_end,
1100 const extern_type*& __frm_nxt,
1102 intern_type* __to_end,
1103 intern_type*& __to_nxt) const {
1104 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1107 _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
1109 _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
1111 _LIBCPP_HIDE_FROM_ABI int
1112 length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const {
1113 return do_length(__st, __frm, __end, __mx);
1116 _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
1118 static locale::id id;
1121 _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {}
1123 ~codecvt() override;
1126 do_out(state_type& __st,
1127 const intern_type* __frm,
1128 const intern_type* __frm_end,
1129 const intern_type*& __frm_nxt,
1131 extern_type* __to_end,
1132 extern_type*& __to_nxt) const;
1134 do_in(state_type& __st,
1135 const extern_type* __frm,
1136 const extern_type* __frm_end,
1137 const extern_type*& __frm_nxt,
1139 intern_type* __to_end,
1140 intern_type*& __to_nxt) const;
1141 virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1142 virtual int do_encoding() const _NOEXCEPT;
1143 virtual bool do_always_noconv() const _NOEXCEPT;
1144 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1145 virtual int do_max_length() const _NOEXCEPT;
1148 #if _LIBCPP_HAS_CHAR8_T
1150 // template <> class codecvt<char32_t, char8_t, mbstate_t> // C++20
1153 class _LIBCPP_EXPORTED_FROM_ABI codecvt<char32_t, char8_t, mbstate_t> : public locale::facet, public codecvt_base {
1155 typedef char32_t intern_type;
1156 typedef char8_t extern_type;
1157 typedef mbstate_t state_type;
1159 _LIBCPP_HIDE_FROM_ABI explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
1161 _LIBCPP_HIDE_FROM_ABI result
1162 out(state_type& __st,
1163 const intern_type* __frm,
1164 const intern_type* __frm_end,
1165 const intern_type*& __frm_nxt,
1167 extern_type* __to_end,
1168 extern_type*& __to_nxt) const {
1169 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1172 _LIBCPP_HIDE_FROM_ABI result
1173 unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const {
1174 return do_unshift(__st, __to, __to_end, __to_nxt);
1177 _LIBCPP_HIDE_FROM_ABI result
1178 in(state_type& __st,
1179 const extern_type* __frm,
1180 const extern_type* __frm_end,
1181 const extern_type*& __frm_nxt,
1183 intern_type* __to_end,
1184 intern_type*& __to_nxt) const {
1185 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt);
1188 _LIBCPP_HIDE_FROM_ABI int encoding() const _NOEXCEPT { return do_encoding(); }
1190 _LIBCPP_HIDE_FROM_ABI bool always_noconv() const _NOEXCEPT { return do_always_noconv(); }
1192 _LIBCPP_HIDE_FROM_ABI int
1193 length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const {
1194 return do_length(__st, __frm, __end, __mx);
1197 _LIBCPP_HIDE_FROM_ABI int max_length() const _NOEXCEPT { return do_max_length(); }
1199 static locale::id id;
1202 _LIBCPP_HIDE_FROM_ABI explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {}
1204 ~codecvt() override;
1207 do_out(state_type& __st,
1208 const intern_type* __frm,
1209 const intern_type* __frm_end,
1210 const intern_type*& __frm_nxt,
1212 extern_type* __to_end,
1213 extern_type*& __to_nxt) const;
1215 do_in(state_type& __st,
1216 const extern_type* __frm,
1217 const extern_type* __frm_end,
1218 const extern_type*& __frm_nxt,
1220 intern_type* __to_end,
1221 intern_type*& __to_nxt) const;
1222 virtual result do_unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const;
1223 virtual int do_encoding() const _NOEXCEPT;
1224 virtual bool do_always_noconv() const _NOEXCEPT;
1225 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const;
1226 virtual int do_max_length() const _NOEXCEPT;
1231 // template <class _InternT, class _ExternT, class _StateT> class codecvt_byname
1233 template <class _InternT, class _ExternT, class _StateT>
1234 class _LIBCPP_TEMPLATE_VIS codecvt_byname : public codecvt<_InternT, _ExternT, _StateT> {
1236 _LIBCPP_HIDE_FROM_ABI explicit codecvt_byname(const char* __nm, size_t __refs = 0)
1237 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {}
1238 _LIBCPP_HIDE_FROM_ABI explicit codecvt_byname(const string& __nm, size_t __refs = 0)
1239 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {}
1242 ~codecvt_byname() override;
1245 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1246 template <class _InternT, class _ExternT, class _StateT>
1247 codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname() {}
1248 _LIBCPP_SUPPRESS_DEPRECATED_POP
1250 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>;
1251 #if _LIBCPP_HAS_WIDE_CHARACTERS
1252 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>;
1254 extern template class _LIBCPP_DEPRECATED_IN_CXX20
1255 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>; // deprecated in C++20
1256 extern template class _LIBCPP_DEPRECATED_IN_CXX20
1257 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>; // deprecated in C++20
1258 #if _LIBCPP_HAS_CHAR8_T
1259 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char8_t, mbstate_t>; // C++20
1260 extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char8_t, mbstate_t>; // C++20
1263 template <size_t _Np>
1264 struct __narrow_to_utf8 {
1265 template <class _OutputIterator, class _CharT>
1266 _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const;
1270 struct __narrow_to_utf8<8> {
1271 template <class _OutputIterator, class _CharT>
1272 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const {
1273 for (; __wb < __we; ++__wb, ++__s)
1279 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1281 struct _LIBCPP_EXPORTED_FROM_ABI __narrow_to_utf8<16> : public codecvt<char16_t, char, mbstate_t> {
1282 _LIBCPP_HIDE_FROM_ABI __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1283 _LIBCPP_SUPPRESS_DEPRECATED_POP
1285 ~__narrow_to_utf8() override;
1287 template <class _OutputIterator, class _CharT>
1288 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const {
1291 while (__wb < __we && __r != error) {
1292 const int __sz = 32;
1295 const char16_t* __wn = (const char16_t*)__wb;
1296 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn, __buf, __buf + __sz, __bn);
1297 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb)
1298 __throw_runtime_error("locale not supported");
1299 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1301 __wb = (const _CharT*)__wn;
1307 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1309 struct _LIBCPP_EXPORTED_FROM_ABI __narrow_to_utf8<32> : public codecvt<char32_t, char, mbstate_t> {
1310 _LIBCPP_HIDE_FROM_ABI __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1311 _LIBCPP_SUPPRESS_DEPRECATED_POP
1313 ~__narrow_to_utf8() override;
1315 template <class _OutputIterator, class _CharT>
1316 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const {
1319 while (__wb < __we && __r != error) {
1320 const int __sz = 32;
1323 const char32_t* __wn = (const char32_t*)__wb;
1324 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn, __buf, __buf + __sz, __bn);
1325 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb)
1326 __throw_runtime_error("locale not supported");
1327 for (const char* __p = __buf; __p < __bn; ++__p, ++__s)
1329 __wb = (const _CharT*)__wn;
1335 template <size_t _Np>
1336 struct __widen_from_utf8 {
1337 template <class _OutputIterator>
1338 _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const;
1342 struct __widen_from_utf8<8> {
1343 template <class _OutputIterator>
1344 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const {
1345 for (; __nb < __ne; ++__nb, ++__s)
1351 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1353 struct _LIBCPP_EXPORTED_FROM_ABI __widen_from_utf8<16> : public codecvt<char16_t, char, mbstate_t> {
1354 _LIBCPP_HIDE_FROM_ABI __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {}
1355 _LIBCPP_SUPPRESS_DEPRECATED_POP
1357 ~__widen_from_utf8() override;
1359 template <class _OutputIterator>
1360 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const {
1363 while (__nb < __ne && __r != error) {
1364 const int __sz = 32;
1365 char16_t __buf[__sz];
1367 const char* __nn = __nb;
1368 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb + __sz : __ne, __nn, __buf, __buf + __sz, __bn);
1369 if (__r == codecvt_base::error || __nn == __nb)
1370 __throw_runtime_error("locale not supported");
1371 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s)
1379 _LIBCPP_SUPPRESS_DEPRECATED_PUSH
1381 struct _LIBCPP_EXPORTED_FROM_ABI __widen_from_utf8<32> : public codecvt<char32_t, char, mbstate_t> {
1382 _LIBCPP_HIDE_FROM_ABI __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {}
1383 _LIBCPP_SUPPRESS_DEPRECATED_POP
1385 ~__widen_from_utf8() override;
1387 template <class _OutputIterator>
1388 _LIBCPP_HIDE_FROM_ABI _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const {
1391 while (__nb < __ne && __r != error) {
1392 const int __sz = 32;
1393 char32_t __buf[__sz];
1395 const char* __nn = __nb;
1396 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb + __sz : __ne, __nn, __buf, __buf + __sz, __bn);
1397 if (__r == codecvt_base::error || __nn == __nb)
1398 __throw_runtime_error("locale not supported");
1399 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s)
1407 // template <class charT> class numpunct
1409 template <class _CharT>
1410 class _LIBCPP_TEMPLATE_VIS numpunct;
1413 class _LIBCPP_EXPORTED_FROM_ABI numpunct<char> : public locale::facet {
1415 typedef char char_type;
1416 typedef basic_string<char_type> string_type;
1418 explicit numpunct(size_t __refs = 0);
1420 _LIBCPP_HIDE_FROM_ABI char_type decimal_point() const { return do_decimal_point(); }
1421 _LIBCPP_HIDE_FROM_ABI char_type thousands_sep() const { return do_thousands_sep(); }
1422 _LIBCPP_HIDE_FROM_ABI string grouping() const { return do_grouping(); }
1423 _LIBCPP_HIDE_FROM_ABI string_type truename() const { return do_truename(); }
1424 _LIBCPP_HIDE_FROM_ABI string_type falsename() const { return do_falsename(); }
1426 static locale::id id;
1429 ~numpunct() override;
1430 virtual char_type do_decimal_point() const;
1431 virtual char_type do_thousands_sep() const;
1432 virtual string do_grouping() const;
1433 virtual string_type do_truename() const;
1434 virtual string_type do_falsename() const;
1436 char_type __decimal_point_;
1437 char_type __thousands_sep_;
1441 #if _LIBCPP_HAS_WIDE_CHARACTERS
1443 class _LIBCPP_EXPORTED_FROM_ABI numpunct<wchar_t> : public locale::facet {
1445 typedef wchar_t char_type;
1446 typedef basic_string<char_type> string_type;
1448 explicit numpunct(size_t __refs = 0);
1450 _LIBCPP_HIDE_FROM_ABI char_type decimal_point() const { return do_decimal_point(); }
1451 _LIBCPP_HIDE_FROM_ABI char_type thousands_sep() const { return do_thousands_sep(); }
1452 _LIBCPP_HIDE_FROM_ABI string grouping() const { return do_grouping(); }
1453 _LIBCPP_HIDE_FROM_ABI string_type truename() const { return do_truename(); }
1454 _LIBCPP_HIDE_FROM_ABI string_type falsename() const { return do_falsename(); }
1456 static locale::id id;
1459 ~numpunct() override;
1460 virtual char_type do_decimal_point() const;
1461 virtual char_type do_thousands_sep() const;
1462 virtual string do_grouping() const;
1463 virtual string_type do_truename() const;
1464 virtual string_type do_falsename() const;
1466 char_type __decimal_point_;
1467 char_type __thousands_sep_;
1470 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
1472 // template <class charT> class numpunct_byname
1474 template <class _CharT>
1475 class _LIBCPP_TEMPLATE_VIS numpunct_byname;
1478 class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<char> : public numpunct<char> {
1480 typedef char char_type;
1481 typedef basic_string<char_type> string_type;
1483 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1484 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1487 ~numpunct_byname() override;
1490 void __init(const char*);
1493 #if _LIBCPP_HAS_WIDE_CHARACTERS
1495 class _LIBCPP_EXPORTED_FROM_ABI numpunct_byname<wchar_t> : public numpunct<wchar_t> {
1497 typedef wchar_t char_type;
1498 typedef basic_string<char_type> string_type;
1500 explicit numpunct_byname(const char* __nm, size_t __refs = 0);
1501 explicit numpunct_byname(const string& __nm, size_t __refs = 0);
1504 ~numpunct_byname() override;
1507 void __init(const char*);
1509 #endif // _LIBCPP_HAS_WIDE_CHARACTERS
1511 _LIBCPP_END_NAMESPACE_STD
1513 #endif // _LIBCPP___LOCALE