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