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 <mutex> 19#include <string> 20 21// Some platforms require more includes than others. Keep the includes on all plaforms for now. 22#include <cstddef> 23#include <cstring> 24 25#if defined(_LIBCPP_MSVCRT_LIKE) 26# include <__support/win32/locale_win32.h> 27#elif defined(_AIX) || defined(__MVS__) 28# include <__support/ibm/xlocale.h> 29#elif defined(__ANDROID__) 30# include <__support/android/locale_bionic.h> 31#elif defined(__sun__) 32# include <__support/solaris/xlocale.h> 33# include <xlocale.h> 34#elif defined(_NEWLIB_VERSION) 35# include <__support/newlib/xlocale.h> 36#elif defined(__OpenBSD__) 37# include <__support/openbsd/xlocale.h> 38#elif (defined(__APPLE__) || defined(__FreeBSD__)) 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 ~facet() override; 197 198// facet(const facet&) = delete; // effectively done in __shared_count 199// void operator=(const facet&) = delete; 200private: 201 void __on_zero_shared() _NOEXCEPT override; 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() override; 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 342extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS collate<char>; 343#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 344extern template 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() override; 365 int do_compare(const char_type* __lo1, const char_type* __hi1, 366 const char_type* __lo2, const char_type* __hi2) const override; 367 string_type do_transform(const char_type* __lo, const char_type* __hi) const override; 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() override; 385 386 int do_compare(const char_type* __lo1, const char_type* __hi1, 387 const char_type* __lo2, const char_type* __hi2) const override; 388 string_type do_transform(const char_type* __lo, const char_type* __hi) const override; 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 = 0x4000; // 0x8000 and 0x0100 and 0x00ff are used 456# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT 457# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA 458#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) 459# ifdef __APPLE__ 460 typedef __uint32_t mask; 461# elif defined(__FreeBSD__) 462 typedef unsigned long mask; 463# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__) 464 typedef unsigned short mask; 465# endif 466 static const mask space = _CTYPE_S; 467 static const mask print = _CTYPE_R; 468 static const mask cntrl = _CTYPE_C; 469 static const mask upper = _CTYPE_U; 470 static const mask lower = _CTYPE_L; 471 static const mask alpha = _CTYPE_A; 472 static const mask digit = _CTYPE_D; 473 static const mask punct = _CTYPE_P; 474 static const mask xdigit = _CTYPE_X; 475 476# if defined(__NetBSD__) 477 static const mask blank = _CTYPE_BL; 478 // NetBSD defines classes up to 0x2000 479 // see sys/ctype_bits.h, _CTYPE_Q 480 static const mask __regex_word = 0x8000; 481# else 482 static const mask blank = _CTYPE_B; 483 static const mask __regex_word = 0x80; 484# endif 485#elif defined(__sun__) || defined(_AIX) 486 typedef unsigned int mask; 487 static const mask space = _ISSPACE; 488 static const mask print = _ISPRINT; 489 static const mask cntrl = _ISCNTRL; 490 static const mask upper = _ISUPPER; 491 static const mask lower = _ISLOWER; 492 static const mask alpha = _ISALPHA; 493 static const mask digit = _ISDIGIT; 494 static const mask punct = _ISPUNCT; 495 static const mask xdigit = _ISXDIGIT; 496 static const mask blank = _ISBLANK; 497# if defined(_AIX) 498 static const mask __regex_word = 0x8000; 499# else 500 static const mask __regex_word = 0x80; 501# endif 502#elif defined(_NEWLIB_VERSION) 503 // Same type as Newlib's _ctype_ array in newlib/libc/include/ctype.h. 504 typedef char mask; 505 static const mask space = _S; 506 static const mask print = _P | _U | _L | _N | _B; 507 static const mask cntrl = _C; 508 static const mask upper = _U; 509 static const mask lower = _L; 510 static const mask alpha = _U | _L; 511 static const mask digit = _N; 512 static const mask punct = _P; 513 static const mask xdigit = _X | _N; 514 static const mask blank = _B; 515 // mask is already fully saturated, use a different type in regex_type_traits. 516 static const unsigned short __regex_word = 0x100; 517# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_PRINT 518# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA 519# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT 520#elif defined(__MVS__) 521# if defined(__NATIVE_ASCII_F) 522 typedef unsigned int mask; 523 static const mask space = _ISSPACE_A; 524 static const mask print = _ISPRINT_A; 525 static const mask cntrl = _ISCNTRL_A; 526 static const mask upper = _ISUPPER_A; 527 static const mask lower = _ISLOWER_A; 528 static const mask alpha = _ISALPHA_A; 529 static const mask digit = _ISDIGIT_A; 530 static const mask punct = _ISPUNCT_A; 531 static const mask xdigit = _ISXDIGIT_A; 532 static const mask blank = _ISBLANK_A; 533# else 534 typedef unsigned short mask; 535 static const mask space = __ISSPACE; 536 static const mask print = __ISPRINT; 537 static const mask cntrl = __ISCNTRL; 538 static const mask upper = __ISUPPER; 539 static const mask lower = __ISLOWER; 540 static const mask alpha = __ISALPHA; 541 static const mask digit = __ISDIGIT; 542 static const mask punct = __ISPUNCT; 543 static const mask xdigit = __ISXDIGIT; 544 static const mask blank = __ISBLANK; 545# endif 546 static const mask __regex_word = 0x8000; 547#else 548# error unknown rune table for this platform -- do you mean to define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE? 549#endif 550 static const mask alnum = alpha | digit; 551 static const mask graph = alnum | punct; 552 553 _LIBCPP_INLINE_VISIBILITY ctype_base() {} 554 555 static_assert((__regex_word & ~(std::make_unsigned<mask>::type)(space | print | cntrl | upper | lower | alpha | 556 digit | punct | xdigit | blank)) == __regex_word, 557 "__regex_word can't overlap other bits"); 558}; 559 560template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype; 561 562#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 563template <> 564class _LIBCPP_TYPE_VIS ctype<wchar_t> 565 : public locale::facet, 566 public ctype_base 567{ 568public: 569 typedef wchar_t char_type; 570 571 _LIBCPP_INLINE_VISIBILITY 572 explicit ctype(size_t __refs = 0) 573 : locale::facet(__refs) {} 574 575 _LIBCPP_INLINE_VISIBILITY 576 bool is(mask __m, char_type __c) const 577 { 578 return do_is(__m, __c); 579 } 580 581 _LIBCPP_INLINE_VISIBILITY 582 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const 583 { 584 return do_is(__low, __high, __vec); 585 } 586 587 _LIBCPP_INLINE_VISIBILITY 588 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const 589 { 590 return do_scan_is(__m, __low, __high); 591 } 592 593 _LIBCPP_INLINE_VISIBILITY 594 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const 595 { 596 return do_scan_not(__m, __low, __high); 597 } 598 599 _LIBCPP_INLINE_VISIBILITY 600 char_type toupper(char_type __c) const 601 { 602 return do_toupper(__c); 603 } 604 605 _LIBCPP_INLINE_VISIBILITY 606 const char_type* toupper(char_type* __low, const char_type* __high) const 607 { 608 return do_toupper(__low, __high); 609 } 610 611 _LIBCPP_INLINE_VISIBILITY 612 char_type tolower(char_type __c) const 613 { 614 return do_tolower(__c); 615 } 616 617 _LIBCPP_INLINE_VISIBILITY 618 const char_type* tolower(char_type* __low, const char_type* __high) const 619 { 620 return do_tolower(__low, __high); 621 } 622 623 _LIBCPP_INLINE_VISIBILITY 624 char_type widen(char __c) const 625 { 626 return do_widen(__c); 627 } 628 629 _LIBCPP_INLINE_VISIBILITY 630 const char* widen(const char* __low, const char* __high, char_type* __to) const 631 { 632 return do_widen(__low, __high, __to); 633 } 634 635 _LIBCPP_INLINE_VISIBILITY 636 char narrow(char_type __c, char __dfault) const 637 { 638 return do_narrow(__c, __dfault); 639 } 640 641 _LIBCPP_INLINE_VISIBILITY 642 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const 643 { 644 return do_narrow(__low, __high, __dfault, __to); 645 } 646 647 static locale::id id; 648 649protected: 650 ~ctype() override; 651 virtual bool do_is(mask __m, char_type __c) const; 652 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const; 653 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const; 654 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const; 655 virtual char_type do_toupper(char_type) const; 656 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; 657 virtual char_type do_tolower(char_type) const; 658 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; 659 virtual char_type do_widen(char) const; 660 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const; 661 virtual char do_narrow(char_type, char __dfault) const; 662 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const; 663}; 664#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 665 666template <> 667class _LIBCPP_TYPE_VIS ctype<char> 668 : public locale::facet, public ctype_base 669{ 670 const mask* __tab_; 671 bool __del_; 672public: 673 typedef char char_type; 674 675 explicit ctype(const mask* __tab = nullptr, bool __del = false, size_t __refs = 0); 676 677 _LIBCPP_INLINE_VISIBILITY 678 bool is(mask __m, char_type __c) const 679 { 680 return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false; 681 } 682 683 _LIBCPP_INLINE_VISIBILITY 684 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const 685 { 686 for (; __low != __high; ++__low, ++__vec) 687 *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0; 688 return __low; 689 } 690 691 _LIBCPP_INLINE_VISIBILITY 692 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const 693 { 694 for (; __low != __high; ++__low) 695 if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m)) 696 break; 697 return __low; 698 } 699 700 _LIBCPP_INLINE_VISIBILITY 701 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const 702 { 703 for (; __low != __high; ++__low) 704 if (!isascii(*__low) || !(__tab_[static_cast<int>(*__low)] & __m)) 705 break; 706 return __low; 707 } 708 709 _LIBCPP_INLINE_VISIBILITY 710 char_type toupper(char_type __c) const 711 { 712 return do_toupper(__c); 713 } 714 715 _LIBCPP_INLINE_VISIBILITY 716 const char_type* toupper(char_type* __low, const char_type* __high) const 717 { 718 return do_toupper(__low, __high); 719 } 720 721 _LIBCPP_INLINE_VISIBILITY 722 char_type tolower(char_type __c) const 723 { 724 return do_tolower(__c); 725 } 726 727 _LIBCPP_INLINE_VISIBILITY 728 const char_type* tolower(char_type* __low, const char_type* __high) const 729 { 730 return do_tolower(__low, __high); 731 } 732 733 _LIBCPP_INLINE_VISIBILITY 734 char_type widen(char __c) const 735 { 736 return do_widen(__c); 737 } 738 739 _LIBCPP_INLINE_VISIBILITY 740 const char* widen(const char* __low, const char* __high, char_type* __to) const 741 { 742 return do_widen(__low, __high, __to); 743 } 744 745 _LIBCPP_INLINE_VISIBILITY 746 char narrow(char_type __c, char __dfault) const 747 { 748 return do_narrow(__c, __dfault); 749 } 750 751 _LIBCPP_INLINE_VISIBILITY 752 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const 753 { 754 return do_narrow(__low, __high, __dfault, __to); 755 } 756 757 static locale::id id; 758 759#ifdef _CACHED_RUNES 760 static const size_t table_size = _CACHED_RUNES; 761#else 762 static const size_t table_size = 256; // FIXME: Don't hardcode this. 763#endif 764 _LIBCPP_INLINE_VISIBILITY const mask* table() const _NOEXCEPT {return __tab_;} 765 static const mask* classic_table() _NOEXCEPT; 766#if defined(__GLIBC__) || defined(__EMSCRIPTEN__) 767 static const int* __classic_upper_table() _NOEXCEPT; 768 static const int* __classic_lower_table() _NOEXCEPT; 769#endif 770#if defined(__NetBSD__) 771 static const short* __classic_upper_table() _NOEXCEPT; 772 static const short* __classic_lower_table() _NOEXCEPT; 773#endif 774#if defined(__MVS__) 775 static const unsigned short* __classic_upper_table() _NOEXCEPT; 776 static const unsigned short* __classic_lower_table() _NOEXCEPT; 777#endif 778 779protected: 780 ~ctype() override; 781 virtual char_type do_toupper(char_type __c) const; 782 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; 783 virtual char_type do_tolower(char_type __c) const; 784 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; 785 virtual char_type do_widen(char __c) const; 786 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const; 787 virtual char do_narrow(char_type __c, char __dfault) const; 788 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const; 789}; 790 791// template <class CharT> class ctype_byname; 792 793template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype_byname; 794 795template <> 796class _LIBCPP_TYPE_VIS ctype_byname<char> 797 : public ctype<char> 798{ 799 locale_t __l_; 800 801public: 802 explicit ctype_byname(const char*, size_t = 0); 803 explicit ctype_byname(const string&, size_t = 0); 804 805protected: 806 ~ctype_byname() override; 807 char_type do_toupper(char_type) const override; 808 const char_type* do_toupper(char_type* __low, const char_type* __high) const override; 809 char_type do_tolower(char_type) const override; 810 const char_type* do_tolower(char_type* __low, const char_type* __high) const override; 811}; 812 813#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 814template <> 815class _LIBCPP_TYPE_VIS ctype_byname<wchar_t> 816 : public ctype<wchar_t> 817{ 818 locale_t __l_; 819 820public: 821 explicit ctype_byname(const char*, size_t = 0); 822 explicit ctype_byname(const string&, size_t = 0); 823 824protected: 825 ~ctype_byname() override; 826 bool do_is(mask __m, char_type __c) const override; 827 const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const override; 828 const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const override; 829 const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const override; 830 char_type do_toupper(char_type) const override; 831 const char_type* do_toupper(char_type* __low, const char_type* __high) const override; 832 char_type do_tolower(char_type) const override; 833 const char_type* do_tolower(char_type* __low, const char_type* __high) const override; 834 char_type do_widen(char) const override; 835 const char* do_widen(const char* __low, const char* __high, char_type* __dest) const override; 836 char do_narrow(char_type, char __dfault) const override; 837 const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const override; 838}; 839#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 840 841template <class _CharT> 842inline _LIBCPP_INLINE_VISIBILITY 843bool 844isspace(_CharT __c, const locale& __loc) 845{ 846 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); 847} 848 849template <class _CharT> 850inline _LIBCPP_INLINE_VISIBILITY 851bool 852isprint(_CharT __c, const locale& __loc) 853{ 854 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); 855} 856 857template <class _CharT> 858inline _LIBCPP_INLINE_VISIBILITY 859bool 860iscntrl(_CharT __c, const locale& __loc) 861{ 862 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); 863} 864 865template <class _CharT> 866inline _LIBCPP_INLINE_VISIBILITY 867bool 868isupper(_CharT __c, const locale& __loc) 869{ 870 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); 871} 872 873template <class _CharT> 874inline _LIBCPP_INLINE_VISIBILITY 875bool 876islower(_CharT __c, const locale& __loc) 877{ 878 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); 879} 880 881template <class _CharT> 882inline _LIBCPP_INLINE_VISIBILITY 883bool 884isalpha(_CharT __c, const locale& __loc) 885{ 886 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); 887} 888 889template <class _CharT> 890inline _LIBCPP_INLINE_VISIBILITY 891bool 892isdigit(_CharT __c, const locale& __loc) 893{ 894 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); 895} 896 897template <class _CharT> 898inline _LIBCPP_INLINE_VISIBILITY 899bool 900ispunct(_CharT __c, const locale& __loc) 901{ 902 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); 903} 904 905template <class _CharT> 906inline _LIBCPP_INLINE_VISIBILITY 907bool 908isxdigit(_CharT __c, const locale& __loc) 909{ 910 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); 911} 912 913template <class _CharT> 914inline _LIBCPP_INLINE_VISIBILITY 915bool 916isalnum(_CharT __c, const locale& __loc) 917{ 918 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); 919} 920 921template <class _CharT> 922inline _LIBCPP_INLINE_VISIBILITY 923bool 924isgraph(_CharT __c, const locale& __loc) 925{ 926 return std::use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); 927} 928 929template <class _CharT> 930inline _LIBCPP_INLINE_VISIBILITY 931_CharT 932toupper(_CharT __c, const locale& __loc) 933{ 934 return std::use_facet<ctype<_CharT> >(__loc).toupper(__c); 935} 936 937template <class _CharT> 938inline _LIBCPP_INLINE_VISIBILITY 939_CharT 940tolower(_CharT __c, const locale& __loc) 941{ 942 return std::use_facet<ctype<_CharT> >(__loc).tolower(__c); 943} 944 945// codecvt_base 946 947class _LIBCPP_TYPE_VIS codecvt_base 948{ 949public: 950 _LIBCPP_INLINE_VISIBILITY codecvt_base() {} 951 enum result {ok, partial, error, noconv}; 952}; 953 954// template <class internT, class externT, class stateT> class codecvt; 955 956template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TEMPLATE_VIS codecvt; 957 958// template <> class codecvt<char, char, mbstate_t> 959 960template <> 961class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t> 962 : public locale::facet, 963 public codecvt_base 964{ 965public: 966 typedef char intern_type; 967 typedef char extern_type; 968 typedef mbstate_t state_type; 969 970 _LIBCPP_INLINE_VISIBILITY 971 explicit codecvt(size_t __refs = 0) 972 : locale::facet(__refs) {} 973 974 _LIBCPP_INLINE_VISIBILITY 975 result out(state_type& __st, 976 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 977 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 978 { 979 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 980 } 981 982 _LIBCPP_INLINE_VISIBILITY 983 result unshift(state_type& __st, 984 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 985 { 986 return do_unshift(__st, __to, __to_end, __to_nxt); 987 } 988 989 _LIBCPP_INLINE_VISIBILITY 990 result in(state_type& __st, 991 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 992 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const 993 { 994 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 995 } 996 997 _LIBCPP_INLINE_VISIBILITY 998 int encoding() const _NOEXCEPT 999 { 1000 return do_encoding(); 1001 } 1002 1003 _LIBCPP_INLINE_VISIBILITY 1004 bool always_noconv() const _NOEXCEPT 1005 { 1006 return do_always_noconv(); 1007 } 1008 1009 _LIBCPP_INLINE_VISIBILITY 1010 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const 1011 { 1012 return do_length(__st, __frm, __end, __mx); 1013 } 1014 1015 _LIBCPP_INLINE_VISIBILITY 1016 int max_length() const _NOEXCEPT 1017 { 1018 return do_max_length(); 1019 } 1020 1021 static locale::id id; 1022 1023protected: 1024 _LIBCPP_INLINE_VISIBILITY 1025 explicit codecvt(const char*, size_t __refs = 0) 1026 : locale::facet(__refs) {} 1027 1028 ~codecvt() override; 1029 1030 virtual result do_out(state_type& __st, 1031 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1032 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1033 virtual result do_in(state_type& __st, 1034 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1035 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; 1036 virtual result do_unshift(state_type& __st, 1037 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1038 virtual int do_encoding() const _NOEXCEPT; 1039 virtual bool do_always_noconv() const _NOEXCEPT; 1040 virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const; 1041 virtual int do_max_length() const _NOEXCEPT; 1042}; 1043 1044// template <> class codecvt<wchar_t, char, mbstate_t> 1045 1046#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1047template <> 1048class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t> 1049 : public locale::facet, 1050 public codecvt_base 1051{ 1052 locale_t __l_; 1053public: 1054 typedef wchar_t intern_type; 1055 typedef char extern_type; 1056 typedef mbstate_t state_type; 1057 1058 explicit codecvt(size_t __refs = 0); 1059 1060 _LIBCPP_INLINE_VISIBILITY 1061 result out(state_type& __st, 1062 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1063 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1064 { 1065 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1066 } 1067 1068 _LIBCPP_INLINE_VISIBILITY 1069 result unshift(state_type& __st, 1070 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1071 { 1072 return do_unshift(__st, __to, __to_end, __to_nxt); 1073 } 1074 1075 _LIBCPP_INLINE_VISIBILITY 1076 result in(state_type& __st, 1077 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1078 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const 1079 { 1080 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1081 } 1082 1083 _LIBCPP_INLINE_VISIBILITY 1084 int encoding() const _NOEXCEPT 1085 { 1086 return do_encoding(); 1087 } 1088 1089 _LIBCPP_INLINE_VISIBILITY 1090 bool always_noconv() const _NOEXCEPT 1091 { 1092 return do_always_noconv(); 1093 } 1094 1095 _LIBCPP_INLINE_VISIBILITY 1096 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const 1097 { 1098 return do_length(__st, __frm, __end, __mx); 1099 } 1100 1101 _LIBCPP_INLINE_VISIBILITY 1102 int max_length() const _NOEXCEPT 1103 { 1104 return do_max_length(); 1105 } 1106 1107 static locale::id id; 1108 1109protected: 1110 explicit codecvt(const char*, size_t __refs = 0); 1111 1112 ~codecvt() override; 1113 1114 virtual result do_out(state_type& __st, 1115 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1116 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1117 virtual result do_in(state_type& __st, 1118 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1119 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; 1120 virtual result do_unshift(state_type& __st, 1121 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1122 virtual int do_encoding() const _NOEXCEPT; 1123 virtual bool do_always_noconv() const _NOEXCEPT; 1124 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; 1125 virtual int do_max_length() const _NOEXCEPT; 1126}; 1127#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 1128 1129// template <> class codecvt<char16_t, char, mbstate_t> // deprecated in C++20 1130 1131template <> 1132class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t> 1133 : public locale::facet, 1134 public codecvt_base 1135{ 1136public: 1137 typedef char16_t intern_type; 1138 typedef char extern_type; 1139 typedef mbstate_t state_type; 1140 1141 _LIBCPP_INLINE_VISIBILITY 1142 explicit codecvt(size_t __refs = 0) 1143 : locale::facet(__refs) {} 1144 1145 _LIBCPP_INLINE_VISIBILITY 1146 result out(state_type& __st, 1147 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1148 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1149 { 1150 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1151 } 1152 1153 _LIBCPP_INLINE_VISIBILITY 1154 result unshift(state_type& __st, 1155 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1156 { 1157 return do_unshift(__st, __to, __to_end, __to_nxt); 1158 } 1159 1160 _LIBCPP_INLINE_VISIBILITY 1161 result in(state_type& __st, 1162 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1163 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const 1164 { 1165 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1166 } 1167 1168 _LIBCPP_INLINE_VISIBILITY 1169 int encoding() const _NOEXCEPT 1170 { 1171 return do_encoding(); 1172 } 1173 1174 _LIBCPP_INLINE_VISIBILITY 1175 bool always_noconv() const _NOEXCEPT 1176 { 1177 return do_always_noconv(); 1178 } 1179 1180 _LIBCPP_INLINE_VISIBILITY 1181 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const 1182 { 1183 return do_length(__st, __frm, __end, __mx); 1184 } 1185 1186 _LIBCPP_INLINE_VISIBILITY 1187 int max_length() const _NOEXCEPT 1188 { 1189 return do_max_length(); 1190 } 1191 1192 static locale::id id; 1193 1194protected: 1195 _LIBCPP_INLINE_VISIBILITY 1196 explicit codecvt(const char*, size_t __refs = 0) 1197 : locale::facet(__refs) {} 1198 1199 ~codecvt() override; 1200 1201 virtual result do_out(state_type& __st, 1202 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1203 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1204 virtual result do_in(state_type& __st, 1205 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1206 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; 1207 virtual result do_unshift(state_type& __st, 1208 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1209 virtual int do_encoding() const _NOEXCEPT; 1210 virtual bool do_always_noconv() const _NOEXCEPT; 1211 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; 1212 virtual int do_max_length() const _NOEXCEPT; 1213}; 1214 1215#ifndef _LIBCPP_HAS_NO_CHAR8_T 1216 1217// template <> class codecvt<char16_t, char8_t, mbstate_t> // C++20 1218 1219template <> 1220class _LIBCPP_TYPE_VIS codecvt<char16_t, char8_t, mbstate_t> 1221 : public locale::facet, 1222 public codecvt_base 1223{ 1224public: 1225 typedef char16_t intern_type; 1226 typedef char8_t extern_type; 1227 typedef mbstate_t state_type; 1228 1229 _LIBCPP_INLINE_VISIBILITY 1230 explicit codecvt(size_t __refs = 0) 1231 : locale::facet(__refs) {} 1232 1233 _LIBCPP_INLINE_VISIBILITY 1234 result out(state_type& __st, 1235 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1236 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1237 { 1238 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1239 } 1240 1241 _LIBCPP_INLINE_VISIBILITY 1242 result unshift(state_type& __st, 1243 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1244 { 1245 return do_unshift(__st, __to, __to_end, __to_nxt); 1246 } 1247 1248 _LIBCPP_INLINE_VISIBILITY 1249 result in(state_type& __st, 1250 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1251 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const 1252 { 1253 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1254 } 1255 1256 _LIBCPP_INLINE_VISIBILITY 1257 int encoding() const _NOEXCEPT 1258 { 1259 return do_encoding(); 1260 } 1261 1262 _LIBCPP_INLINE_VISIBILITY 1263 bool always_noconv() const _NOEXCEPT 1264 { 1265 return do_always_noconv(); 1266 } 1267 1268 _LIBCPP_INLINE_VISIBILITY 1269 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const 1270 { 1271 return do_length(__st, __frm, __end, __mx); 1272 } 1273 1274 _LIBCPP_INLINE_VISIBILITY 1275 int max_length() const _NOEXCEPT 1276 { 1277 return do_max_length(); 1278 } 1279 1280 static locale::id id; 1281 1282protected: 1283 _LIBCPP_INLINE_VISIBILITY 1284 explicit codecvt(const char*, size_t __refs = 0) 1285 : locale::facet(__refs) {} 1286 1287 ~codecvt() override; 1288 1289 virtual result do_out(state_type& __st, 1290 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1291 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1292 virtual result do_in(state_type& __st, 1293 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1294 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; 1295 virtual result do_unshift(state_type& __st, 1296 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1297 virtual int do_encoding() const _NOEXCEPT; 1298 virtual bool do_always_noconv() const _NOEXCEPT; 1299 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; 1300 virtual int do_max_length() const _NOEXCEPT; 1301}; 1302 1303#endif 1304 1305// template <> class codecvt<char32_t, char, mbstate_t> // deprecated in C++20 1306 1307template <> 1308class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t> 1309 : public locale::facet, 1310 public codecvt_base 1311{ 1312public: 1313 typedef char32_t intern_type; 1314 typedef char extern_type; 1315 typedef mbstate_t state_type; 1316 1317 _LIBCPP_INLINE_VISIBILITY 1318 explicit codecvt(size_t __refs = 0) 1319 : locale::facet(__refs) {} 1320 1321 _LIBCPP_INLINE_VISIBILITY 1322 result out(state_type& __st, 1323 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1324 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1325 { 1326 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1327 } 1328 1329 _LIBCPP_INLINE_VISIBILITY 1330 result unshift(state_type& __st, 1331 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1332 { 1333 return do_unshift(__st, __to, __to_end, __to_nxt); 1334 } 1335 1336 _LIBCPP_INLINE_VISIBILITY 1337 result in(state_type& __st, 1338 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1339 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const 1340 { 1341 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1342 } 1343 1344 _LIBCPP_INLINE_VISIBILITY 1345 int encoding() const _NOEXCEPT 1346 { 1347 return do_encoding(); 1348 } 1349 1350 _LIBCPP_INLINE_VISIBILITY 1351 bool always_noconv() const _NOEXCEPT 1352 { 1353 return do_always_noconv(); 1354 } 1355 1356 _LIBCPP_INLINE_VISIBILITY 1357 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const 1358 { 1359 return do_length(__st, __frm, __end, __mx); 1360 } 1361 1362 _LIBCPP_INLINE_VISIBILITY 1363 int max_length() const _NOEXCEPT 1364 { 1365 return do_max_length(); 1366 } 1367 1368 static locale::id id; 1369 1370protected: 1371 _LIBCPP_INLINE_VISIBILITY 1372 explicit codecvt(const char*, size_t __refs = 0) 1373 : locale::facet(__refs) {} 1374 1375 ~codecvt() override; 1376 1377 virtual result do_out(state_type& __st, 1378 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1379 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1380 virtual result do_in(state_type& __st, 1381 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1382 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; 1383 virtual result do_unshift(state_type& __st, 1384 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1385 virtual int do_encoding() const _NOEXCEPT; 1386 virtual bool do_always_noconv() const _NOEXCEPT; 1387 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; 1388 virtual int do_max_length() const _NOEXCEPT; 1389}; 1390 1391#ifndef _LIBCPP_HAS_NO_CHAR8_T 1392 1393// template <> class codecvt<char32_t, char8_t, mbstate_t> // C++20 1394 1395template <> 1396class _LIBCPP_TYPE_VIS codecvt<char32_t, char8_t, mbstate_t> 1397 : public locale::facet, 1398 public codecvt_base 1399{ 1400public: 1401 typedef char32_t intern_type; 1402 typedef char8_t extern_type; 1403 typedef mbstate_t state_type; 1404 1405 _LIBCPP_INLINE_VISIBILITY 1406 explicit codecvt(size_t __refs = 0) 1407 : locale::facet(__refs) {} 1408 1409 _LIBCPP_INLINE_VISIBILITY 1410 result out(state_type& __st, 1411 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1412 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1413 { 1414 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1415 } 1416 1417 _LIBCPP_INLINE_VISIBILITY 1418 result unshift(state_type& __st, 1419 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1420 { 1421 return do_unshift(__st, __to, __to_end, __to_nxt); 1422 } 1423 1424 _LIBCPP_INLINE_VISIBILITY 1425 result in(state_type& __st, 1426 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1427 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const 1428 { 1429 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1430 } 1431 1432 _LIBCPP_INLINE_VISIBILITY 1433 int encoding() const _NOEXCEPT 1434 { 1435 return do_encoding(); 1436 } 1437 1438 _LIBCPP_INLINE_VISIBILITY 1439 bool always_noconv() const _NOEXCEPT 1440 { 1441 return do_always_noconv(); 1442 } 1443 1444 _LIBCPP_INLINE_VISIBILITY 1445 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const 1446 { 1447 return do_length(__st, __frm, __end, __mx); 1448 } 1449 1450 _LIBCPP_INLINE_VISIBILITY 1451 int max_length() const _NOEXCEPT 1452 { 1453 return do_max_length(); 1454 } 1455 1456 static locale::id id; 1457 1458protected: 1459 _LIBCPP_INLINE_VISIBILITY 1460 explicit codecvt(const char*, size_t __refs = 0) 1461 : locale::facet(__refs) {} 1462 1463 ~codecvt() override; 1464 1465 virtual result do_out(state_type& __st, 1466 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1467 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1468 virtual result do_in(state_type& __st, 1469 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1470 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; 1471 virtual result do_unshift(state_type& __st, 1472 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1473 virtual int do_encoding() const _NOEXCEPT; 1474 virtual bool do_always_noconv() const _NOEXCEPT; 1475 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; 1476 virtual int do_max_length() const _NOEXCEPT; 1477}; 1478 1479#endif 1480 1481// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname 1482 1483template <class _InternT, class _ExternT, class _StateT> 1484class _LIBCPP_TEMPLATE_VIS codecvt_byname 1485 : public codecvt<_InternT, _ExternT, _StateT> 1486{ 1487public: 1488 _LIBCPP_INLINE_VISIBILITY 1489 explicit codecvt_byname(const char* __nm, size_t __refs = 0) 1490 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {} 1491 _LIBCPP_INLINE_VISIBILITY 1492 explicit codecvt_byname(const string& __nm, size_t __refs = 0) 1493 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {} 1494protected: 1495 ~codecvt_byname() override; 1496}; 1497 1498_LIBCPP_SUPPRESS_DEPRECATED_PUSH 1499template <class _InternT, class _ExternT, class _StateT> 1500codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname() 1501{ 1502} 1503_LIBCPP_SUPPRESS_DEPRECATED_POP 1504 1505extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char, char, mbstate_t>; 1506#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1507extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<wchar_t, char, mbstate_t>; 1508#endif 1509extern template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>; // deprecated in C++20 1510extern template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>; // deprecated in C++20 1511#ifndef _LIBCPP_HAS_NO_CHAR8_T 1512extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char8_t, mbstate_t>; // C++20 1513extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char8_t, mbstate_t>; // C++20 1514#endif 1515 1516template <size_t _Np> 1517struct __narrow_to_utf8 1518{ 1519 template <class _OutputIterator, class _CharT> 1520 _OutputIterator 1521 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const; 1522}; 1523 1524template <> 1525struct __narrow_to_utf8<8> 1526{ 1527 template <class _OutputIterator, class _CharT> 1528 _LIBCPP_INLINE_VISIBILITY 1529 _OutputIterator 1530 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const 1531 { 1532 for (; __wb < __we; ++__wb, ++__s) 1533 *__s = *__wb; 1534 return __s; 1535 } 1536}; 1537 1538_LIBCPP_SUPPRESS_DEPRECATED_PUSH 1539template <> 1540struct _LIBCPP_TYPE_VIS __narrow_to_utf8<16> 1541 : public codecvt<char16_t, char, mbstate_t> 1542{ 1543 _LIBCPP_INLINE_VISIBILITY 1544 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {} 1545_LIBCPP_SUPPRESS_DEPRECATED_POP 1546 1547 ~__narrow_to_utf8() override; 1548 1549 template <class _OutputIterator, class _CharT> 1550 _LIBCPP_INLINE_VISIBILITY 1551 _OutputIterator 1552 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const 1553 { 1554 result __r = ok; 1555 mbstate_t __mb; 1556 while (__wb < __we && __r != error) 1557 { 1558 const int __sz = 32; 1559 char __buf[__sz]; 1560 char* __bn; 1561 const char16_t* __wn = (const char16_t*)__wb; 1562 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn, 1563 __buf, __buf+__sz, __bn); 1564 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb) 1565 __throw_runtime_error("locale not supported"); 1566 for (const char* __p = __buf; __p < __bn; ++__p, ++__s) 1567 *__s = *__p; 1568 __wb = (const _CharT*)__wn; 1569 } 1570 return __s; 1571 } 1572}; 1573 1574_LIBCPP_SUPPRESS_DEPRECATED_PUSH 1575template <> 1576struct _LIBCPP_TYPE_VIS __narrow_to_utf8<32> 1577 : public codecvt<char32_t, char, mbstate_t> 1578{ 1579 _LIBCPP_INLINE_VISIBILITY 1580 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {} 1581_LIBCPP_SUPPRESS_DEPRECATED_POP 1582 1583 ~__narrow_to_utf8() override; 1584 1585 template <class _OutputIterator, class _CharT> 1586 _LIBCPP_INLINE_VISIBILITY 1587 _OutputIterator 1588 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const 1589 { 1590 result __r = ok; 1591 mbstate_t __mb; 1592 while (__wb < __we && __r != error) 1593 { 1594 const int __sz = 32; 1595 char __buf[__sz]; 1596 char* __bn; 1597 const char32_t* __wn = (const char32_t*)__wb; 1598 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn, 1599 __buf, __buf+__sz, __bn); 1600 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb) 1601 __throw_runtime_error("locale not supported"); 1602 for (const char* __p = __buf; __p < __bn; ++__p, ++__s) 1603 *__s = *__p; 1604 __wb = (const _CharT*)__wn; 1605 } 1606 return __s; 1607 } 1608}; 1609 1610template <size_t _Np> 1611struct __widen_from_utf8 1612{ 1613 template <class _OutputIterator> 1614 _OutputIterator 1615 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const; 1616}; 1617 1618template <> 1619struct __widen_from_utf8<8> 1620{ 1621 template <class _OutputIterator> 1622 _LIBCPP_INLINE_VISIBILITY 1623 _OutputIterator 1624 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const 1625 { 1626 for (; __nb < __ne; ++__nb, ++__s) 1627 *__s = *__nb; 1628 return __s; 1629 } 1630}; 1631 1632_LIBCPP_SUPPRESS_DEPRECATED_PUSH 1633template <> 1634struct _LIBCPP_TYPE_VIS __widen_from_utf8<16> 1635 : public codecvt<char16_t, char, mbstate_t> 1636{ 1637 _LIBCPP_INLINE_VISIBILITY 1638 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {} 1639_LIBCPP_SUPPRESS_DEPRECATED_POP 1640 1641 ~__widen_from_utf8() override; 1642 1643 template <class _OutputIterator> 1644 _LIBCPP_INLINE_VISIBILITY 1645 _OutputIterator 1646 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const 1647 { 1648 result __r = ok; 1649 mbstate_t __mb; 1650 while (__nb < __ne && __r != error) 1651 { 1652 const int __sz = 32; 1653 char16_t __buf[__sz]; 1654 char16_t* __bn; 1655 const char* __nn = __nb; 1656 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn, 1657 __buf, __buf+__sz, __bn); 1658 if (__r == codecvt_base::error || __nn == __nb) 1659 __throw_runtime_error("locale not supported"); 1660 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s) 1661 *__s = *__p; 1662 __nb = __nn; 1663 } 1664 return __s; 1665 } 1666}; 1667 1668_LIBCPP_SUPPRESS_DEPRECATED_PUSH 1669template <> 1670struct _LIBCPP_TYPE_VIS __widen_from_utf8<32> 1671 : public codecvt<char32_t, char, mbstate_t> 1672{ 1673 _LIBCPP_INLINE_VISIBILITY 1674 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {} 1675_LIBCPP_SUPPRESS_DEPRECATED_POP 1676 1677 ~__widen_from_utf8() override; 1678 1679 template <class _OutputIterator> 1680 _LIBCPP_INLINE_VISIBILITY 1681 _OutputIterator 1682 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const 1683 { 1684 result __r = ok; 1685 mbstate_t __mb; 1686 while (__nb < __ne && __r != error) 1687 { 1688 const int __sz = 32; 1689 char32_t __buf[__sz]; 1690 char32_t* __bn; 1691 const char* __nn = __nb; 1692 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn, 1693 __buf, __buf+__sz, __bn); 1694 if (__r == codecvt_base::error || __nn == __nb) 1695 __throw_runtime_error("locale not supported"); 1696 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s) 1697 *__s = *__p; 1698 __nb = __nn; 1699 } 1700 return __s; 1701 } 1702}; 1703 1704// template <class charT> class numpunct 1705 1706template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct; 1707 1708template <> 1709class _LIBCPP_TYPE_VIS numpunct<char> 1710 : public locale::facet 1711{ 1712public: 1713 typedef char char_type; 1714 typedef basic_string<char_type> string_type; 1715 1716 explicit numpunct(size_t __refs = 0); 1717 1718 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();} 1719 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();} 1720 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();} 1721 _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();} 1722 _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();} 1723 1724 static locale::id id; 1725 1726protected: 1727 ~numpunct() override; 1728 virtual char_type do_decimal_point() const; 1729 virtual char_type do_thousands_sep() const; 1730 virtual string do_grouping() const; 1731 virtual string_type do_truename() const; 1732 virtual string_type do_falsename() const; 1733 1734 char_type __decimal_point_; 1735 char_type __thousands_sep_; 1736 string __grouping_; 1737}; 1738 1739#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1740template <> 1741class _LIBCPP_TYPE_VIS numpunct<wchar_t> 1742 : public locale::facet 1743{ 1744public: 1745 typedef wchar_t char_type; 1746 typedef basic_string<char_type> string_type; 1747 1748 explicit numpunct(size_t __refs = 0); 1749 1750 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();} 1751 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();} 1752 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();} 1753 _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();} 1754 _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();} 1755 1756 static locale::id id; 1757 1758protected: 1759 ~numpunct() override; 1760 virtual char_type do_decimal_point() const; 1761 virtual char_type do_thousands_sep() const; 1762 virtual string do_grouping() const; 1763 virtual string_type do_truename() const; 1764 virtual string_type do_falsename() const; 1765 1766 char_type __decimal_point_; 1767 char_type __thousands_sep_; 1768 string __grouping_; 1769}; 1770#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 1771 1772// template <class charT> class numpunct_byname 1773 1774template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct_byname; 1775 1776template <> 1777class _LIBCPP_TYPE_VIS numpunct_byname<char> 1778: public numpunct<char> 1779{ 1780public: 1781 typedef char char_type; 1782 typedef basic_string<char_type> string_type; 1783 1784 explicit numpunct_byname(const char* __nm, size_t __refs = 0); 1785 explicit numpunct_byname(const string& __nm, size_t __refs = 0); 1786 1787protected: 1788 ~numpunct_byname() override; 1789 1790private: 1791 void __init(const char*); 1792}; 1793 1794#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 1795template <> 1796class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t> 1797: public numpunct<wchar_t> 1798{ 1799public: 1800 typedef wchar_t char_type; 1801 typedef basic_string<char_type> string_type; 1802 1803 explicit numpunct_byname(const char* __nm, size_t __refs = 0); 1804 explicit numpunct_byname(const string& __nm, size_t __refs = 0); 1805 1806protected: 1807 ~numpunct_byname() override; 1808 1809private: 1810 void __init(const char*); 1811}; 1812#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 1813 1814_LIBCPP_END_NAMESPACE_STD 1815 1816#endif // _LIBCPP___LOCALE 1817