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