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