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