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) 49struct __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_; 60private: 61 __libcpp_locale_guard(__libcpp_locale_guard const&); 62 __libcpp_locale_guard& operator=(__libcpp_locale_guard const&); 63}; 64#elif defined(_LIBCPP_MSVCRT_LIKE) 65struct __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 93class _LIBCPP_TYPE_VIS locale; 94 95template <class _Facet> 96_LIBCPP_INLINE_VISIBILITY 97bool 98has_facet(const locale&) _NOEXCEPT; 99 100template <class _Facet> 101_LIBCPP_INLINE_VISIBILITY 102const _Facet& 103use_facet(const locale&); 104 105class _LIBCPP_TYPE_VIS locale 106{ 107public: 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 156private: 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 169class _LIBCPP_TYPE_VIS locale::facet 170 : public __shared_count 171{ 172protected: 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; 181private: 182 virtual void __on_zero_shared() _NOEXCEPT; 183}; 184 185class _LIBCPP_TYPE_VIS locale::id 186{ 187 once_flag __flag_; 188 int32_t __id_; 189 190 static int32_t __next_id; 191public: 192 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {} 193private: 194 void __init(); 195 void operator=(const id&); // = delete; 196 id(const id&); // = delete; 197public: // only needed for tests 198 long __get(); 199 200 friend class locale; 201 friend class locale::__imp; 202}; 203 204template <class _Facet> 205inline _LIBCPP_INLINE_VISIBILITY 206locale::locale(const locale& __other, _Facet* __f) 207{ 208 __install_ctor(__other, __f, __f ? __f->id.__get() : 0); 209} 210 211template <class _Facet> 212locale 213locale::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 221template <class _Facet> 222inline _LIBCPP_INLINE_VISIBILITY 223bool 224has_facet(const locale& __l) _NOEXCEPT 225{ 226 return __l.has_facet(_Facet::id); 227} 228 229template <class _Facet> 230inline _LIBCPP_INLINE_VISIBILITY 231const _Facet& 232use_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 239template <class _CharT> 240class _LIBCPP_TEMPLATE_VIS collate 241 : public locale::facet 242{ 243public: 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 272protected: 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 281template <class _CharT> locale::id collate<_CharT>::id; 282 283template <class _CharT> 284collate<_CharT>::~collate() 285{ 286} 287 288template <class _CharT> 289int 290collate<_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 303template <class _CharT> 304long 305collate<_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 324template <class _CharT> class _LIBCPP_TEMPLATE_VIS collate_byname; 325 326template <> 327class _LIBCPP_TYPE_VIS collate_byname<char> 328 : public collate<char> 329{ 330 locale_t __l; 331public: 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 338protected: 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 345template <> 346class _LIBCPP_TYPE_VIS collate_byname<wchar_t> 347 : public collate<wchar_t> 348{ 349 locale_t __l; 350public: 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 357protected: 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 365template <class _CharT, class _Traits, class _Allocator> 366bool 367locale::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 377class _LIBCPP_TYPE_VIS ctype_base 378{ 379public: 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 475template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype; 476 477template <> 478class _LIBCPP_TYPE_VIS ctype<wchar_t> 479 : public locale::facet, 480 public ctype_base 481{ 482public: 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 563protected: 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 579template <> 580class _LIBCPP_TYPE_VIS ctype<char> 581 : public locale::facet, public ctype_base 582{ 583 const mask* __tab_; 584 bool __del_; 585public: 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 688protected: 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 702template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype_byname; 703 704template <> 705class _LIBCPP_TYPE_VIS ctype_byname<char> 706 : public ctype<char> 707{ 708 locale_t __l; 709 710public: 711 explicit ctype_byname(const char*, size_t = 0); 712 explicit ctype_byname(const string&, size_t = 0); 713 714protected: 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 722template <> 723class _LIBCPP_TYPE_VIS ctype_byname<wchar_t> 724 : public ctype<wchar_t> 725{ 726 locale_t __l; 727 728public: 729 explicit ctype_byname(const char*, size_t = 0); 730 explicit ctype_byname(const string&, size_t = 0); 731 732protected: 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 748template <class _CharT> 749inline _LIBCPP_INLINE_VISIBILITY 750bool 751isspace(_CharT __c, const locale& __loc) 752{ 753 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); 754} 755 756template <class _CharT> 757inline _LIBCPP_INLINE_VISIBILITY 758bool 759isprint(_CharT __c, const locale& __loc) 760{ 761 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); 762} 763 764template <class _CharT> 765inline _LIBCPP_INLINE_VISIBILITY 766bool 767iscntrl(_CharT __c, const locale& __loc) 768{ 769 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); 770} 771 772template <class _CharT> 773inline _LIBCPP_INLINE_VISIBILITY 774bool 775isupper(_CharT __c, const locale& __loc) 776{ 777 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); 778} 779 780template <class _CharT> 781inline _LIBCPP_INLINE_VISIBILITY 782bool 783islower(_CharT __c, const locale& __loc) 784{ 785 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); 786} 787 788template <class _CharT> 789inline _LIBCPP_INLINE_VISIBILITY 790bool 791isalpha(_CharT __c, const locale& __loc) 792{ 793 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); 794} 795 796template <class _CharT> 797inline _LIBCPP_INLINE_VISIBILITY 798bool 799isdigit(_CharT __c, const locale& __loc) 800{ 801 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); 802} 803 804template <class _CharT> 805inline _LIBCPP_INLINE_VISIBILITY 806bool 807ispunct(_CharT __c, const locale& __loc) 808{ 809 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); 810} 811 812template <class _CharT> 813inline _LIBCPP_INLINE_VISIBILITY 814bool 815isxdigit(_CharT __c, const locale& __loc) 816{ 817 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); 818} 819 820template <class _CharT> 821inline _LIBCPP_INLINE_VISIBILITY 822bool 823isalnum(_CharT __c, const locale& __loc) 824{ 825 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); 826} 827 828template <class _CharT> 829inline _LIBCPP_INLINE_VISIBILITY 830bool 831isgraph(_CharT __c, const locale& __loc) 832{ 833 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); 834} 835 836template <class _CharT> 837inline _LIBCPP_INLINE_VISIBILITY 838_CharT 839toupper(_CharT __c, const locale& __loc) 840{ 841 return use_facet<ctype<_CharT> >(__loc).toupper(__c); 842} 843 844template <class _CharT> 845inline _LIBCPP_INLINE_VISIBILITY 846_CharT 847tolower(_CharT __c, const locale& __loc) 848{ 849 return use_facet<ctype<_CharT> >(__loc).tolower(__c); 850} 851 852// codecvt_base 853 854class _LIBCPP_TYPE_VIS codecvt_base 855{ 856public: 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 863template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TEMPLATE_VIS codecvt; 864 865// template <> class codecvt<char, char, mbstate_t> 866 867template <> 868class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t> 869 : public locale::facet, 870 public codecvt_base 871{ 872public: 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 930protected: 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 953template <> 954class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t> 955 : public locale::facet, 956 public codecvt_base 957{ 958 locale_t __l; 959public: 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 1015protected: 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 1036template <> 1037class _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t> 1038 : public locale::facet, 1039 public codecvt_base 1040{ 1041public: 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 1099protected: 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 1122template <> 1123class _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t> 1124 : public locale::facet, 1125 public codecvt_base 1126{ 1127public: 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 1185protected: 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 1208template <class _InternT, class _ExternT, class _StateT> 1209class _LIBCPP_TEMPLATE_VIS codecvt_byname 1210 : public codecvt<_InternT, _ExternT, _StateT> 1211{ 1212public: 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) {} 1219protected: 1220 ~codecvt_byname(); 1221}; 1222 1223template <class _InternT, class _ExternT, class _StateT> 1224codecvt_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 1235template <size_t _Np> 1236struct __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 1243template <> 1244struct __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 1257template <> 1258struct _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 1291template <> 1292struct _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 1325template <size_t _Np> 1326struct __widen_from_utf8 1327{ 1328 template <class _OutputIterator> 1329 _OutputIterator 1330 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const; 1331}; 1332 1333template <> 1334struct __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 1347template <> 1348struct _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 1381template <> 1382struct _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 1417template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct; 1418 1419template <> 1420class _LIBCPP_TYPE_VIS numpunct<char> 1421 : public locale::facet 1422{ 1423public: 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 1437protected: 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 1450template <> 1451class _LIBCPP_TYPE_VIS numpunct<wchar_t> 1452 : public locale::facet 1453{ 1454public: 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 1468protected: 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 1483template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct_byname; 1484 1485template <> 1486class _LIBCPP_TYPE_VIS numpunct_byname<char> 1487: public numpunct<char> 1488{ 1489public: 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 1496protected: 1497 ~numpunct_byname(); 1498 1499private: 1500 void __init(const char*); 1501}; 1502 1503template <> 1504class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t> 1505: public numpunct<wchar_t> 1506{ 1507public: 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 1514protected: 1515 ~numpunct_byname(); 1516 1517private: 1518 void __init(const char*); 1519}; 1520 1521_LIBCPP_END_NAMESPACE_STD 1522 1523#endif // _LIBCPP___LOCALE 1524