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