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