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