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