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