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