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