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