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