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