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