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 34 class _LIBCPP_VISIBLE locale; 35 36 template <class _Facet> 37 _LIBCPP_INLINE_VISIBILITY 38 bool 39 has_facet(const locale&) _NOEXCEPT; 40 41 template <class _Facet> 42 _LIBCPP_INLINE_VISIBILITY 43 const _Facet& 44 use_facet(const locale&); 45 46 class _LIBCPP_VISIBLE locale 47 { 48 public: 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 93 private: 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 106 class _LIBCPP_VISIBLE locale::facet 107 : public __shared_count 108 { 109 protected: 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; 118 private: 119 virtual void __on_zero_shared() _NOEXCEPT; 120 }; 121 122 class _LIBCPP_VISIBLE locale::id 123 { 124 once_flag __flag_; 125 int32_t __id_; 126 127 static int32_t __next_id; 128 public: 129 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR id() :__id_(0) {} 130 private: 131 void __init(); 132 void operator=(const id&); // = delete; 133 id(const id&); // = delete; 134 public: // only needed for tests 135 long __get(); 136 137 friend class locale; 138 friend class locale::__imp; 139 }; 140 141 template <class _Facet> 142 inline _LIBCPP_INLINE_VISIBILITY 143 locale::locale(const locale& __other, _Facet* __f) 144 { 145 __install_ctor(__other, __f, __f ? __f->id.__get() : 0); 146 } 147 148 template <class _Facet> 149 locale 150 locale::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 159 template <class _Facet> 160 inline _LIBCPP_INLINE_VISIBILITY 161 bool 162 has_facet(const locale& __l) _NOEXCEPT 163 { 164 return __l.has_facet(_Facet::id); 165 } 166 167 template <class _Facet> 168 inline _LIBCPP_INLINE_VISIBILITY 169 const _Facet& 170 use_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 177 template <class _CharT> 178 class _LIBCPP_VISIBLE collate 179 : public locale::facet 180 { 181 public: 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 210 protected: 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 219 template <class _CharT> locale::id collate<_CharT>::id; 220 221 template <class _CharT> 222 collate<_CharT>::~collate() 223 { 224 } 225 226 template <class _CharT> 227 int 228 collate<_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 241 template <class _CharT> 242 long 243 collate<_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 262 template <class _CharT> class _LIBCPP_VISIBLE collate_byname; 263 264 template <> 265 class _LIBCPP_VISIBLE collate_byname<char> 266 : public collate<char> 267 { 268 locale_t __l; 269 public: 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 276 protected: 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 283 template <> 284 class _LIBCPP_VISIBLE collate_byname<wchar_t> 285 : public collate<wchar_t> 286 { 287 locale_t __l; 288 public: 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 295 protected: 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 303 template <class _CharT, class _Traits, class _Allocator> 304 bool 305 locale::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 315 class _LIBCPP_VISIBLE ctype_base 316 { 317 public: 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 403 template <class _CharT> class _LIBCPP_VISIBLE ctype; 404 405 template <> 406 class _LIBCPP_VISIBLE ctype<wchar_t> 407 : public locale::facet, 408 public ctype_base 409 { 410 public: 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 491 protected: 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 507 template <> 508 class _LIBCPP_VISIBLE ctype<char> 509 : public locale::facet, public ctype_base 510 { 511 const mask* __tab_; 512 bool __del_; 513 public: 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 614 protected: 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 628 template <class _CharT> class _LIBCPP_VISIBLE ctype_byname; 629 630 template <> 631 class _LIBCPP_VISIBLE ctype_byname<char> 632 : public ctype<char> 633 { 634 locale_t __l; 635 636 public: 637 explicit ctype_byname(const char*, size_t = 0); 638 explicit ctype_byname(const string&, size_t = 0); 639 640 protected: 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 648 template <> 649 class _LIBCPP_VISIBLE ctype_byname<wchar_t> 650 : public ctype<wchar_t> 651 { 652 locale_t __l; 653 654 public: 655 explicit ctype_byname(const char*, size_t = 0); 656 explicit ctype_byname(const string&, size_t = 0); 657 658 protected: 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 674 template <class _CharT> 675 inline _LIBCPP_INLINE_VISIBILITY 676 bool 677 isspace(_CharT __c, const locale& __loc) 678 { 679 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); 680 } 681 682 template <class _CharT> 683 inline _LIBCPP_INLINE_VISIBILITY 684 bool 685 isprint(_CharT __c, const locale& __loc) 686 { 687 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); 688 } 689 690 template <class _CharT> 691 inline _LIBCPP_INLINE_VISIBILITY 692 bool 693 iscntrl(_CharT __c, const locale& __loc) 694 { 695 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); 696 } 697 698 template <class _CharT> 699 inline _LIBCPP_INLINE_VISIBILITY 700 bool 701 isupper(_CharT __c, const locale& __loc) 702 { 703 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); 704 } 705 706 template <class _CharT> 707 inline _LIBCPP_INLINE_VISIBILITY 708 bool 709 islower(_CharT __c, const locale& __loc) 710 { 711 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); 712 } 713 714 template <class _CharT> 715 inline _LIBCPP_INLINE_VISIBILITY 716 bool 717 isalpha(_CharT __c, const locale& __loc) 718 { 719 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); 720 } 721 722 template <class _CharT> 723 inline _LIBCPP_INLINE_VISIBILITY 724 bool 725 isdigit(_CharT __c, const locale& __loc) 726 { 727 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); 728 } 729 730 template <class _CharT> 731 inline _LIBCPP_INLINE_VISIBILITY 732 bool 733 ispunct(_CharT __c, const locale& __loc) 734 { 735 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); 736 } 737 738 template <class _CharT> 739 inline _LIBCPP_INLINE_VISIBILITY 740 bool 741 isxdigit(_CharT __c, const locale& __loc) 742 { 743 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); 744 } 745 746 template <class _CharT> 747 inline _LIBCPP_INLINE_VISIBILITY 748 bool 749 isalnum(_CharT __c, const locale& __loc) 750 { 751 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); 752 } 753 754 template <class _CharT> 755 inline _LIBCPP_INLINE_VISIBILITY 756 bool 757 isgraph(_CharT __c, const locale& __loc) 758 { 759 return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); 760 } 761 762 template <class _CharT> 763 inline _LIBCPP_INLINE_VISIBILITY 764 _CharT 765 toupper(_CharT __c, const locale& __loc) 766 { 767 return use_facet<ctype<_CharT> >(__loc).toupper(__c); 768 } 769 770 template <class _CharT> 771 inline _LIBCPP_INLINE_VISIBILITY 772 _CharT 773 tolower(_CharT __c, const locale& __loc) 774 { 775 return use_facet<ctype<_CharT> >(__loc).tolower(__c); 776 } 777 778 // codecvt_base 779 780 class _LIBCPP_VISIBLE codecvt_base 781 { 782 public: 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 789 template <class _InternT, class _ExternT, class _StateT> class _LIBCPP_VISIBLE codecvt; 790 791 // template <> class codecvt<char, char, mbstate_t> 792 793 template <> 794 class _LIBCPP_VISIBLE codecvt<char, char, mbstate_t> 795 : public locale::facet, 796 public codecvt_base 797 { 798 public: 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 856 protected: 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 879 template <> 880 class _LIBCPP_VISIBLE codecvt<wchar_t, char, mbstate_t> 881 : public locale::facet, 882 public codecvt_base 883 { 884 locale_t __l; 885 public: 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 941 protected: 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 962 template <> 963 class _LIBCPP_VISIBLE codecvt<char16_t, char, mbstate_t> 964 : public locale::facet, 965 public codecvt_base 966 { 967 public: 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 1025 protected: 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 1048 template <> 1049 class _LIBCPP_VISIBLE codecvt<char32_t, char, mbstate_t> 1050 : public locale::facet, 1051 public codecvt_base 1052 { 1053 public: 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 1111 protected: 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 1134 template <class _InternT, class _ExternT, class _StateT> 1135 class _LIBCPP_VISIBLE codecvt_byname 1136 : public codecvt<_InternT, _ExternT, _StateT> 1137 { 1138 public: 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) {} 1145 protected: 1146 ~codecvt_byname(); 1147 }; 1148 1149 template <class _InternT, class _ExternT, class _StateT> 1150 codecvt_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 1161 template <size_t _Np> 1162 struct __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 1169 template <> 1170 struct __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 1183 template <> 1184 struct __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 1217 template <> 1218 struct __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 1251 template <size_t _Np> 1252 struct __widen_from_utf8 1253 { 1254 template <class _OutputIterator> 1255 _OutputIterator 1256 operator()(_OutputIterator __s, const char* __nb, const char* __ne) const; 1257 }; 1258 1259 template <> 1260 struct __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 1273 template <> 1274 struct __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 1307 template <> 1308 struct __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 1343 template <class _CharT> class _LIBCPP_VISIBLE numpunct; 1344 1345 template <> 1346 class _LIBCPP_VISIBLE numpunct<char> 1347 : public locale::facet 1348 { 1349 public: 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 1363 protected: 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 1376 template <> 1377 class _LIBCPP_VISIBLE numpunct<wchar_t> 1378 : public locale::facet 1379 { 1380 public: 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 1394 protected: 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 1409 template <class charT> class _LIBCPP_VISIBLE numpunct_byname; 1410 1411 template <> 1412 class _LIBCPP_VISIBLE numpunct_byname<char> 1413 : public numpunct<char> 1414 { 1415 public: 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 1422 protected: 1423 ~numpunct_byname(); 1424 1425 private: 1426 void __init(const char*); 1427 }; 1428 1429 template <> 1430 class _LIBCPP_VISIBLE numpunct_byname<wchar_t> 1431 : public numpunct<wchar_t> 1432 { 1433 public: 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 1440 protected: 1441 ~numpunct_byname(); 1442 1443 private: 1444 void __init(const char*); 1445 }; 1446 1447 _LIBCPP_END_NAMESPACE_STD 1448 1449 #endif // _LIBCPP___LOCALE 1450