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