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