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