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