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