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