__locale revision 253159
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#else // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || EMSCRIPTEN || __sun__ 377 typedef unsigned long mask; 378 static const mask space = 1<<0; 379 static const mask print = 1<<1; 380 static const mask cntrl = 1<<2; 381 static const mask upper = 1<<3; 382 static const mask lower = 1<<4; 383 static const mask alpha = 1<<5; 384 static const mask digit = 1<<6; 385 static const mask punct = 1<<7; 386 static const mask xdigit = 1<<8; 387 static const mask blank = 1<<9; 388#endif // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ 389 static const mask alnum = alpha | digit; 390 static const mask graph = alnum | punct; 391 392 _LIBCPP_ALWAYS_INLINE ctype_base() {} 393}; 394 395template <class _CharT> class _LIBCPP_TYPE_VIS ctype; 396 397template <> 398class _LIBCPP_TYPE_VIS ctype<wchar_t> 399 : public locale::facet, 400 public ctype_base 401{ 402public: 403 typedef wchar_t char_type; 404 405 _LIBCPP_ALWAYS_INLINE 406 explicit ctype(size_t __refs = 0) 407 : locale::facet(__refs) {} 408 409 _LIBCPP_ALWAYS_INLINE 410 bool is(mask __m, char_type __c) const 411 { 412 return do_is(__m, __c); 413 } 414 415 _LIBCPP_ALWAYS_INLINE 416 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const 417 { 418 return do_is(__low, __high, __vec); 419 } 420 421 _LIBCPP_ALWAYS_INLINE 422 const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const 423 { 424 return do_scan_is(__m, __low, __high); 425 } 426 427 _LIBCPP_ALWAYS_INLINE 428 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const 429 { 430 return do_scan_not(__m, __low, __high); 431 } 432 433 _LIBCPP_ALWAYS_INLINE 434 char_type toupper(char_type __c) const 435 { 436 return do_toupper(__c); 437 } 438 439 _LIBCPP_ALWAYS_INLINE 440 const char_type* toupper(char_type* __low, const char_type* __high) const 441 { 442 return do_toupper(__low, __high); 443 } 444 445 _LIBCPP_ALWAYS_INLINE 446 char_type tolower(char_type __c) const 447 { 448 return do_tolower(__c); 449 } 450 451 _LIBCPP_ALWAYS_INLINE 452 const char_type* tolower(char_type* __low, const char_type* __high) const 453 { 454 return do_tolower(__low, __high); 455 } 456 457 _LIBCPP_ALWAYS_INLINE 458 char_type widen(char __c) const 459 { 460 return do_widen(__c); 461 } 462 463 _LIBCPP_ALWAYS_INLINE 464 const char* widen(const char* __low, const char* __high, char_type* __to) const 465 { 466 return do_widen(__low, __high, __to); 467 } 468 469 _LIBCPP_ALWAYS_INLINE 470 char narrow(char_type __c, char __dfault) const 471 { 472 return do_narrow(__c, __dfault); 473 } 474 475 _LIBCPP_ALWAYS_INLINE 476 const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const 477 { 478 return do_narrow(__low, __high, __dfault, __to); 479 } 480 481 static locale::id id; 482 483protected: 484 ~ctype(); 485 virtual bool do_is(mask __m, char_type __c) const; 486 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const; 487 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const; 488 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const; 489 virtual char_type do_toupper(char_type) const; 490 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; 491 virtual char_type do_tolower(char_type) const; 492 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; 493 virtual char_type do_widen(char) const; 494 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const; 495 virtual char do_narrow(char_type, char __dfault) const; 496 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const; 497}; 498 499template <> 500class _LIBCPP_TYPE_VIS ctype<char> 501 : public locale::facet, public ctype_base 502{ 503 const mask* __tab_; 504 bool __del_; 505public: 506 typedef char char_type; 507 508 explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0); 509 510 _LIBCPP_ALWAYS_INLINE 511 bool is(mask __m, char_type __c) const 512 { 513 return isascii(__c) ? __tab_[static_cast<int>(__c)] & __m : false; 514 } 515 516 _LIBCPP_ALWAYS_INLINE 517 const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const 518 { 519 for (; __low != __high; ++__low, ++__vec) 520 *__vec = isascii(*__low) ? __tab_[static_cast<int>(*__low)] : 0; 521 return __low; 522 } 523 524 _LIBCPP_ALWAYS_INLINE 525 const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const 526 { 527 for (; __low != __high; ++__low) 528 if (isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m)) 529 break; 530 return __low; 531 } 532 533 _LIBCPP_ALWAYS_INLINE 534 const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const 535 { 536 for (; __low != __high; ++__low) 537 if (!(isascii(*__low) && (__tab_[static_cast<int>(*__low)] & __m))) 538 break; 539 return __low; 540 } 541 542 _LIBCPP_ALWAYS_INLINE 543 char_type toupper(char_type __c) const 544 { 545 return do_toupper(__c); 546 } 547 548 _LIBCPP_ALWAYS_INLINE 549 const char_type* toupper(char_type* __low, const char_type* __high) const 550 { 551 return do_toupper(__low, __high); 552 } 553 554 _LIBCPP_ALWAYS_INLINE 555 char_type tolower(char_type __c) const 556 { 557 return do_tolower(__c); 558 } 559 560 _LIBCPP_ALWAYS_INLINE 561 const char_type* tolower(char_type* __low, const char_type* __high) const 562 { 563 return do_tolower(__low, __high); 564 } 565 566 _LIBCPP_ALWAYS_INLINE 567 char_type widen(char __c) const 568 { 569 return do_widen(__c); 570 } 571 572 _LIBCPP_ALWAYS_INLINE 573 const char* widen(const char* __low, const char* __high, char_type* __to) const 574 { 575 return do_widen(__low, __high, __to); 576 } 577 578 _LIBCPP_ALWAYS_INLINE 579 char narrow(char_type __c, char __dfault) const 580 { 581 return do_narrow(__c, __dfault); 582 } 583 584 _LIBCPP_ALWAYS_INLINE 585 const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const 586 { 587 return do_narrow(__low, __high, __dfault, __to); 588 } 589 590 static locale::id id; 591 592#ifdef _CACHED_RUNES 593 static const size_t table_size = _CACHED_RUNES; 594#else 595 static const size_t table_size = 256; // FIXME: Don't hardcode this. 596#endif 597 _LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;} 598 static const mask* classic_table() _NOEXCEPT; 599#if defined(__GLIBC__) || defined(EMSCRIPTEN) 600 static const int* __classic_upper_table() _NOEXCEPT; 601 static const int* __classic_lower_table() _NOEXCEPT; 602#endif 603#if defined(__NetBSD__) 604 static const short* __classic_upper_table() _NOEXCEPT; 605 static const short* __classic_lower_table() _NOEXCEPT; 606#endif 607 608protected: 609 ~ctype(); 610 virtual char_type do_toupper(char_type __c) const; 611 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; 612 virtual char_type do_tolower(char_type __c) const; 613 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; 614 virtual char_type do_widen(char __c) const; 615 virtual const char* do_widen(const char* __low, const char* __high, char_type* __to) const; 616 virtual char do_narrow(char_type __c, char __dfault) const; 617 virtual const char* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const; 618}; 619 620// template <class CharT> class ctype_byname; 621 622template <class _CharT> class _LIBCPP_TYPE_VIS ctype_byname; 623 624template <> 625class _LIBCPP_TYPE_VIS ctype_byname<char> 626 : public ctype<char> 627{ 628 locale_t __l; 629 630public: 631 explicit ctype_byname(const char*, size_t = 0); 632 explicit ctype_byname(const string&, size_t = 0); 633 634protected: 635 ~ctype_byname(); 636 virtual char_type do_toupper(char_type) const; 637 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; 638 virtual char_type do_tolower(char_type) const; 639 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; 640}; 641 642template <> 643class _LIBCPP_TYPE_VIS ctype_byname<wchar_t> 644 : public ctype<wchar_t> 645{ 646 locale_t __l; 647 648public: 649 explicit ctype_byname(const char*, size_t = 0); 650 explicit ctype_byname(const string&, size_t = 0); 651 652protected: 653 ~ctype_byname(); 654 virtual bool do_is(mask __m, char_type __c) const; 655 virtual const char_type* do_is(const char_type* __low, const char_type* __high, mask* __vec) const; 656 virtual const char_type* do_scan_is(mask __m, const char_type* __low, const char_type* __high) const; 657 virtual const char_type* do_scan_not(mask __m, const char_type* __low, const char_type* __high) const; 658 virtual char_type do_toupper(char_type) const; 659 virtual const char_type* do_toupper(char_type* __low, const char_type* __high) const; 660 virtual char_type do_tolower(char_type) const; 661 virtual const char_type* do_tolower(char_type* __low, const char_type* __high) const; 662 virtual char_type do_widen(char) const; 663 virtual const char* do_widen(const char* __low, const char* __high, char_type* __dest) const; 664 virtual char do_narrow(char_type, char __dfault) const; 665 virtual const char_type* do_narrow(const char_type* __low, const char_type* __high, char __dfault, char* __dest) const; 666}; 667 668template <class _CharT> 669inline _LIBCPP_INLINE_VISIBILITY 670bool 671isspace(_CharT __c, const locale& __loc) 672{ 673 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); 674} 675 676template <class _CharT> 677inline _LIBCPP_INLINE_VISIBILITY 678bool 679isprint(_CharT __c, const locale& __loc) 680{ 681 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); 682} 683 684template <class _CharT> 685inline _LIBCPP_INLINE_VISIBILITY 686bool 687iscntrl(_CharT __c, const locale& __loc) 688{ 689 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); 690} 691 692template <class _CharT> 693inline _LIBCPP_INLINE_VISIBILITY 694bool 695isupper(_CharT __c, const locale& __loc) 696{ 697 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); 698} 699 700template <class _CharT> 701inline _LIBCPP_INLINE_VISIBILITY 702bool 703islower(_CharT __c, const locale& __loc) 704{ 705 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); 706} 707 708template <class _CharT> 709inline _LIBCPP_INLINE_VISIBILITY 710bool 711isalpha(_CharT __c, const locale& __loc) 712{ 713 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); 714} 715 716template <class _CharT> 717inline _LIBCPP_INLINE_VISIBILITY 718bool 719isdigit(_CharT __c, const locale& __loc) 720{ 721 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); 722} 723 724template <class _CharT> 725inline _LIBCPP_INLINE_VISIBILITY 726bool 727ispunct(_CharT __c, const locale& __loc) 728{ 729 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); 730} 731 732template <class _CharT> 733inline _LIBCPP_INLINE_VISIBILITY 734bool 735isxdigit(_CharT __c, const locale& __loc) 736{ 737 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); 738} 739 740template <class _CharT> 741inline _LIBCPP_INLINE_VISIBILITY 742bool 743isalnum(_CharT __c, const locale& __loc) 744{ 745 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); 746} 747 748template <class _CharT> 749inline _LIBCPP_INLINE_VISIBILITY 750bool 751isgraph(_CharT __c, const locale& __loc) 752{ 753 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); 754} 755 756template <class _CharT> 757inline _LIBCPP_INLINE_VISIBILITY 758_CharT 759toupper(_CharT __c, const locale& __loc) 760{ 761 return use_facet<ctype<_CharT> >(__loc).toupper(__c); 762} 763 764template <class _CharT> 765inline _LIBCPP_INLINE_VISIBILITY 766_CharT 767tolower(_CharT __c, const locale& __loc) 768{ 769 return use_facet<ctype<_CharT> >(__loc).tolower(__c); 770} 771 772// codecvt_base 773 774class _LIBCPP_TYPE_VIS codecvt_base 775{ 776public: 777 _LIBCPP_ALWAYS_INLINE codecvt_base() {} 778 enum result {ok, partial, error, noconv}; 779}; 780 781// template <class internT, class externT, class stateT> class codecvt; 782 783template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_TYPE_VIS codecvt; 784 785// template <> class codecvt<char, char, mbstate_t> 786 787template <> 788class _LIBCPP_TYPE_VIS codecvt<char, char, mbstate_t> 789 : public locale::facet, 790 public codecvt_base 791{ 792public: 793 typedef char intern_type; 794 typedef char extern_type; 795 typedef mbstate_t state_type; 796 797 _LIBCPP_ALWAYS_INLINE 798 explicit codecvt(size_t __refs = 0) 799 : locale::facet(__refs) {} 800 801 _LIBCPP_ALWAYS_INLINE 802 result out(state_type& __st, 803 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 804 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 805 { 806 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 807 } 808 809 _LIBCPP_ALWAYS_INLINE 810 result unshift(state_type& __st, 811 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 812 { 813 return do_unshift(__st, __to, __to_end, __to_nxt); 814 } 815 816 _LIBCPP_ALWAYS_INLINE 817 result in(state_type& __st, 818 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 819 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const 820 { 821 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 822 } 823 824 _LIBCPP_ALWAYS_INLINE 825 int encoding() const _NOEXCEPT 826 { 827 return do_encoding(); 828 } 829 830 _LIBCPP_ALWAYS_INLINE 831 bool always_noconv() const _NOEXCEPT 832 { 833 return do_always_noconv(); 834 } 835 836 _LIBCPP_ALWAYS_INLINE 837 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const 838 { 839 return do_length(__st, __frm, __end, __mx); 840 } 841 842 _LIBCPP_ALWAYS_INLINE 843 int max_length() const _NOEXCEPT 844 { 845 return do_max_length(); 846 } 847 848 static locale::id id; 849 850protected: 851 _LIBCPP_ALWAYS_INLINE 852 explicit codecvt(const char*, size_t __refs = 0) 853 : locale::facet(__refs) {} 854 855 ~codecvt(); 856 857 virtual result do_out(state_type& __st, 858 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 859 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 860 virtual result do_in(state_type& __st, 861 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 862 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; 863 virtual result do_unshift(state_type& __st, 864 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 865 virtual int do_encoding() const _NOEXCEPT; 866 virtual bool do_always_noconv() const _NOEXCEPT; 867 virtual int do_length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const; 868 virtual int do_max_length() const _NOEXCEPT; 869}; 870 871// template <> class codecvt<wchar_t, char, mbstate_t> 872 873template <> 874class _LIBCPP_TYPE_VIS codecvt<wchar_t, char, mbstate_t> 875 : public locale::facet, 876 public codecvt_base 877{ 878 locale_t __l; 879public: 880 typedef wchar_t intern_type; 881 typedef char extern_type; 882 typedef mbstate_t state_type; 883 884 explicit codecvt(size_t __refs = 0); 885 886 _LIBCPP_ALWAYS_INLINE 887 result out(state_type& __st, 888 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 889 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 890 { 891 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 892 } 893 894 _LIBCPP_ALWAYS_INLINE 895 result unshift(state_type& __st, 896 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 897 { 898 return do_unshift(__st, __to, __to_end, __to_nxt); 899 } 900 901 _LIBCPP_ALWAYS_INLINE 902 result in(state_type& __st, 903 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 904 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const 905 { 906 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 907 } 908 909 _LIBCPP_ALWAYS_INLINE 910 int encoding() const _NOEXCEPT 911 { 912 return do_encoding(); 913 } 914 915 _LIBCPP_ALWAYS_INLINE 916 bool always_noconv() const _NOEXCEPT 917 { 918 return do_always_noconv(); 919 } 920 921 _LIBCPP_ALWAYS_INLINE 922 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const 923 { 924 return do_length(__st, __frm, __end, __mx); 925 } 926 927 _LIBCPP_ALWAYS_INLINE 928 int max_length() const _NOEXCEPT 929 { 930 return do_max_length(); 931 } 932 933 static locale::id id; 934 935protected: 936 explicit codecvt(const char*, size_t __refs = 0); 937 938 ~codecvt(); 939 940 virtual result do_out(state_type& __st, 941 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 942 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 943 virtual result do_in(state_type& __st, 944 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 945 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; 946 virtual result do_unshift(state_type& __st, 947 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 948 virtual int do_encoding() const _NOEXCEPT; 949 virtual bool do_always_noconv() const _NOEXCEPT; 950 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; 951 virtual int do_max_length() const _NOEXCEPT; 952}; 953 954// template <> class codecvt<char16_t, char, mbstate_t> 955 956template <> 957class _LIBCPP_TYPE_VIS codecvt<char16_t, char, mbstate_t> 958 : public locale::facet, 959 public codecvt_base 960{ 961public: 962 typedef char16_t intern_type; 963 typedef char extern_type; 964 typedef mbstate_t state_type; 965 966 _LIBCPP_ALWAYS_INLINE 967 explicit codecvt(size_t __refs = 0) 968 : locale::facet(__refs) {} 969 970 _LIBCPP_ALWAYS_INLINE 971 result out(state_type& __st, 972 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 973 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 974 { 975 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 976 } 977 978 _LIBCPP_ALWAYS_INLINE 979 result unshift(state_type& __st, 980 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 981 { 982 return do_unshift(__st, __to, __to_end, __to_nxt); 983 } 984 985 _LIBCPP_ALWAYS_INLINE 986 result in(state_type& __st, 987 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 988 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const 989 { 990 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 991 } 992 993 _LIBCPP_ALWAYS_INLINE 994 int encoding() const _NOEXCEPT 995 { 996 return do_encoding(); 997 } 998 999 _LIBCPP_ALWAYS_INLINE 1000 bool always_noconv() const _NOEXCEPT 1001 { 1002 return do_always_noconv(); 1003 } 1004 1005 _LIBCPP_ALWAYS_INLINE 1006 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const 1007 { 1008 return do_length(__st, __frm, __end, __mx); 1009 } 1010 1011 _LIBCPP_ALWAYS_INLINE 1012 int max_length() const _NOEXCEPT 1013 { 1014 return do_max_length(); 1015 } 1016 1017 static locale::id id; 1018 1019protected: 1020 _LIBCPP_ALWAYS_INLINE 1021 explicit codecvt(const char*, size_t __refs = 0) 1022 : locale::facet(__refs) {} 1023 1024 ~codecvt(); 1025 1026 virtual result do_out(state_type& __st, 1027 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1028 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1029 virtual result do_in(state_type& __st, 1030 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1031 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; 1032 virtual result do_unshift(state_type& __st, 1033 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1034 virtual int do_encoding() const _NOEXCEPT; 1035 virtual bool do_always_noconv() const _NOEXCEPT; 1036 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; 1037 virtual int do_max_length() const _NOEXCEPT; 1038}; 1039 1040// template <> class codecvt<char32_t, char, mbstate_t> 1041 1042template <> 1043class _LIBCPP_TYPE_VIS codecvt<char32_t, char, mbstate_t> 1044 : public locale::facet, 1045 public codecvt_base 1046{ 1047public: 1048 typedef char32_t intern_type; 1049 typedef char extern_type; 1050 typedef mbstate_t state_type; 1051 1052 _LIBCPP_ALWAYS_INLINE 1053 explicit codecvt(size_t __refs = 0) 1054 : locale::facet(__refs) {} 1055 1056 _LIBCPP_ALWAYS_INLINE 1057 result out(state_type& __st, 1058 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1059 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1060 { 1061 return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1062 } 1063 1064 _LIBCPP_ALWAYS_INLINE 1065 result unshift(state_type& __st, 1066 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const 1067 { 1068 return do_unshift(__st, __to, __to_end, __to_nxt); 1069 } 1070 1071 _LIBCPP_ALWAYS_INLINE 1072 result in(state_type& __st, 1073 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1074 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const 1075 { 1076 return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); 1077 } 1078 1079 _LIBCPP_ALWAYS_INLINE 1080 int encoding() const _NOEXCEPT 1081 { 1082 return do_encoding(); 1083 } 1084 1085 _LIBCPP_ALWAYS_INLINE 1086 bool always_noconv() const _NOEXCEPT 1087 { 1088 return do_always_noconv(); 1089 } 1090 1091 _LIBCPP_ALWAYS_INLINE 1092 int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const 1093 { 1094 return do_length(__st, __frm, __end, __mx); 1095 } 1096 1097 _LIBCPP_ALWAYS_INLINE 1098 int max_length() const _NOEXCEPT 1099 { 1100 return do_max_length(); 1101 } 1102 1103 static locale::id id; 1104 1105protected: 1106 _LIBCPP_ALWAYS_INLINE 1107 explicit codecvt(const char*, size_t __refs = 0) 1108 : locale::facet(__refs) {} 1109 1110 ~codecvt(); 1111 1112 virtual result do_out(state_type& __st, 1113 const intern_type* __frm, const intern_type* __frm_end, const intern_type*& __frm_nxt, 1114 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1115 virtual result do_in(state_type& __st, 1116 const extern_type* __frm, const extern_type* __frm_end, const extern_type*& __frm_nxt, 1117 intern_type* __to, intern_type* __to_end, intern_type*& __to_nxt) const; 1118 virtual result do_unshift(state_type& __st, 1119 extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const; 1120 virtual int do_encoding() const _NOEXCEPT; 1121 virtual bool do_always_noconv() const _NOEXCEPT; 1122 virtual int do_length(state_type&, const extern_type* __frm, const extern_type* __end, size_t __mx) const; 1123 virtual int do_max_length() const _NOEXCEPT; 1124}; 1125 1126// template <class _InternT, class _ExternT, class _StateT> class codecvt_byname 1127 1128template <class _InternT, class _ExternT, class _StateT> 1129class _LIBCPP_TYPE_VIS codecvt_byname 1130 : public codecvt<_InternT, _ExternT, _StateT> 1131{ 1132public: 1133 _LIBCPP_ALWAYS_INLINE 1134 explicit codecvt_byname(const char* __nm, size_t __refs = 0) 1135 : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {} 1136 _LIBCPP_ALWAYS_INLINE 1137 explicit codecvt_byname(const string& __nm, size_t __refs = 0) 1138 : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {} 1139protected: 1140 ~codecvt_byname(); 1141}; 1142 1143template <class _InternT, class _ExternT, class _StateT> 1144codecvt_byname<_InternT, _ExternT, _StateT>::~codecvt_byname() 1145{ 1146} 1147 1148_LIBCPP_EXTERN_TEMPLATE(class codecvt_byname<char, char, mbstate_t>) 1149_LIBCPP_EXTERN_TEMPLATE(class codecvt_byname<wchar_t, char, mbstate_t>) 1150_LIBCPP_EXTERN_TEMPLATE(class codecvt_byname<char16_t, char, mbstate_t>) 1151_LIBCPP_EXTERN_TEMPLATE(class codecvt_byname<char32_t, char, mbstate_t>) 1152 1153_LIBCPP_FUNC_VIS void __throw_runtime_error(const char*); 1154 1155template <size_t _Np> 1156struct __narrow_to_utf8 1157{ 1158 template <class _OutputIterator, class _CharT> 1159 _OutputIterator 1160 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const; 1161}; 1162 1163template <> 1164struct __narrow_to_utf8<8> 1165{ 1166 template <class _OutputIterator, class _CharT> 1167 _LIBCPP_ALWAYS_INLINE 1168 _OutputIterator 1169 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const 1170 { 1171 for (; __wb < __we; ++__wb, ++__s) 1172 *__s = *__wb; 1173 return __s; 1174 } 1175}; 1176 1177template <> 1178struct __narrow_to_utf8<16> 1179 : public codecvt<char16_t, char, mbstate_t> 1180{ 1181 _LIBCPP_ALWAYS_INLINE 1182 __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {} 1183 1184 ~__narrow_to_utf8(); 1185 1186 template <class _OutputIterator, class _CharT> 1187 _LIBCPP_ALWAYS_INLINE 1188 _OutputIterator 1189 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const 1190 { 1191 result __r = ok; 1192 mbstate_t __mb; 1193 while (__wb < __we && __r != error) 1194 { 1195 const int __sz = 32; 1196 char __buf[__sz]; 1197 char* __bn; 1198 const char16_t* __wn = (const char16_t*)__wb; 1199 __r = do_out(__mb, (const char16_t*)__wb, (const char16_t*)__we, __wn, 1200 __buf, __buf+__sz, __bn); 1201 if (__r == codecvt_base::error || __wn == (const char16_t*)__wb) 1202 __throw_runtime_error("locale not supported"); 1203 for (const char* __p = __buf; __p < __bn; ++__p, ++__s) 1204 *__s = *__p; 1205 __wb = (const _CharT*)__wn; 1206 } 1207 return __s; 1208 } 1209}; 1210 1211template <> 1212struct __narrow_to_utf8<32> 1213 : public codecvt<char32_t, char, mbstate_t> 1214{ 1215 _LIBCPP_ALWAYS_INLINE 1216 __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {} 1217 1218 ~__narrow_to_utf8(); 1219 1220 template <class _OutputIterator, class _CharT> 1221 _LIBCPP_ALWAYS_INLINE 1222 _OutputIterator 1223 operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const 1224 { 1225 result __r = ok; 1226 mbstate_t __mb; 1227 while (__wb < __we && __r != error) 1228 { 1229 const int __sz = 32; 1230 char __buf[__sz]; 1231 char* __bn; 1232 const char32_t* __wn = (const char32_t*)__wb; 1233 __r = do_out(__mb, (const char32_t*)__wb, (const char32_t*)__we, __wn, 1234 __buf, __buf+__sz, __bn); 1235 if (__r == codecvt_base::error || __wn == (const char32_t*)__wb) 1236 __throw_runtime_error("locale not supported"); 1237 for (const char* __p = __buf; __p < __bn; ++__p, ++__s) 1238 *__s = *__p; 1239 __wb = (const _CharT*)__wn; 1240 } 1241 return __s; 1242 } 1243}; 1244 1245template <size_t _Np> 1246struct __widen_from_utf8 1247{ 1248 template <class _OutputIterator> 1249 _OutputIterator 1250 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const; 1251}; 1252 1253template <> 1254struct __widen_from_utf8<8> 1255{ 1256 template <class _OutputIterator> 1257 _LIBCPP_ALWAYS_INLINE 1258 _OutputIterator 1259 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const 1260 { 1261 for (; __nb < __ne; ++__nb, ++__s) 1262 *__s = *__nb; 1263 return __s; 1264 } 1265}; 1266 1267template <> 1268struct __widen_from_utf8<16> 1269 : public codecvt<char16_t, char, mbstate_t> 1270{ 1271 _LIBCPP_ALWAYS_INLINE 1272 __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {} 1273 1274 ~__widen_from_utf8(); 1275 1276 template <class _OutputIterator> 1277 _LIBCPP_ALWAYS_INLINE 1278 _OutputIterator 1279 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const 1280 { 1281 result __r = ok; 1282 mbstate_t __mb; 1283 while (__nb < __ne && __r != error) 1284 { 1285 const int __sz = 32; 1286 char16_t __buf[__sz]; 1287 char16_t* __bn; 1288 const char* __nn = __nb; 1289 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn, 1290 __buf, __buf+__sz, __bn); 1291 if (__r == codecvt_base::error || __nn == __nb) 1292 __throw_runtime_error("locale not supported"); 1293 for (const char16_t* __p = __buf; __p < __bn; ++__p, ++__s) 1294 *__s = (wchar_t)*__p; 1295 __nb = __nn; 1296 } 1297 return __s; 1298 } 1299}; 1300 1301template <> 1302struct __widen_from_utf8<32> 1303 : public codecvt<char32_t, char, mbstate_t> 1304{ 1305 _LIBCPP_ALWAYS_INLINE 1306 __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {} 1307 1308 ~__widen_from_utf8(); 1309 1310 template <class _OutputIterator> 1311 _LIBCPP_ALWAYS_INLINE 1312 _OutputIterator 1313 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const 1314 { 1315 result __r = ok; 1316 mbstate_t __mb; 1317 while (__nb < __ne && __r != error) 1318 { 1319 const int __sz = 32; 1320 char32_t __buf[__sz]; 1321 char32_t* __bn; 1322 const char* __nn = __nb; 1323 __r = do_in(__mb, __nb, __ne - __nb > __sz ? __nb+__sz : __ne, __nn, 1324 __buf, __buf+__sz, __bn); 1325 if (__r == codecvt_base::error || __nn == __nb) 1326 __throw_runtime_error("locale not supported"); 1327 for (const char32_t* __p = __buf; __p < __bn; ++__p, ++__s) 1328 *__s = (wchar_t)*__p; 1329 __nb = __nn; 1330 } 1331 return __s; 1332 } 1333}; 1334 1335// template <class charT> class numpunct 1336 1337template <class _CharT> class _LIBCPP_TYPE_VIS numpunct; 1338 1339template <> 1340class _LIBCPP_TYPE_VIS numpunct<char> 1341 : public locale::facet 1342{ 1343public: 1344 typedef char char_type; 1345 typedef basic_string<char_type> string_type; 1346 1347 explicit numpunct(size_t __refs = 0); 1348 1349 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();} 1350 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();} 1351 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();} 1352 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();} 1353 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();} 1354 1355 static locale::id id; 1356 1357protected: 1358 ~numpunct(); 1359 virtual char_type do_decimal_point() const; 1360 virtual char_type do_thousands_sep() const; 1361 virtual string do_grouping() const; 1362 virtual string_type do_truename() const; 1363 virtual string_type do_falsename() const; 1364 1365 char_type __decimal_point_; 1366 char_type __thousands_sep_; 1367 string __grouping_; 1368}; 1369 1370template <> 1371class _LIBCPP_TYPE_VIS numpunct<wchar_t> 1372 : public locale::facet 1373{ 1374public: 1375 typedef wchar_t char_type; 1376 typedef basic_string<char_type> string_type; 1377 1378 explicit numpunct(size_t __refs = 0); 1379 1380 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();} 1381 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();} 1382 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();} 1383 _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();} 1384 _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();} 1385 1386 static locale::id id; 1387 1388protected: 1389 ~numpunct(); 1390 virtual char_type do_decimal_point() const; 1391 virtual char_type do_thousands_sep() const; 1392 virtual string do_grouping() const; 1393 virtual string_type do_truename() const; 1394 virtual string_type do_falsename() const; 1395 1396 char_type __decimal_point_; 1397 char_type __thousands_sep_; 1398 string __grouping_; 1399}; 1400 1401// template <class charT> class numpunct_byname 1402 1403template <class charT> class _LIBCPP_TYPE_VIS numpunct_byname; 1404 1405template <> 1406class _LIBCPP_TYPE_VIS numpunct_byname<char> 1407: public numpunct<char> 1408{ 1409public: 1410 typedef char char_type; 1411 typedef basic_string<char_type> string_type; 1412 1413 explicit numpunct_byname(const char* __nm, size_t __refs = 0); 1414 explicit numpunct_byname(const string& __nm, size_t __refs = 0); 1415 1416protected: 1417 ~numpunct_byname(); 1418 1419private: 1420 void __init(const char*); 1421}; 1422 1423template <> 1424class _LIBCPP_TYPE_VIS numpunct_byname<wchar_t> 1425: public numpunct<wchar_t> 1426{ 1427public: 1428 typedef wchar_t char_type; 1429 typedef basic_string<char_type> string_type; 1430 1431 explicit numpunct_byname(const char* __nm, size_t __refs = 0); 1432 explicit numpunct_byname(const string& __nm, size_t __refs = 0); 1433 1434protected: 1435 ~numpunct_byname(); 1436 1437private: 1438 void __init(const char*); 1439}; 1440 1441_LIBCPP_END_NAMESPACE_STD 1442 1443#endif // _LIBCPP___LOCALE 1444