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