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