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 1233template <size_t _Np> 1234struct __narrow_to_utf8 1235{ 1236 template <class _OutputIterator, class _CharT> 1237 _OutputIterator 1238 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const; 1239}; 1240 1241template <> 1242struct __narrow_to_utf8<8> 1243{ 1244 template <class _OutputIterator, class _CharT> 1245 _LIBCPP_INLINE_VISIBILITY 1246 _OutputIterator 1247 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const 1248 { 1249 for (; __wb < __we; ++__wb, ++__s) 1250 *__s = *__wb; 1251 return __s; 1252 } 1253}; 1254 1255template <> 1256struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16> 1257 : public codecvt<char16_t, char, mbstate_t> 1258{ 1259 _LIBCPP_INLINE_VISIBILITY 1260 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {} 1261 1262 _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8(); 1263 1264 template <class _OutputIterator, class _CharT> 1265 _LIBCPP_INLINE_VISIBILITY 1266 _OutputIterator 1267 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const 1268 { 1269 result __r = ok; 1270 mbstate_t __mb; 1271 while (__wb < __we && __r != error) 1272 { 1273 const int __sz = 32; 1274 char __buf[__sz]; 1275 char* __bn; 1276 const char16_t* __wn = (const char16_t*)__wb; 1277 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn, 1278 __buf, __buf+__sz, __bn); 1279 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb) 1280 __throw_runtime_error("locale not supported"); 1281 for (const char* __p = __buf; __p < __bn; ++__p, ++__s) 1282 *__s = *__p; 1283 __wb = (const _CharT*)__wn; 1284 } 1285 return __s; 1286 } 1287}; 1288 1289template <> 1290struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32> 1291 : public codecvt<char32_t, char, mbstate_t> 1292{ 1293 _LIBCPP_INLINE_VISIBILITY 1294 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {} 1295 1296 _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8(); 1297 1298 template <class _OutputIterator, class _CharT> 1299 _LIBCPP_INLINE_VISIBILITY 1300 _OutputIterator 1301 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const 1302 { 1303 result __r = ok; 1304 mbstate_t __mb; 1305 while (__wb < __we && __r != error) 1306 { 1307 const int __sz = 32; 1308 char __buf[__sz]; 1309 char* __bn; 1310 const char32_t* __wn = (const char32_t*)__wb; 1311 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn, 1312 __buf, __buf+__sz, __bn); 1313 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb) 1314 __throw_runtime_error("locale not supported"); 1315 for (const char* __p = __buf; __p < __bn; ++__p, ++__s) 1316 *__s = *__p; 1317 __wb = (const _CharT*)__wn; 1318 } 1319 return __s; 1320 } 1321}; 1322 1323template <size_t _Np> 1324struct __widen_from_utf8 1325{ 1326 template <class _OutputIterator> 1327 _OutputIterator 1328 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const; 1329}; 1330 1331template <> 1332struct __widen_from_utf8<8> 1333{ 1334 template <class _OutputIterator> 1335 _LIBCPP_INLINE_VISIBILITY 1336 _OutputIterator 1337 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const 1338 { 1339 for (; __nb < __ne; ++__nb, ++__s) 1340 *__s = *__nb; 1341 return __s; 1342 } 1343}; 1344 1345template <> 1346struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16> 1347 : public codecvt<char16_t, char, mbstate_t> 1348{ 1349 _LIBCPP_INLINE_VISIBILITY 1350 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {} 1351 1352 _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8(); 1353 1354 template <class _OutputIterator> 1355 _LIBCPP_INLINE_VISIBILITY 1356 _OutputIterator 1357 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const 1358 { 1359 result __r = ok; 1360 mbstate_t __mb; 1361 while (__nb < __ne && __r != error) 1362 { 1363 const int __sz = 32; 1364 char16_t __buf[__sz]; 1365 char16_t* __bn; 1366 const char* __nn = __nb; 1367 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn, 1368 __buf, __buf+__sz, __bn); 1369 if (__r == codecvt_base::error || __nn == __nb) 1370 __throw_runtime_error("locale not supported"); 1371 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s) 1372 *__s = (wchar_t)*__p; 1373 __nb = __nn; 1374 } 1375 return __s; 1376 } 1377}; 1378 1379template <> 1380struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32> 1381 : public codecvt<char32_t, char, mbstate_t> 1382{ 1383 _LIBCPP_INLINE_VISIBILITY 1384 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {} 1385 1386 _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8(); 1387 1388 template <class _OutputIterator> 1389 _LIBCPP_INLINE_VISIBILITY 1390 _OutputIterator 1391 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const 1392 { 1393 result __r = ok; 1394 mbstate_t __mb; 1395 while (__nb < __ne && __r != error) 1396 { 1397 const int __sz = 32; 1398 char32_t __buf[__sz]; 1399 char32_t* __bn; 1400 const char* __nn = __nb; 1401 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn, 1402 __buf, __buf+__sz, __bn); 1403 if (__r == codecvt_base::error || __nn == __nb) 1404 __throw_runtime_error("locale not supported"); 1405 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s) 1406 *__s = (wchar_t)*__p; 1407 __nb = __nn; 1408 } 1409 return __s; 1410 } 1411}; 1412 1413// template <class charT> class numpunct 1414 1415template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct; 1416 1417template <> 1418class _LIBCPP_TYPE_VIS numpunct<char> 1419 : public locale::facet 1420{ 1421public: 1422 typedef char char_type; 1423 typedef basic_string<char_type> string_type; 1424 1425 explicit numpunct(size_t __refs = 0); 1426 1427 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();} 1428 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();} 1429 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();} 1430 _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();} 1431 _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();} 1432 1433 static locale::id id; 1434 1435protected: 1436 ~numpunct(); 1437 virtual char_type do_decimal_point() const; 1438 virtual char_type do_thousands_sep() const; 1439 virtual string do_grouping() const; 1440 virtual string_type do_truename() const; 1441 virtual string_type do_falsename() const; 1442 1443 char_type __decimal_point_; 1444 char_type __thousands_sep_; 1445 string __grouping_; 1446}; 1447 1448template <> 1449class _LIBCPP_TYPE_VIS numpunct<wchar_t> 1450 : public locale::facet 1451{ 1452public: 1453 typedef wchar_t char_type; 1454 typedef basic_string<char_type> string_type; 1455 1456 explicit numpunct(size_t __refs = 0); 1457 1458 _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();} 1459 _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();} 1460 _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();} 1461 _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();} 1462 _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();} 1463 1464 static locale::id id; 1465 1466protected: 1467 ~numpunct(); 1468 virtual char_type do_decimal_point() const; 1469 virtual char_type do_thousands_sep() const; 1470 virtual string do_grouping() const; 1471 virtual string_type do_truename() const; 1472 virtual string_type do_falsename() const; 1473 1474 char_type __decimal_point_; 1475 char_type __thousands_sep_; 1476 string __grouping_; 1477}; 1478 1479// template <class charT> class numpunct_byname 1480 1481template <class _CharT> class _LIBCPP_TEMPLATE_VIS numpunct_byname; 1482 1483template <> 1484class _LIBCPP_TYPE_VIS numpunct_byname<char> 1485: public numpunct<char> 1486{ 1487public: 1488 typedef char char_type; 1489 typedef basic_string<char_type> string_type; 1490 1491 explicit numpunct_byname(const char* __nm, size_t __refs = 0); 1492 explicit numpunct_byname(const string& __nm, size_t __refs = 0); 1493 1494protected: 1495 ~numpunct_byname(); 1496 1497private: 1498 void __init(const char*); 1499}; 1500 1501template <> 1502class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t> 1503: public numpunct<wchar_t> 1504{ 1505public: 1506 typedef wchar_t char_type; 1507 typedef basic_string<char_type> string_type; 1508 1509 explicit numpunct_byname(const char* __nm, size_t __refs = 0); 1510 explicit numpunct_byname(const string& __nm, size_t __refs = 0); 1511 1512protected: 1513 ~numpunct_byname(); 1514 1515private: 1516 void __init(const char*); 1517}; 1518 1519_LIBCPP_END_NAMESPACE_STD 1520 1521#endif // _LIBCPP___LOCALE 1522