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