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