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