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