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