locale revision 232950
1// -*- C++ -*- 2//===-------------------------- locale ------------------------------------===// 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/* 15 locale synopsis 16 17namespace std 18{ 19 20class locale 21{ 22public: 23 // types: 24 class facet; 25 class id; 26 27 typedef int category; 28 static const category // values assigned here are for exposition only 29 none = 0x000, 30 collate = 0x010, 31 ctype = 0x020, 32 monetary = 0x040, 33 numeric = 0x080, 34 time = 0x100, 35 messages = 0x200, 36 all = collate | ctype | monetary | numeric | time | messages; 37 38 // construct/copy/destroy: 39 locale() noexcept; 40 locale(const locale& other) noexcept; 41 explicit locale(const char* std_name); 42 explicit locale(const string& std_name); 43 locale(const locale& other, const char* std_name, category); 44 locale(const locale& other, const string& std_name, category); 45 template <class Facet> locale(const locale& other, Facet* f); 46 locale(const locale& other, const locale& one, category); 47 48 ~locale(); // not virtual 49 50 const locale& operator=(const locale& other) noexcept; 51 52 template <class Facet> locale combine(const locale& other) const; 53 54 // locale operations: 55 basic_string<char> name() const; 56 bool operator==(const locale& other) const; 57 bool operator!=(const locale& other) const; 58 template <class charT, class Traits, class Allocator> 59 bool operator()(const basic_string<charT,Traits,Allocator>& s1, 60 const basic_string<charT,Traits,Allocator>& s2) const; 61 62 // global locale objects: 63 static locale global(const locale&); 64 static const locale& classic(); 65}; 66 67template <class Facet> const Facet& use_facet(const locale&); 68template <class Facet> bool has_facet(const locale&) noexcept; 69 70// 22.3.3, convenience interfaces: 71template <class charT> bool isspace (charT c, const locale& loc); 72template <class charT> bool isprint (charT c, const locale& loc); 73template <class charT> bool iscntrl (charT c, const locale& loc); 74template <class charT> bool isupper (charT c, const locale& loc); 75template <class charT> bool islower (charT c, const locale& loc); 76template <class charT> bool isalpha (charT c, const locale& loc); 77template <class charT> bool isdigit (charT c, const locale& loc); 78template <class charT> bool ispunct (charT c, const locale& loc); 79template <class charT> bool isxdigit(charT c, const locale& loc); 80template <class charT> bool isalnum (charT c, const locale& loc); 81template <class charT> bool isgraph (charT c, const locale& loc); 82template <class charT> charT toupper(charT c, const locale& loc); 83template <class charT> charT tolower(charT c, const locale& loc); 84 85template<class Codecvt, class Elem = wchar_t, 86 class Wide_alloc = allocator<Elem>, 87 class Byte_alloc = allocator<char>> 88class wstring_convert 89{ 90public: 91 typedef basic_string<char, char_traits<char>, Byte_alloc> byte_string; 92 typedef basic_string<Elem, char_traits<Elem>, Wide_alloc> wide_string; 93 typedef typename Codecvt::state_type state_type; 94 typedef typename wide_string::traits_type::int_type int_type; 95 96 wstring_convert(Codecvt* pcvt = new Codecvt); 97 wstring_convert(Codecvt* pcvt, state_type state); 98 wstring_convert(const byte_string& byte_err, 99 const wide_string& wide_err = wide_string()); 100 ~wstring_convert(); 101 102 wide_string from_bytes(char byte); 103 wide_string from_bytes(const char* ptr); 104 wide_string from_bytes(const byte_string& str); 105 wide_string from_bytes(const char* first, const char* last); 106 107 byte_string to_bytes(Elem wchar); 108 byte_string to_bytes(const Elem* wptr); 109 byte_string to_bytes(const wide_string& wstr); 110 byte_string to_bytes(const Elem* first, const Elem* last); 111 112 size_t converted() const; 113 state_type state() const; 114}; 115 116template <class Codecvt, class Elem = wchar_t, class Tr = char_traits<Elem>> 117class wbuffer_convert 118 : public basic_streambuf<Elem, Tr> 119{ 120public: 121 typedef typename Tr::state_type state_type; 122 123 wbuffer_convert(streambuf* bytebuf = 0, Codecvt* pcvt = new Codecvt, 124 state_type state = state_type()); 125 126 streambuf* rdbuf() const; 127 streambuf* rdbuf(streambuf* bytebuf); 128 129 state_type state() const; 130}; 131 132// 22.4.1 and 22.4.1.3, ctype: 133class ctype_base; 134template <class charT> class ctype; 135template <> class ctype<char>; // specialization 136template <class charT> class ctype_byname; 137template <> class ctype_byname<char>; // specialization 138 139class codecvt_base; 140template <class internT, class externT, class stateT> class codecvt; 141template <class internT, class externT, class stateT> class codecvt_byname; 142 143// 22.4.2 and 22.4.3, numeric: 144template <class charT, class InputIterator> class num_get; 145template <class charT, class OutputIterator> class num_put; 146template <class charT> class numpunct; 147template <class charT> class numpunct_byname; 148 149// 22.4.4, col lation: 150template <class charT> class collate; 151template <class charT> class collate_byname; 152 153// 22.4.5, date and time: 154class time_base; 155template <class charT, class InputIterator> class time_get; 156template <class charT, class InputIterator> class time_get_byname; 157template <class charT, class OutputIterator> class time_put; 158template <class charT, class OutputIterator> class time_put_byname; 159 160// 22.4.6, money: 161class money_base; 162template <class charT, class InputIterator> class money_get; 163template <class charT, class OutputIterator> class money_put; 164template <class charT, bool Intl> class moneypunct; 165template <class charT, bool Intl> class moneypunct_byname; 166 167// 22.4.7, message retrieval: 168class messages_base; 169template <class charT> class messages; 170template <class charT> class messages_byname; 171 172} // std 173 174*/ 175 176#include <__config> 177#include <__locale> 178#include <algorithm> 179#include <memory> 180#include <ios> 181#include <streambuf> 182#include <iterator> 183#include <limits> 184#if !__APPLE__ 185#include <cstdarg> 186#endif 187#include <cstdlib> 188#include <ctime> 189#if _WIN32 190#include <support/win32/locale_win32.h> 191#else // _WIN32 192#include <nl_types.h> 193#endif // !_WIN32 194 195#include <__undef_min_max> 196 197#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 198#pragma GCC system_header 199#endif 200 201_LIBCPP_BEGIN_NAMESPACE_STD 202 203#if __APPLE__ || __FreeBSD__ 204# define _LIBCPP_GET_C_LOCALE 0 205#else 206# define _LIBCPP_GET_C_LOCALE __cloc() 207 // Get the C locale object 208 locale_t __cloc(); 209#define __cloc_defined 210#endif 211 212typedef _VSTD::remove_pointer<locale_t>::type __locale_struct; 213typedef _VSTD::unique_ptr<__locale_struct, decltype(&freelocale)> __locale_unique_ptr; 214#ifndef _LIBCPP_LOCALE__L_EXTENSIONS 215typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii; 216#endif 217 218// OSX has nice foo_l() functions that let you turn off use of the global 219// locale. Linux, not so much. The following functions avoid the locale when 220// that's possible and otherwise do the wrong thing. FIXME. 221#ifdef __linux__ 222 223#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 224decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>())) 225inline _LIBCPP_INLINE_VISIBILITY 226__mb_cur_max_l(locale_t __l) 227{ 228 return MB_CUR_MAX_L(__l); 229} 230#else // _LIBCPP_LOCALE__L_EXTENSIONS 231_LIBCPP_ALWAYS_INLINE inline 232decltype(MB_CUR_MAX) __mb_cur_max_l(locale_t __l) 233{ 234 __locale_raii __current(uselocale(__l), uselocale); 235 return MB_CUR_MAX; 236} 237#endif // _LIBCPP_LOCALE__L_EXTENSIONS 238 239_LIBCPP_ALWAYS_INLINE inline 240wint_t __btowc_l(int __c, locale_t __l) 241{ 242#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 243 return btowc_l(__c, __l); 244#else 245 __locale_raii __current(uselocale(__l), uselocale); 246 return btowc(__c); 247#endif 248} 249 250_LIBCPP_ALWAYS_INLINE inline 251int __wctob_l(wint_t __c, locale_t __l) 252{ 253#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 254 return wctob_l(__c, __l); 255#else 256 __locale_raii __current(uselocale(__l), uselocale); 257 return wctob(__c); 258#endif 259} 260 261_LIBCPP_ALWAYS_INLINE inline 262size_t __wcsnrtombs_l(char *__dest, const wchar_t **__src, size_t __nwc, 263 size_t __len, mbstate_t *__ps, locale_t __l) 264{ 265#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 266 return wcsnrtombs_l(__dest, __src, __nwc, __len, __ps, __l); 267#else 268 __locale_raii __current(uselocale(__l), uselocale); 269 return wcsnrtombs(__dest, __src, __nwc, __len, __ps); 270#endif 271} 272 273_LIBCPP_ALWAYS_INLINE inline 274size_t __wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l) 275{ 276#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 277 return wcrtomb_l(__s, __wc, __ps, __l); 278#else 279 __locale_raii __current(uselocale(__l), uselocale); 280 return wcrtomb(__s, __wc, __ps); 281#endif 282} 283 284_LIBCPP_ALWAYS_INLINE inline 285size_t __mbsnrtowcs_l(wchar_t * __dest, const char **__src, size_t __nms, 286 size_t __len, mbstate_t *__ps, locale_t __l) 287{ 288#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 289 return mbsnrtowcs_l(__dest, __src, __nms, __len, __ps, __l); 290#else 291 __locale_raii __current(uselocale(__l), uselocale); 292 return mbsnrtowcs(__dest, __src, __nms, __len, __ps); 293#endif 294} 295 296_LIBCPP_ALWAYS_INLINE inline 297size_t __mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n, 298 mbstate_t *__ps, locale_t __l) 299{ 300#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 301 return mbrtowc_l(__pwc, __s, __n, __ps, __l); 302#else 303 __locale_raii __current(uselocale(__l), uselocale); 304 return mbrtowc(__pwc, __s, __n, __ps); 305#endif 306} 307 308_LIBCPP_ALWAYS_INLINE inline 309int __mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l) 310{ 311#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 312 return mbtowc_l(__pwc, __pmb, __max, __l); 313#else 314 __locale_raii __current(uselocale(__l), uselocale); 315 return mbtowc(__pwc, __pmb, __max); 316#endif 317} 318 319_LIBCPP_ALWAYS_INLINE inline 320size_t __mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) 321{ 322#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 323 return mbrlen_l(__s, __n, __ps, __l); 324#else 325 __locale_raii __current(uselocale(__l), uselocale); 326 return mbrlen(__s, __n, __ps); 327#endif 328} 329 330_LIBCPP_ALWAYS_INLINE inline 331lconv *__localeconv_l(locale_t __l) 332{ 333#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 334 return localeconv_l(__l); 335#else 336 __locale_raii __current(uselocale(__l), uselocale); 337 return localeconv(); 338#endif 339} 340 341_LIBCPP_ALWAYS_INLINE inline 342size_t __mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len, 343 mbstate_t *__ps, locale_t __l) 344{ 345#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 346 return mbsrtowcs_l(__dest, __src, __len, __ps, __l); 347#else 348 __locale_raii __current(uselocale(__l), uselocale); 349 return mbsrtowcs(__dest, __src, __len, __ps); 350#endif 351} 352 353_LIBCPP_ALWAYS_INLINE inline 354int __sprintf_l(char *__s, locale_t __l, const char *__format, ...) { 355 va_list __va; 356 va_start(__va, __format); 357#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 358 int __res = vsprintf_l(__s, __l, __format, __va); 359#else 360 __locale_raii __current(uselocale(__l), uselocale); 361 int __res = vsprintf(__s, __format, __va); 362#endif 363 va_end(__va); 364 return __res; 365} 366 367_LIBCPP_ALWAYS_INLINE inline 368int __snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...) { 369 va_list __va; 370 va_start(__va, __format); 371#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 372 int __res = vsnprintf_l(__s, __n, __l, __format, __va); 373#else 374 __locale_raii __current(uselocale(__l), uselocale); 375 int __res = vsnprintf(__s, __n, __format, __va); 376#endif 377 va_end(__va); 378 return __res; 379} 380 381_LIBCPP_ALWAYS_INLINE inline 382int __asprintf_l(char **__s, locale_t __l, const char *__format, ...) { 383 va_list __va; 384 va_start(__va, __format); 385#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 386 int __res = vasprintf_l(__s, __l, __format, __va); 387#else 388 __locale_raii __current(uselocale(__l), uselocale); 389 int __res = vasprintf(__s, __format, __va); 390#endif 391 va_end(__va); 392 return __res; 393} 394 395_LIBCPP_ALWAYS_INLINE inline 396int __sscanf_l(const char *__s, locale_t __l, const char *__format, ...) { 397 va_list __va; 398 va_start(__va, __format); 399#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 400 int __res = vsscanf_l(__s, __l, __format, __va); 401#else 402 __locale_raii __current(uselocale(__l), uselocale); 403 int __res = vsscanf(__s, __format, __va); 404#endif 405 va_end(__va); 406 return __res; 407} 408 409#endif // __linux__ 410 411// __scan_keyword 412// Scans [__b, __e) until a match is found in the basic_strings range 413// [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke). 414// __b will be incremented (visibly), consuming CharT until a match is found 415// or proved to not exist. A keyword may be "", in which will match anything. 416// If one keyword is a prefix of another, and the next CharT in the input 417// might match another keyword, the algorithm will attempt to find the longest 418// matching keyword. If the longer matching keyword ends up not matching, then 419// no keyword match is found. If no keyword match is found, __ke is returned 420// and failbit is set in __err. 421// Else an iterator pointing to the matching keyword is found. If more than 422// one keyword matches, an iterator to the first matching keyword is returned. 423// If on exit __b == __e, eofbit is set in __err. If __case_senstive is false, 424// __ct is used to force to lower case before comparing characters. 425// Examples: 426// Keywords: "a", "abb" 427// If the input is "a", the first keyword matches and eofbit is set. 428// If the input is "abc", no match is found and "ab" are consumed. 429template <class _InputIterator, class _ForwardIterator, class _Ctype> 430_LIBCPP_HIDDEN 431_ForwardIterator 432__scan_keyword(_InputIterator& __b, _InputIterator __e, 433 _ForwardIterator __kb, _ForwardIterator __ke, 434 const _Ctype& __ct, ios_base::iostate& __err, 435 bool __case_sensitive = true) 436{ 437 typedef typename iterator_traits<_InputIterator>::value_type _CharT; 438 size_t __nkw = static_cast<size_t>(_VSTD::distance(__kb, __ke)); 439 const unsigned char __doesnt_match = '\0'; 440 const unsigned char __might_match = '\1'; 441 const unsigned char __does_match = '\2'; 442 unsigned char __statbuf[100]; 443 unsigned char* __status = __statbuf; 444 unique_ptr<unsigned char, void(*)(void*)> __stat_hold(0, free); 445 if (__nkw > sizeof(__statbuf)) 446 { 447 __status = (unsigned char*)malloc(__nkw); 448 if (__status == 0) 449 __throw_bad_alloc(); 450 __stat_hold.reset(__status); 451 } 452 size_t __n_might_match = __nkw; // At this point, any keyword might match 453 size_t __n_does_match = 0; // but none of them definitely do 454 // Initialize all statuses to __might_match, except for "" keywords are __does_match 455 unsigned char* __st = __status; 456 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st) 457 { 458 if (!__ky->empty()) 459 *__st = __might_match; 460 else 461 { 462 *__st = __does_match; 463 --__n_might_match; 464 ++__n_does_match; 465 } 466 } 467 // While there might be a match, test keywords against the next CharT 468 for (size_t __indx = 0; __b != __e && __n_might_match > 0; ++__indx) 469 { 470 // Peek at the next CharT but don't consume it 471 _CharT __c = *__b; 472 if (!__case_sensitive) 473 __c = __ct.toupper(__c); 474 bool __consume = false; 475 // For each keyword which might match, see if the __indx character is __c 476 // If a match if found, consume __c 477 // If a match is found, and that is the last character in the keyword, 478 // then that keyword matches. 479 // If the keyword doesn't match this character, then change the keyword 480 // to doesn't match 481 __st = __status; 482 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st) 483 { 484 if (*__st == __might_match) 485 { 486 _CharT __kc = (*__ky)[__indx]; 487 if (!__case_sensitive) 488 __kc = __ct.toupper(__kc); 489 if (__c == __kc) 490 { 491 __consume = true; 492 if (__ky->size() == __indx+1) 493 { 494 *__st = __does_match; 495 --__n_might_match; 496 ++__n_does_match; 497 } 498 } 499 else 500 { 501 *__st = __doesnt_match; 502 --__n_might_match; 503 } 504 } 505 } 506 // consume if we matched a character 507 if (__consume) 508 { 509 ++__b; 510 // If we consumed a character and there might be a matched keyword that 511 // was marked matched on a previous iteration, then such keywords 512 // which are now marked as not matching. 513 if (__n_might_match + __n_does_match > 1) 514 { 515 __st = __status; 516 for (_ForwardIterator __ky = __kb; __ky != __ke; ++__ky, ++__st) 517 { 518 if (*__st == __does_match && __ky->size() != __indx+1) 519 { 520 *__st = __doesnt_match; 521 --__n_does_match; 522 } 523 } 524 } 525 } 526 } 527 // We've exited the loop because we hit eof and/or we have no more "might matches". 528 if (__b == __e) 529 __err |= ios_base::eofbit; 530 // Return the first matching result 531 for (__st = __status; __kb != __ke; ++__kb, ++__st) 532 if (*__st == __does_match) 533 break; 534 if (__kb == __ke) 535 __err |= ios_base::failbit; 536 return __kb; 537} 538 539struct __num_get_base 540{ 541 static const int __num_get_buf_sz = 40; 542 543 static int __get_base(ios_base&); 544 static const char __src[33]; 545}; 546 547void __check_grouping(const string& __grouping, unsigned* __g, unsigned* __g_end, 548 ios_base::iostate& __err); 549 550template <class _CharT> 551struct __num_get 552 : protected __num_get_base 553{ 554 static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep); 555 static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, 556 _CharT& __thousands_sep); 557 static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, 558 unsigned& __dc, _CharT __thousands_sep, const string& __grouping, 559 unsigned* __g, unsigned*& __g_end, _CharT* __atoms); 560 static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, 561 char* __a, char*& __a_end, 562 _CharT __decimal_point, _CharT __thousands_sep, 563 const string& __grouping, unsigned* __g, 564 unsigned*& __g_end, unsigned& __dc, _CharT* __atoms); 565}; 566 567template <class _CharT> 568string 569__num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep) 570{ 571 locale __loc = __iob.getloc(); 572 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 26, __atoms); 573 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 574 __thousands_sep = __np.thousands_sep(); 575 return __np.grouping(); 576} 577 578template <class _CharT> 579string 580__num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, 581 _CharT& __thousands_sep) 582{ 583 locale __loc = __iob.getloc(); 584 use_facet<ctype<_CharT> >(__loc).widen(__src, __src + 32, __atoms); 585 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 586 __decimal_point = __np.decimal_point(); 587 __thousands_sep = __np.thousands_sep(); 588 return __np.grouping(); 589} 590 591template <class _CharT> 592int 593__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, 594 unsigned& __dc, _CharT __thousands_sep, const string& __grouping, 595 unsigned* __g, unsigned*& __g_end, _CharT* __atoms) 596{ 597 if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) 598 { 599 *__a_end++ = __ct == __atoms[24] ? '+' : '-'; 600 __dc = 0; 601 return 0; 602 } 603 if (__grouping.size() != 0 && __ct == __thousands_sep) 604 { 605 if (__g_end-__g < __num_get_buf_sz) 606 { 607 *__g_end++ = __dc; 608 __dc = 0; 609 } 610 return 0; 611 } 612 ptrdiff_t __f = find(__atoms, __atoms + 26, __ct) - __atoms; 613 if (__f >= 24) 614 return -1; 615 switch (__base) 616 { 617 case 8: 618 case 10: 619 if (__f >= __base) 620 return -1; 621 break; 622 case 16: 623 if (__f < 22) 624 break; 625 if (__a_end != __a && __a_end - __a <= 2 && __a_end[-1] == '0') 626 { 627 __dc = 0; 628 *__a_end++ = __src[__f]; 629 return 0; 630 } 631 return -1; 632 } 633 if (__a_end-__a < __num_get_buf_sz - 1) 634 *__a_end++ = __src[__f]; 635 ++__dc; 636 return 0; 637} 638 639template <class _CharT> 640int 641__num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, char* __a, char*& __a_end, 642 _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping, 643 unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms) 644{ 645 if (__ct == __decimal_point) 646 { 647 if (!__in_units) 648 return -1; 649 __in_units = false; 650 *__a_end++ = '.'; 651 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz) 652 *__g_end++ = __dc; 653 return 0; 654 } 655 if (__ct == __thousands_sep && __grouping.size() != 0) 656 { 657 if (!__in_units) 658 return -1; 659 if (__g_end-__g < __num_get_buf_sz) 660 { 661 *__g_end++ = __dc; 662 __dc = 0; 663 } 664 return 0; 665 } 666 ptrdiff_t __f = find(__atoms, __atoms + 32, __ct) - __atoms; 667 if (__f >= 32) 668 return -1; 669 char __x = __src[__f]; 670 if (__x == '-' || __x == '+') 671 { 672 if (__a_end == __a || (__a_end[-1] & 0xDF) == __exp) 673 { 674 *__a_end++ = __x; 675 return 0; 676 } 677 return -1; 678 } 679 if (__a_end-__a < __num_get_buf_sz - 1) 680 *__a_end++ = __x; 681 if (__x == 'x' || __x == 'X') 682 __exp = 'P'; 683 else if ((__x & 0xDF) == __exp) 684 { 685 __in_units = false; 686 if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz) 687 *__g_end++ = __dc; 688 } 689 if (__f >= 22) 690 return 0; 691 ++__dc; 692 return 0; 693} 694 695extern template struct __num_get<char>; 696extern template struct __num_get<wchar_t>; 697 698template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 699class _LIBCPP_VISIBLE num_get 700 : public locale::facet, 701 private __num_get<_CharT> 702{ 703public: 704 typedef _CharT char_type; 705 typedef _InputIterator iter_type; 706 707 _LIBCPP_ALWAYS_INLINE 708 explicit num_get(size_t __refs = 0) 709 : locale::facet(__refs) {} 710 711 _LIBCPP_ALWAYS_INLINE 712 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 713 ios_base::iostate& __err, bool& __v) const 714 { 715 return do_get(__b, __e, __iob, __err, __v); 716 } 717 718 _LIBCPP_ALWAYS_INLINE 719 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 720 ios_base::iostate& __err, long& __v) const 721 { 722 return do_get(__b, __e, __iob, __err, __v); 723 } 724 725 _LIBCPP_ALWAYS_INLINE 726 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 727 ios_base::iostate& __err, long long& __v) const 728 { 729 return do_get(__b, __e, __iob, __err, __v); 730 } 731 732 _LIBCPP_ALWAYS_INLINE 733 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 734 ios_base::iostate& __err, unsigned short& __v) const 735 { 736 return do_get(__b, __e, __iob, __err, __v); 737 } 738 739 _LIBCPP_ALWAYS_INLINE 740 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 741 ios_base::iostate& __err, unsigned int& __v) const 742 { 743 return do_get(__b, __e, __iob, __err, __v); 744 } 745 746 _LIBCPP_ALWAYS_INLINE 747 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 748 ios_base::iostate& __err, unsigned long& __v) const 749 { 750 return do_get(__b, __e, __iob, __err, __v); 751 } 752 753 _LIBCPP_ALWAYS_INLINE 754 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 755 ios_base::iostate& __err, unsigned long long& __v) const 756 { 757 return do_get(__b, __e, __iob, __err, __v); 758 } 759 760 _LIBCPP_ALWAYS_INLINE 761 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 762 ios_base::iostate& __err, float& __v) const 763 { 764 return do_get(__b, __e, __iob, __err, __v); 765 } 766 767 _LIBCPP_ALWAYS_INLINE 768 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 769 ios_base::iostate& __err, double& __v) const 770 { 771 return do_get(__b, __e, __iob, __err, __v); 772 } 773 774 _LIBCPP_ALWAYS_INLINE 775 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 776 ios_base::iostate& __err, long double& __v) const 777 { 778 return do_get(__b, __e, __iob, __err, __v); 779 } 780 781 _LIBCPP_ALWAYS_INLINE 782 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 783 ios_base::iostate& __err, void*& __v) const 784 { 785 return do_get(__b, __e, __iob, __err, __v); 786 } 787 788 static locale::id id; 789 790protected: 791 _LIBCPP_ALWAYS_INLINE 792 ~num_get() {} 793 794 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 795 ios_base::iostate& __err, bool& __v) const; 796 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 797 ios_base::iostate& __err, long& __v) const; 798 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 799 ios_base::iostate& __err, long long& __v) const; 800 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 801 ios_base::iostate& __err, unsigned short& __v) const; 802 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 803 ios_base::iostate& __err, unsigned int& __v) const; 804 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 805 ios_base::iostate& __err, unsigned long& __v) const; 806 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 807 ios_base::iostate& __err, unsigned long long& __v) const; 808 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 809 ios_base::iostate& __err, float& __v) const; 810 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 811 ios_base::iostate& __err, double& __v) const; 812 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 813 ios_base::iostate& __err, long double& __v) const; 814 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 815 ios_base::iostate& __err, void*& __v) const; 816}; 817 818template <class _CharT, class _InputIterator> 819locale::id 820num_get<_CharT, _InputIterator>::id; 821 822template <class _Tp> 823_Tp 824__num_get_signed_integral(const char* __a, const char* __a_end, 825 ios_base::iostate& __err, int __base) 826{ 827 if (__a != __a_end) 828 { 829 int __save_errno = errno; 830 errno = 0; 831 char *__p2; 832 long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); 833 int __current_errno = errno; 834 if (__current_errno == 0) 835 errno = __save_errno; 836 if (__p2 != __a_end) 837 { 838 __err = ios_base::failbit; 839 return 0; 840 } 841 else if (__current_errno == ERANGE || 842 __ll < numeric_limits<_Tp>::min() || 843 numeric_limits<_Tp>::max() < __ll) 844 { 845 __err = ios_base::failbit; 846 if (__ll > 0) 847 return numeric_limits<_Tp>::max(); 848 else 849 return numeric_limits<_Tp>::min(); 850 } 851 return static_cast<_Tp>(__ll); 852 } 853 __err = ios_base::failbit; 854 return 0; 855} 856 857template <class _Tp> 858_Tp 859__num_get_unsigned_integral(const char* __a, const char* __a_end, 860 ios_base::iostate& __err, int __base) 861{ 862 if (__a != __a_end) 863 { 864 if (*__a == '-') 865 { 866 __err = ios_base::failbit; 867 return 0; 868 } 869 int __save_errno = errno; 870 errno = 0; 871 char *__p2; 872 unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE); 873 int __current_errno = errno; 874 if (__current_errno == 0) 875 errno = __save_errno; 876 if (__p2 != __a_end) 877 { 878 __err = ios_base::failbit; 879 return 0; 880 } 881 else if (__current_errno == ERANGE || 882 numeric_limits<_Tp>::max() < __ll) 883 { 884 __err = ios_base::failbit; 885 return numeric_limits<_Tp>::max(); 886 } 887 return static_cast<_Tp>(__ll); 888 } 889 __err = ios_base::failbit; 890 return 0; 891} 892 893template <class _Tp> 894_Tp 895__num_get_float(const char* __a, const char* __a_end, ios_base::iostate& __err) 896{ 897 if (__a != __a_end) 898 { 899 char *__p2; 900 long double __ld = strtold_l(__a, &__p2, _LIBCPP_GET_C_LOCALE); 901 if (__p2 != __a_end) 902 { 903 __err = ios_base::failbit; 904 return 0; 905 } 906 return static_cast<_Tp>(__ld); 907 } 908 __err = ios_base::failbit; 909 return 0; 910} 911 912template <class _CharT, class _InputIterator> 913_InputIterator 914num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 915 ios_base& __iob, 916 ios_base::iostate& __err, 917 bool& __v) const 918{ 919 if ((__iob.flags() & ios_base::boolalpha) == 0) 920 { 921 long __lv = -1; 922 __b = do_get(__b, __e, __iob, __err, __lv); 923 switch (__lv) 924 { 925 case 0: 926 __v = false; 927 break; 928 case 1: 929 __v = true; 930 break; 931 default: 932 __v = true; 933 __err = ios_base::failbit; 934 break; 935 } 936 return __b; 937 } 938 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__iob.getloc()); 939 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__iob.getloc()); 940 typedef typename numpunct<_CharT>::string_type string_type; 941 const string_type __names[2] = {__np.truename(), __np.falsename()}; 942 const string_type* __i = __scan_keyword(__b, __e, __names, __names+2, 943 __ct, __err); 944 __v = __i == __names; 945 return __b; 946} 947 948template <class _CharT, class _InputIterator> 949_InputIterator 950num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 951 ios_base& __iob, 952 ios_base::iostate& __err, 953 long& __v) const 954{ 955 // Stage 1 956 int __base = this->__get_base(__iob); 957 // Stage 2 958 char_type __atoms[26]; 959 char_type __thousands_sep; 960 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 961 char __a[__num_get_base::__num_get_buf_sz] = {0}; 962 char* __a_end = __a; 963 unsigned __g[__num_get_base::__num_get_buf_sz]; 964 unsigned* __g_end = __g; 965 unsigned __dc = 0; 966 for (; __b != __e; ++__b) 967 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 968 __thousands_sep, __grouping, __g, __g_end, 969 __atoms)) 970 break; 971 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 972 *__g_end++ = __dc; 973 // Stage 3 974 __v = __num_get_signed_integral<long>(__a, __a_end, __err, __base); 975 // Digit grouping checked 976 __check_grouping(__grouping, __g, __g_end, __err); 977 // EOF checked 978 if (__b == __e) 979 __err |= ios_base::eofbit; 980 return __b; 981} 982 983template <class _CharT, class _InputIterator> 984_InputIterator 985num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 986 ios_base& __iob, 987 ios_base::iostate& __err, 988 long long& __v) const 989{ 990 // Stage 1 991 int __base = this->__get_base(__iob); 992 // Stage 2 993 char_type __atoms[26]; 994 char_type __thousands_sep; 995 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 996 char __a[__num_get_base::__num_get_buf_sz] = {0}; 997 char* __a_end = __a; 998 unsigned __g[__num_get_base::__num_get_buf_sz]; 999 unsigned* __g_end = __g; 1000 unsigned __dc = 0; 1001 for (; __b != __e; ++__b) 1002 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 1003 __thousands_sep, __grouping, __g, __g_end, 1004 __atoms)) 1005 break; 1006 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 1007 *__g_end++ = __dc; 1008 // Stage 3 1009 __v = __num_get_signed_integral<long long>(__a, __a_end, __err, __base); 1010 // Digit grouping checked 1011 __check_grouping(__grouping, __g, __g_end, __err); 1012 // EOF checked 1013 if (__b == __e) 1014 __err |= ios_base::eofbit; 1015 return __b; 1016} 1017 1018template <class _CharT, class _InputIterator> 1019_InputIterator 1020num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1021 ios_base& __iob, 1022 ios_base::iostate& __err, 1023 unsigned short& __v) const 1024{ 1025 // Stage 1 1026 int __base = this->__get_base(__iob); 1027 // Stage 2 1028 char_type __atoms[26]; 1029 char_type __thousands_sep; 1030 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 1031 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1032 char* __a_end = __a; 1033 unsigned __g[__num_get_base::__num_get_buf_sz]; 1034 unsigned* __g_end = __g; 1035 unsigned __dc = 0; 1036 for (; __b != __e; ++__b) 1037 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 1038 __thousands_sep, __grouping, __g, __g_end, 1039 __atoms)) 1040 break; 1041 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 1042 *__g_end++ = __dc; 1043 // Stage 3 1044 __v = __num_get_unsigned_integral<unsigned short>(__a, __a_end, __err, __base); 1045 // Digit grouping checked 1046 __check_grouping(__grouping, __g, __g_end, __err); 1047 // EOF checked 1048 if (__b == __e) 1049 __err |= ios_base::eofbit; 1050 return __b; 1051} 1052 1053template <class _CharT, class _InputIterator> 1054_InputIterator 1055num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1056 ios_base& __iob, 1057 ios_base::iostate& __err, 1058 unsigned int& __v) const 1059{ 1060 // Stage 1 1061 int __base = this->__get_base(__iob); 1062 // Stage 2 1063 char_type __atoms[26]; 1064 char_type __thousands_sep; 1065 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 1066 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1067 char* __a_end = __a; 1068 unsigned __g[__num_get_base::__num_get_buf_sz]; 1069 unsigned* __g_end = __g; 1070 unsigned __dc = 0; 1071 for (; __b != __e; ++__b) 1072 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 1073 __thousands_sep, __grouping, __g, __g_end, 1074 __atoms)) 1075 break; 1076 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 1077 *__g_end++ = __dc; 1078 // Stage 3 1079 __v = __num_get_unsigned_integral<unsigned int>(__a, __a_end, __err, __base); 1080 // Digit grouping checked 1081 __check_grouping(__grouping, __g, __g_end, __err); 1082 // EOF checked 1083 if (__b == __e) 1084 __err |= ios_base::eofbit; 1085 return __b; 1086} 1087 1088template <class _CharT, class _InputIterator> 1089_InputIterator 1090num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1091 ios_base& __iob, 1092 ios_base::iostate& __err, 1093 unsigned long& __v) const 1094{ 1095 // Stage 1 1096 int __base = this->__get_base(__iob); 1097 // Stage 2 1098 char_type __atoms[26]; 1099 char_type __thousands_sep; 1100 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 1101 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1102 char* __a_end = __a; 1103 unsigned __g[__num_get_base::__num_get_buf_sz]; 1104 unsigned* __g_end = __g; 1105 unsigned __dc = 0; 1106 for (; __b != __e; ++__b) 1107 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 1108 __thousands_sep, __grouping, __g, __g_end, 1109 __atoms)) 1110 break; 1111 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 1112 *__g_end++ = __dc; 1113 // Stage 3 1114 __v = __num_get_unsigned_integral<unsigned long>(__a, __a_end, __err, __base); 1115 // Digit grouping checked 1116 __check_grouping(__grouping, __g, __g_end, __err); 1117 // EOF checked 1118 if (__b == __e) 1119 __err |= ios_base::eofbit; 1120 return __b; 1121} 1122 1123template <class _CharT, class _InputIterator> 1124_InputIterator 1125num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1126 ios_base& __iob, 1127 ios_base::iostate& __err, 1128 unsigned long long& __v) const 1129{ 1130 // Stage 1 1131 int __base = this->__get_base(__iob); 1132 // Stage 2 1133 char_type __atoms[26]; 1134 char_type __thousands_sep; 1135 string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); 1136 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1137 char* __a_end = __a; 1138 unsigned __g[__num_get_base::__num_get_buf_sz]; 1139 unsigned* __g_end = __g; 1140 unsigned __dc = 0; 1141 for (; __b != __e; ++__b) 1142 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 1143 __thousands_sep, __grouping, __g, __g_end, 1144 __atoms)) 1145 break; 1146 if (__grouping.size() != 0 && __g_end-__g < __num_get_base::__num_get_buf_sz) 1147 *__g_end++ = __dc; 1148 // Stage 3 1149 __v = __num_get_unsigned_integral<unsigned long long>(__a, __a_end, __err, __base); 1150 // Digit grouping checked 1151 __check_grouping(__grouping, __g, __g_end, __err); 1152 // EOF checked 1153 if (__b == __e) 1154 __err |= ios_base::eofbit; 1155 return __b; 1156} 1157 1158template <class _CharT, class _InputIterator> 1159_InputIterator 1160num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1161 ios_base& __iob, 1162 ios_base::iostate& __err, 1163 float& __v) const 1164{ 1165 // Stage 1, nothing to do 1166 // Stage 2 1167 char_type __atoms[32]; 1168 char_type __decimal_point; 1169 char_type __thousands_sep; 1170 string __grouping = this->__stage2_float_prep(__iob, __atoms, 1171 __decimal_point, 1172 __thousands_sep); 1173 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1174 char* __a_end = __a; 1175 unsigned __g[__num_get_base::__num_get_buf_sz]; 1176 unsigned* __g_end = __g; 1177 unsigned __dc = 0; 1178 bool __in_units = true; 1179 char __exp = 'E'; 1180 for (; __b != __e; ++__b) 1181 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end, 1182 __decimal_point, __thousands_sep, 1183 __grouping, __g, __g_end, 1184 __dc, __atoms)) 1185 break; 1186 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz) 1187 *__g_end++ = __dc; 1188 // Stage 3 1189 __v = __num_get_float<float>(__a, __a_end, __err); 1190 // Digit grouping checked 1191 __check_grouping(__grouping, __g, __g_end, __err); 1192 // EOF checked 1193 if (__b == __e) 1194 __err |= ios_base::eofbit; 1195 return __b; 1196} 1197 1198template <class _CharT, class _InputIterator> 1199_InputIterator 1200num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1201 ios_base& __iob, 1202 ios_base::iostate& __err, 1203 double& __v) const 1204{ 1205 // Stage 1, nothing to do 1206 // Stage 2 1207 char_type __atoms[32]; 1208 char_type __decimal_point; 1209 char_type __thousands_sep; 1210 string __grouping = this->__stage2_float_prep(__iob, __atoms, 1211 __decimal_point, 1212 __thousands_sep); 1213 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1214 char* __a_end = __a; 1215 unsigned __g[__num_get_base::__num_get_buf_sz]; 1216 unsigned* __g_end = __g; 1217 unsigned __dc = 0; 1218 bool __in_units = true; 1219 char __exp = 'E'; 1220 for (; __b != __e; ++__b) 1221 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end, 1222 __decimal_point, __thousands_sep, 1223 __grouping, __g, __g_end, 1224 __dc, __atoms)) 1225 break; 1226 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz) 1227 *__g_end++ = __dc; 1228 // Stage 3 1229 __v = __num_get_float<double>(__a, __a_end, __err); 1230 // Digit grouping checked 1231 __check_grouping(__grouping, __g, __g_end, __err); 1232 // EOF checked 1233 if (__b == __e) 1234 __err |= ios_base::eofbit; 1235 return __b; 1236} 1237 1238template <class _CharT, class _InputIterator> 1239_InputIterator 1240num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1241 ios_base& __iob, 1242 ios_base::iostate& __err, 1243 long double& __v) const 1244{ 1245 // Stage 1, nothing to do 1246 // Stage 2 1247 char_type __atoms[32]; 1248 char_type __decimal_point; 1249 char_type __thousands_sep; 1250 string __grouping = this->__stage2_float_prep(__iob, __atoms, 1251 __decimal_point, 1252 __thousands_sep); 1253 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1254 char* __a_end = __a; 1255 unsigned __g[__num_get_base::__num_get_buf_sz]; 1256 unsigned* __g_end = __g; 1257 unsigned __dc = 0; 1258 bool __in_units = true; 1259 char __exp = 'E'; 1260 for (; __b != __e; ++__b) 1261 if (this->__stage2_float_loop(*__b, __in_units, __exp, __a, __a_end, 1262 __decimal_point, __thousands_sep, 1263 __grouping, __g, __g_end, 1264 __dc, __atoms)) 1265 break; 1266 if (__grouping.size() != 0 && __in_units && __g_end-__g < __num_get_base::__num_get_buf_sz) 1267 *__g_end++ = __dc; 1268 // Stage 3 1269 __v = __num_get_float<long double>(__a, __a_end, __err); 1270 // Digit grouping checked 1271 __check_grouping(__grouping, __g, __g_end, __err); 1272 // EOF checked 1273 if (__b == __e) 1274 __err |= ios_base::eofbit; 1275 return __b; 1276} 1277 1278template <class _CharT, class _InputIterator> 1279_InputIterator 1280num_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 1281 ios_base& __iob, 1282 ios_base::iostate& __err, 1283 void*& __v) const 1284{ 1285 // Stage 1 1286 int __base = 16; 1287 // Stage 2 1288 char_type __atoms[26]; 1289 char_type __thousands_sep = 0; 1290 string __grouping; 1291 use_facet<ctype<_CharT> >(__iob.getloc()).widen(__num_get_base::__src, 1292 __num_get_base::__src + 26, __atoms); 1293 char __a[__num_get_base::__num_get_buf_sz] = {0}; 1294 char* __a_end = __a; 1295 unsigned __g[__num_get_base::__num_get_buf_sz]; 1296 unsigned* __g_end = __g; 1297 unsigned __dc = 0; 1298 for (; __b != __e; ++__b) 1299 if (this->__stage2_int_loop(*__b, __base, __a, __a_end, __dc, 1300 __thousands_sep, __grouping, 1301 __g, __g_end, __atoms)) 1302 break; 1303 // Stage 3 1304 __a[sizeof(__a)-1] = 0; 1305#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1306 if (sscanf_l(__a, _LIBCPP_GET_C_LOCALE, "%p", &__v) != 1) 1307#else 1308 if (__sscanf_l(__a, __cloc(), "%p", &__v) != 1) 1309#endif 1310 __err = ios_base::failbit; 1311 // EOF checked 1312 if (__b == __e) 1313 __err |= ios_base::eofbit; 1314 return __b; 1315} 1316 1317extern template class num_get<char>; 1318extern template class num_get<wchar_t>; 1319 1320struct __num_put_base 1321{ 1322protected: 1323 static void __format_int(char* __fmt, const char* __len, bool __signd, 1324 ios_base::fmtflags __flags); 1325 static bool __format_float(char* __fmt, const char* __len, 1326 ios_base::fmtflags __flags); 1327 static char* __identify_padding(char* __nb, char* __ne, 1328 const ios_base& __iob); 1329}; 1330 1331template <class _CharT> 1332struct __num_put 1333 : protected __num_put_base 1334{ 1335 static void __widen_and_group_int(char* __nb, char* __np, char* __ne, 1336 _CharT* __ob, _CharT*& __op, _CharT*& __oe, 1337 const locale& __loc); 1338 static void __widen_and_group_float(char* __nb, char* __np, char* __ne, 1339 _CharT* __ob, _CharT*& __op, _CharT*& __oe, 1340 const locale& __loc); 1341}; 1342 1343template <class _CharT> 1344void 1345__num_put<_CharT>::__widen_and_group_int(char* __nb, char* __np, char* __ne, 1346 _CharT* __ob, _CharT*& __op, _CharT*& __oe, 1347 const locale& __loc) 1348{ 1349 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc); 1350 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc); 1351 string __grouping = __npt.grouping(); 1352 if (__grouping.empty()) 1353 { 1354 __ct.widen(__nb, __ne, __ob); 1355 __oe = __ob + (__ne - __nb); 1356 } 1357 else 1358 { 1359 __oe = __ob; 1360 char* __nf = __nb; 1361 if (*__nf == '-' || *__nf == '+') 1362 *__oe++ = __ct.widen(*__nf++); 1363 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' || 1364 __nf[1] == 'X')) 1365 { 1366 *__oe++ = __ct.widen(*__nf++); 1367 *__oe++ = __ct.widen(*__nf++); 1368 } 1369 reverse(__nf, __ne); 1370 _CharT __thousands_sep = __npt.thousands_sep(); 1371 unsigned __dc = 0; 1372 unsigned __dg = 0; 1373 for (char* __p = __nf; __p < __ne; ++__p) 1374 { 1375 if (static_cast<unsigned>(__grouping[__dg]) > 0 && 1376 __dc == static_cast<unsigned>(__grouping[__dg])) 1377 { 1378 *__oe++ = __thousands_sep; 1379 __dc = 0; 1380 if (__dg < __grouping.size()-1) 1381 ++__dg; 1382 } 1383 *__oe++ = __ct.widen(*__p); 1384 ++__dc; 1385 } 1386 reverse(__ob + (__nf - __nb), __oe); 1387 } 1388 if (__np == __ne) 1389 __op = __oe; 1390 else 1391 __op = __ob + (__np - __nb); 1392} 1393 1394template <class _CharT> 1395void 1396__num_put<_CharT>::__widen_and_group_float(char* __nb, char* __np, char* __ne, 1397 _CharT* __ob, _CharT*& __op, _CharT*& __oe, 1398 const locale& __loc) 1399{ 1400 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> > (__loc); 1401 const numpunct<_CharT>& __npt = use_facet<numpunct<_CharT> >(__loc); 1402 string __grouping = __npt.grouping(); 1403 __oe = __ob; 1404 char* __nf = __nb; 1405 if (*__nf == '-' || *__nf == '+') 1406 *__oe++ = __ct.widen(*__nf++); 1407 char* __ns; 1408 if (__ne - __nf >= 2 && __nf[0] == '0' && (__nf[1] == 'x' || 1409 __nf[1] == 'X')) 1410 { 1411 *__oe++ = __ct.widen(*__nf++); 1412 *__oe++ = __ct.widen(*__nf++); 1413 for (__ns = __nf; __ns < __ne; ++__ns) 1414 if (!isxdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) 1415 break; 1416 } 1417 else 1418 { 1419 for (__ns = __nf; __ns < __ne; ++__ns) 1420 if (!isdigit_l(*__ns, _LIBCPP_GET_C_LOCALE)) 1421 break; 1422 } 1423 if (__grouping.empty()) 1424 { 1425 __ct.widen(__nf, __ns, __oe); 1426 __oe += __ns - __nf; 1427 } 1428 else 1429 { 1430 reverse(__nf, __ns); 1431 _CharT __thousands_sep = __npt.thousands_sep(); 1432 unsigned __dc = 0; 1433 unsigned __dg = 0; 1434 for (char* __p = __nf; __p < __ns; ++__p) 1435 { 1436 if (__grouping[__dg] > 0 && __dc == static_cast<unsigned>(__grouping[__dg])) 1437 { 1438 *__oe++ = __thousands_sep; 1439 __dc = 0; 1440 if (__dg < __grouping.size()-1) 1441 ++__dg; 1442 } 1443 *__oe++ = __ct.widen(*__p); 1444 ++__dc; 1445 } 1446 reverse(__ob + (__nf - __nb), __oe); 1447 } 1448 for (__nf = __ns; __nf < __ne; ++__nf) 1449 { 1450 if (*__nf == '.') 1451 { 1452 *__oe++ = __npt.decimal_point(); 1453 ++__nf; 1454 break; 1455 } 1456 else 1457 *__oe++ = __ct.widen(*__nf); 1458 } 1459 __ct.widen(__nf, __ne, __oe); 1460 __oe += __ne - __nf; 1461 if (__np == __ne) 1462 __op = __oe; 1463 else 1464 __op = __ob + (__np - __nb); 1465} 1466 1467extern template struct __num_put<char>; 1468extern template struct __num_put<wchar_t>; 1469 1470template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 1471class _LIBCPP_VISIBLE num_put 1472 : public locale::facet, 1473 private __num_put<_CharT> 1474{ 1475public: 1476 typedef _CharT char_type; 1477 typedef _OutputIterator iter_type; 1478 1479 _LIBCPP_ALWAYS_INLINE 1480 explicit num_put(size_t __refs = 0) 1481 : locale::facet(__refs) {} 1482 1483 _LIBCPP_ALWAYS_INLINE 1484 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1485 bool __v) const 1486 { 1487 return do_put(__s, __iob, __fl, __v); 1488 } 1489 1490 _LIBCPP_ALWAYS_INLINE 1491 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1492 long __v) const 1493 { 1494 return do_put(__s, __iob, __fl, __v); 1495 } 1496 1497 _LIBCPP_ALWAYS_INLINE 1498 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1499 long long __v) const 1500 { 1501 return do_put(__s, __iob, __fl, __v); 1502 } 1503 1504 _LIBCPP_ALWAYS_INLINE 1505 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1506 unsigned long __v) const 1507 { 1508 return do_put(__s, __iob, __fl, __v); 1509 } 1510 1511 _LIBCPP_ALWAYS_INLINE 1512 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1513 unsigned long long __v) const 1514 { 1515 return do_put(__s, __iob, __fl, __v); 1516 } 1517 1518 _LIBCPP_ALWAYS_INLINE 1519 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1520 double __v) const 1521 { 1522 return do_put(__s, __iob, __fl, __v); 1523 } 1524 1525 _LIBCPP_ALWAYS_INLINE 1526 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1527 long double __v) const 1528 { 1529 return do_put(__s, __iob, __fl, __v); 1530 } 1531 1532 _LIBCPP_ALWAYS_INLINE 1533 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 1534 const void* __v) const 1535 { 1536 return do_put(__s, __iob, __fl, __v); 1537 } 1538 1539 static locale::id id; 1540 1541protected: 1542 _LIBCPP_ALWAYS_INLINE 1543 ~num_put() {} 1544 1545 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1546 bool __v) const; 1547 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1548 long __v) const; 1549 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1550 long long __v) const; 1551 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1552 unsigned long) const; 1553 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1554 unsigned long long) const; 1555 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1556 double __v) const; 1557 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1558 long double __v) const; 1559 virtual iter_type do_put(iter_type __s, ios_base& __iob, char_type __fl, 1560 const void* __v) const; 1561}; 1562 1563template <class _CharT, class _OutputIterator> 1564locale::id 1565num_put<_CharT, _OutputIterator>::id; 1566 1567template <class _CharT, class _OutputIterator> 1568_LIBCPP_HIDDEN 1569_OutputIterator 1570__pad_and_output(_OutputIterator __s, 1571 const _CharT* __ob, const _CharT* __op, const _CharT* __oe, 1572 ios_base& __iob, _CharT __fl) 1573{ 1574 streamsize __sz = __oe - __ob; 1575 streamsize __ns = __iob.width(); 1576 if (__ns > __sz) 1577 __ns -= __sz; 1578 else 1579 __ns = 0; 1580 for (;__ob < __op; ++__ob, ++__s) 1581 *__s = *__ob; 1582 for (; __ns; --__ns, ++__s) 1583 *__s = __fl; 1584 for (; __ob < __oe; ++__ob, ++__s) 1585 *__s = *__ob; 1586 __iob.width(0); 1587 return __s; 1588} 1589 1590template <class _CharT, class _OutputIterator> 1591_OutputIterator 1592num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1593 char_type __fl, bool __v) const 1594{ 1595 if ((__iob.flags() & ios_base::boolalpha) == 0) 1596 return do_put(__s, __iob, __fl, (unsigned long)__v); 1597 const numpunct<char_type>& __np = use_facet<numpunct<char_type> >(__iob.getloc()); 1598 typedef typename numpunct<char_type>::string_type string_type; 1599 string_type __nm = __v ? __np.truename() : __np.falsename(); 1600 for (typename string_type::iterator __i = __nm.begin(); __i != __nm.end(); ++__i, ++__s) 1601 *__s = *__i; 1602 return __s; 1603} 1604 1605template <class _CharT, class _OutputIterator> 1606_OutputIterator 1607num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1608 char_type __fl, long __v) const 1609{ 1610 // Stage 1 - Get number in narrow char 1611 char __fmt[6] = {'%', 0}; 1612 const char* __len = "l"; 1613 this->__format_int(__fmt+1, __len, true, __iob.flags()); 1614 const unsigned __nbuf = (numeric_limits<long>::digits / 3) 1615 + ((numeric_limits<long>::digits % 3) != 0) 1616 + 1; 1617 char __nar[__nbuf]; 1618#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1619 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1620#else 1621 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v); 1622#endif 1623 char* __ne = __nar + __nc; 1624 char* __np = this->__identify_padding(__nar, __ne, __iob); 1625 // Stage 2 - Widen __nar while adding thousands separators 1626 char_type __o[2*(__nbuf-1) - 1]; 1627 char_type* __op; // pad here 1628 char_type* __oe; // end of output 1629 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1630 // [__o, __oe) contains thousands_sep'd wide number 1631 // Stage 3 & 4 1632 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1633} 1634 1635template <class _CharT, class _OutputIterator> 1636_OutputIterator 1637num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1638 char_type __fl, long long __v) const 1639{ 1640 // Stage 1 - Get number in narrow char 1641 char __fmt[8] = {'%', 0}; 1642 const char* __len = "ll"; 1643 this->__format_int(__fmt+1, __len, true, __iob.flags()); 1644 const unsigned __nbuf = (numeric_limits<long long>::digits / 3) 1645 + ((numeric_limits<long long>::digits % 3) != 0) 1646 + 1; 1647 char __nar[__nbuf]; 1648#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1649 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1650#else 1651 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v); 1652#endif 1653 char* __ne = __nar + __nc; 1654 char* __np = this->__identify_padding(__nar, __ne, __iob); 1655 // Stage 2 - Widen __nar while adding thousands separators 1656 char_type __o[2*(__nbuf-1) - 1]; 1657 char_type* __op; // pad here 1658 char_type* __oe; // end of output 1659 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1660 // [__o, __oe) contains thousands_sep'd wide number 1661 // Stage 3 & 4 1662 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1663} 1664 1665template <class _CharT, class _OutputIterator> 1666_OutputIterator 1667num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1668 char_type __fl, unsigned long __v) const 1669{ 1670 // Stage 1 - Get number in narrow char 1671 char __fmt[6] = {'%', 0}; 1672 const char* __len = "l"; 1673 this->__format_int(__fmt+1, __len, false, __iob.flags()); 1674 const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3) 1675 + ((numeric_limits<unsigned long>::digits % 3) != 0) 1676 + 1; 1677 char __nar[__nbuf]; 1678#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1679 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1680#else 1681 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v); 1682#endif 1683 char* __ne = __nar + __nc; 1684 char* __np = this->__identify_padding(__nar, __ne, __iob); 1685 // Stage 2 - Widen __nar while adding thousands separators 1686 char_type __o[2*(__nbuf-1) - 1]; 1687 char_type* __op; // pad here 1688 char_type* __oe; // end of output 1689 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1690 // [__o, __oe) contains thousands_sep'd wide number 1691 // Stage 3 & 4 1692 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1693} 1694 1695template <class _CharT, class _OutputIterator> 1696_OutputIterator 1697num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1698 char_type __fl, unsigned long long __v) const 1699{ 1700 // Stage 1 - Get number in narrow char 1701 char __fmt[8] = {'%', 0}; 1702 const char* __len = "ll"; 1703 this->__format_int(__fmt+1, __len, false, __iob.flags()); 1704 const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3) 1705 + ((numeric_limits<unsigned long long>::digits % 3) != 0) 1706 + 1; 1707 char __nar[__nbuf]; 1708#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1709 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1710#else 1711 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v); 1712#endif 1713 char* __ne = __nar + __nc; 1714 char* __np = this->__identify_padding(__nar, __ne, __iob); 1715 // Stage 2 - Widen __nar while adding thousands separators 1716 char_type __o[2*(__nbuf-1) - 1]; 1717 char_type* __op; // pad here 1718 char_type* __oe; // end of output 1719 this->__widen_and_group_int(__nar, __np, __ne, __o, __op, __oe, __iob.getloc()); 1720 // [__o, __oe) contains thousands_sep'd wide number 1721 // Stage 3 & 4 1722 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1723} 1724 1725template <class _CharT, class _OutputIterator> 1726_OutputIterator 1727num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1728 char_type __fl, double __v) const 1729{ 1730 // Stage 1 - Get number in narrow char 1731 char __fmt[8] = {'%', 0}; 1732 const char* __len = ""; 1733 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags()); 1734 const unsigned __nbuf = 30; 1735 char __nar[__nbuf]; 1736 char* __nb = __nar; 1737 int __nc; 1738 if (__specify_precision) 1739#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1740 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, 1741 (int)__iob.precision(), __v); 1742#else 1743 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, 1744 (int)__iob.precision(), __v); 1745#endif 1746 else 1747#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1748 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1749#else 1750 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v); 1751#endif 1752 unique_ptr<char, void(*)(void*)> __nbh(0, free); 1753 if (__nc > static_cast<int>(__nbuf-1)) 1754 { 1755 if (__specify_precision) 1756#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1757 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); 1758#else 1759 __nc = __asprintf_l(&__nb, __cloc(), __fmt, 1760 (int)__iob.precision(), __v); 1761#endif 1762 else 1763#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1764 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1765#else 1766 __nc = __asprintf_l(&__nb, __cloc(), __fmt, (int)__iob.precision(), __v); 1767#endif 1768 if (__nb == 0) 1769 __throw_bad_alloc(); 1770 __nbh.reset(__nb); 1771 } 1772 char* __ne = __nb + __nc; 1773 char* __np = this->__identify_padding(__nb, __ne, __iob); 1774 // Stage 2 - Widen __nar while adding thousands separators 1775 char_type __o[2*(__nbuf-1) - 1]; 1776 char_type* __ob = __o; 1777 unique_ptr<char_type, void(*)(void*)> __obh(0, free); 1778 if (__nb != __nar) 1779 { 1780 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type)); 1781 if (__ob == 0) 1782 __throw_bad_alloc(); 1783 __obh.reset(__ob); 1784 } 1785 char_type* __op; // pad here 1786 char_type* __oe; // end of output 1787 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc()); 1788 // [__o, __oe) contains thousands_sep'd wide number 1789 // Stage 3 & 4 1790 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl); 1791 return __s; 1792} 1793 1794template <class _CharT, class _OutputIterator> 1795_OutputIterator 1796num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1797 char_type __fl, long double __v) const 1798{ 1799 // Stage 1 - Get number in narrow char 1800 char __fmt[8] = {'%', 0}; 1801 const char* __len = "L"; 1802 bool __specify_precision = this->__format_float(__fmt+1, __len, __iob.flags()); 1803 const unsigned __nbuf = 30; 1804 char __nar[__nbuf]; 1805 char* __nb = __nar; 1806 int __nc; 1807 if (__specify_precision) 1808#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1809 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, 1810 (int)__iob.precision(), __v); 1811#else 1812 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, 1813 (int)__iob.precision(), __v); 1814#endif 1815 else 1816#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1817 __nc = snprintf_l(__nb, __nbuf, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1818#else 1819 __nc = __snprintf_l(__nb, __nbuf, __cloc(), __fmt, __v); 1820#endif 1821 unique_ptr<char, void(*)(void*)> __nbh(0, free); 1822 if (__nc > static_cast<int>(__nbuf-1)) 1823 { 1824 if (__specify_precision) 1825#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1826 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, (int)__iob.precision(), __v); 1827#else 1828 __nc = __asprintf_l(&__nb, __cloc(), __fmt, 1829 (int)__iob.precision(), __v); 1830#endif 1831 else 1832#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1833 __nc = asprintf_l(&__nb, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1834#else 1835 __nc = __asprintf_l(&__nb, __cloc(), __fmt, __v); 1836#endif 1837 if (__nb == 0) 1838 __throw_bad_alloc(); 1839 __nbh.reset(__nb); 1840 } 1841 char* __ne = __nb + __nc; 1842 char* __np = this->__identify_padding(__nb, __ne, __iob); 1843 // Stage 2 - Widen __nar while adding thousands separators 1844 char_type __o[2*(__nbuf-1) - 1]; 1845 char_type* __ob = __o; 1846 unique_ptr<char_type, void(*)(void*)> __obh(0, free); 1847 if (__nb != __nar) 1848 { 1849 __ob = (char_type*)malloc(2*static_cast<size_t>(__nc)*sizeof(char_type)); 1850 if (__ob == 0) 1851 __throw_bad_alloc(); 1852 __obh.reset(__ob); 1853 } 1854 char_type* __op; // pad here 1855 char_type* __oe; // end of output 1856 this->__widen_and_group_float(__nb, __np, __ne, __ob, __op, __oe, __iob.getloc()); 1857 // [__o, __oe) contains thousands_sep'd wide number 1858 // Stage 3 & 4 1859 __s = __pad_and_output(__s, __ob, __op, __oe, __iob, __fl); 1860 return __s; 1861} 1862 1863template <class _CharT, class _OutputIterator> 1864_OutputIterator 1865num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob, 1866 char_type __fl, const void* __v) const 1867{ 1868 // Stage 1 - Get pointer in narrow char 1869 char __fmt[6] = "%p"; 1870 const unsigned __nbuf = 20; 1871 char __nar[__nbuf]; 1872#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 1873 int __nc = sprintf_l(__nar, _LIBCPP_GET_C_LOCALE, __fmt, __v); 1874#else 1875 int __nc = __sprintf_l(__nar, __cloc(), __fmt, __v); 1876#endif 1877 char* __ne = __nar + __nc; 1878 char* __np = this->__identify_padding(__nar, __ne, __iob); 1879 // Stage 2 - Widen __nar 1880 char_type __o[2*(__nbuf-1) - 1]; 1881 char_type* __op; // pad here 1882 char_type* __oe; // end of output 1883 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 1884 __ct.widen(__nar, __ne, __o); 1885 __oe = __o + (__ne - __nar); 1886 if (__np == __ne) 1887 __op = __oe; 1888 else 1889 __op = __o + (__np - __nar); 1890 // [__o, __oe) contains wide number 1891 // Stage 3 & 4 1892 return __pad_and_output(__s, __o, __op, __oe, __iob, __fl); 1893} 1894 1895extern template class num_put<char>; 1896extern template class num_put<wchar_t>; 1897 1898template <class _CharT, class _InputIterator> 1899_LIBCPP_HIDDEN 1900int 1901__get_up_to_n_digits(_InputIterator& __b, _InputIterator __e, 1902 ios_base::iostate& __err, const ctype<_CharT>& __ct, int __n) 1903{ 1904 // Precondition: __n >= 1 1905 if (__b == __e) 1906 { 1907 __err |= ios_base::eofbit | ios_base::failbit; 1908 return 0; 1909 } 1910 // get first digit 1911 _CharT __c = *__b; 1912 if (!__ct.is(ctype_base::digit, __c)) 1913 { 1914 __err |= ios_base::failbit; 1915 return 0; 1916 } 1917 int __r = __ct.narrow(__c, 0) - '0'; 1918 for (++__b, --__n; __b != __e && __n > 0; ++__b, --__n) 1919 { 1920 // get next digit 1921 __c = *__b; 1922 if (!__ct.is(ctype_base::digit, __c)) 1923 return __r; 1924 __r = __r * 10 + __ct.narrow(__c, 0) - '0'; 1925 } 1926 if (__b == __e) 1927 __err |= ios_base::eofbit; 1928 return __r; 1929} 1930 1931class _LIBCPP_VISIBLE time_base 1932{ 1933public: 1934 enum dateorder {no_order, dmy, mdy, ymd, ydm}; 1935}; 1936 1937template <class _CharT> 1938class __time_get_c_storage // purposefully not decorated 1939{ 1940protected: 1941 typedef basic_string<_CharT> string_type; 1942 1943 virtual const string_type* __weeks() const; 1944 virtual const string_type* __months() const; 1945 virtual const string_type* __am_pm() const; 1946 virtual const string_type& __c() const; 1947 virtual const string_type& __r() const; 1948 virtual const string_type& __x() const; 1949 virtual const string_type& __X() const; 1950}; 1951 1952template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 1953class _LIBCPP_VISIBLE time_get 1954 : public locale::facet, 1955 public time_base, 1956 private __time_get_c_storage<_CharT> 1957{ 1958public: 1959 typedef _CharT char_type; 1960 typedef _InputIterator iter_type; 1961 typedef time_base::dateorder dateorder; 1962 typedef basic_string<char_type> string_type; 1963 1964 _LIBCPP_ALWAYS_INLINE 1965 explicit time_get(size_t __refs = 0) 1966 : locale::facet(__refs) {} 1967 1968 _LIBCPP_ALWAYS_INLINE 1969 dateorder date_order() const 1970 { 1971 return this->do_date_order(); 1972 } 1973 1974 _LIBCPP_ALWAYS_INLINE 1975 iter_type get_time(iter_type __b, iter_type __e, ios_base& __iob, 1976 ios_base::iostate& __err, tm* __tm) const 1977 { 1978 return do_get_time(__b, __e, __iob, __err, __tm); 1979 } 1980 1981 _LIBCPP_ALWAYS_INLINE 1982 iter_type get_date(iter_type __b, iter_type __e, ios_base& __iob, 1983 ios_base::iostate& __err, tm* __tm) const 1984 { 1985 return do_get_date(__b, __e, __iob, __err, __tm); 1986 } 1987 1988 _LIBCPP_ALWAYS_INLINE 1989 iter_type get_weekday(iter_type __b, iter_type __e, ios_base& __iob, 1990 ios_base::iostate& __err, tm* __tm) const 1991 { 1992 return do_get_weekday(__b, __e, __iob, __err, __tm); 1993 } 1994 1995 _LIBCPP_ALWAYS_INLINE 1996 iter_type get_monthname(iter_type __b, iter_type __e, ios_base& __iob, 1997 ios_base::iostate& __err, tm* __tm) const 1998 { 1999 return do_get_monthname(__b, __e, __iob, __err, __tm); 2000 } 2001 2002 _LIBCPP_ALWAYS_INLINE 2003 iter_type get_year(iter_type __b, iter_type __e, ios_base& __iob, 2004 ios_base::iostate& __err, tm* __tm) const 2005 { 2006 return do_get_year(__b, __e, __iob, __err, __tm); 2007 } 2008 2009 _LIBCPP_ALWAYS_INLINE 2010 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 2011 ios_base::iostate& __err, tm *__tm, 2012 char __fmt, char __mod = 0) const 2013 { 2014 return do_get(__b, __e, __iob, __err, __tm, __fmt, __mod); 2015 } 2016 2017 iter_type get(iter_type __b, iter_type __e, ios_base& __iob, 2018 ios_base::iostate& __err, tm* __tm, 2019 const char_type* __fmtb, const char_type* __fmte) const; 2020 2021 static locale::id id; 2022 2023protected: 2024 _LIBCPP_ALWAYS_INLINE 2025 ~time_get() {} 2026 2027 virtual dateorder do_date_order() const; 2028 virtual iter_type do_get_time(iter_type __b, iter_type __e, ios_base& __iob, 2029 ios_base::iostate& __err, tm* __tm) const; 2030 virtual iter_type do_get_date(iter_type __b, iter_type __e, ios_base& __iob, 2031 ios_base::iostate& __err, tm* __tm) const; 2032 virtual iter_type do_get_weekday(iter_type __b, iter_type __e, ios_base& __iob, 2033 ios_base::iostate& __err, tm* __tm) const; 2034 virtual iter_type do_get_monthname(iter_type __b, iter_type __e, ios_base& __iob, 2035 ios_base::iostate& __err, tm* __tm) const; 2036 virtual iter_type do_get_year(iter_type __b, iter_type __e, ios_base& __iob, 2037 ios_base::iostate& __err, tm* __tm) const; 2038 virtual iter_type do_get(iter_type __b, iter_type __e, ios_base& __iob, 2039 ios_base::iostate& __err, tm* __tm, 2040 char __fmt, char __mod) const; 2041private: 2042 void __get_white_space(iter_type& __b, iter_type __e, 2043 ios_base::iostate& __err, const ctype<char_type>& __ct) const; 2044 void __get_percent(iter_type& __b, iter_type __e, ios_base::iostate& __err, 2045 const ctype<char_type>& __ct) const; 2046 2047 void __get_weekdayname(int& __m, 2048 iter_type& __b, iter_type __e, 2049 ios_base::iostate& __err, 2050 const ctype<char_type>& __ct) const; 2051 void __get_monthname(int& __m, 2052 iter_type& __b, iter_type __e, 2053 ios_base::iostate& __err, 2054 const ctype<char_type>& __ct) const; 2055 void __get_day(int& __d, 2056 iter_type& __b, iter_type __e, 2057 ios_base::iostate& __err, 2058 const ctype<char_type>& __ct) const; 2059 void __get_month(int& __m, 2060 iter_type& __b, iter_type __e, 2061 ios_base::iostate& __err, 2062 const ctype<char_type>& __ct) const; 2063 void __get_year(int& __y, 2064 iter_type& __b, iter_type __e, 2065 ios_base::iostate& __err, 2066 const ctype<char_type>& __ct) const; 2067 void __get_year4(int& __y, 2068 iter_type& __b, iter_type __e, 2069 ios_base::iostate& __err, 2070 const ctype<char_type>& __ct) const; 2071 void __get_hour(int& __d, 2072 iter_type& __b, iter_type __e, 2073 ios_base::iostate& __err, 2074 const ctype<char_type>& __ct) const; 2075 void __get_12_hour(int& __h, 2076 iter_type& __b, iter_type __e, 2077 ios_base::iostate& __err, 2078 const ctype<char_type>& __ct) const; 2079 void __get_am_pm(int& __h, 2080 iter_type& __b, iter_type __e, 2081 ios_base::iostate& __err, 2082 const ctype<char_type>& __ct) const; 2083 void __get_minute(int& __m, 2084 iter_type& __b, iter_type __e, 2085 ios_base::iostate& __err, 2086 const ctype<char_type>& __ct) const; 2087 void __get_second(int& __s, 2088 iter_type& __b, iter_type __e, 2089 ios_base::iostate& __err, 2090 const ctype<char_type>& __ct) const; 2091 void __get_weekday(int& __w, 2092 iter_type& __b, iter_type __e, 2093 ios_base::iostate& __err, 2094 const ctype<char_type>& __ct) const; 2095 void __get_day_year_num(int& __w, 2096 iter_type& __b, iter_type __e, 2097 ios_base::iostate& __err, 2098 const ctype<char_type>& __ct) const; 2099}; 2100 2101template <class _CharT, class _InputIterator> 2102locale::id 2103time_get<_CharT, _InputIterator>::id; 2104 2105// time_get primatives 2106 2107template <class _CharT, class _InputIterator> 2108void 2109time_get<_CharT, _InputIterator>::__get_weekdayname(int& __w, 2110 iter_type& __b, iter_type __e, 2111 ios_base::iostate& __err, 2112 const ctype<char_type>& __ct) const 2113{ 2114 // Note: ignoring case comes from the POSIX strptime spec 2115 const string_type* __wk = this->__weeks(); 2116 ptrdiff_t __i = __scan_keyword(__b, __e, __wk, __wk+14, __ct, __err, false) - __wk; 2117 if (__i < 14) 2118 __w = __i % 7; 2119} 2120 2121template <class _CharT, class _InputIterator> 2122void 2123time_get<_CharT, _InputIterator>::__get_monthname(int& __m, 2124 iter_type& __b, iter_type __e, 2125 ios_base::iostate& __err, 2126 const ctype<char_type>& __ct) const 2127{ 2128 // Note: ignoring case comes from the POSIX strptime spec 2129 const string_type* __month = this->__months(); 2130 ptrdiff_t __i = __scan_keyword(__b, __e, __month, __month+24, __ct, __err, false) - __month; 2131 if (__i < 24) 2132 __m = __i % 12; 2133} 2134 2135template <class _CharT, class _InputIterator> 2136void 2137time_get<_CharT, _InputIterator>::__get_day(int& __d, 2138 iter_type& __b, iter_type __e, 2139 ios_base::iostate& __err, 2140 const ctype<char_type>& __ct) const 2141{ 2142 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2143 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 31) 2144 __d = __t; 2145 else 2146 __err |= ios_base::failbit; 2147} 2148 2149template <class _CharT, class _InputIterator> 2150void 2151time_get<_CharT, _InputIterator>::__get_month(int& __m, 2152 iter_type& __b, iter_type __e, 2153 ios_base::iostate& __err, 2154 const ctype<char_type>& __ct) const 2155{ 2156 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2) - 1; 2157 if (!(__err & ios_base::failbit) && __t <= 11) 2158 __m = __t; 2159 else 2160 __err |= ios_base::failbit; 2161} 2162 2163template <class _CharT, class _InputIterator> 2164void 2165time_get<_CharT, _InputIterator>::__get_year(int& __y, 2166 iter_type& __b, iter_type __e, 2167 ios_base::iostate& __err, 2168 const ctype<char_type>& __ct) const 2169{ 2170 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4); 2171 if (!(__err & ios_base::failbit)) 2172 { 2173 if (__t < 69) 2174 __t += 2000; 2175 else if (69 <= __t && __t <= 99) 2176 __t += 1900; 2177 __y = __t - 1900; 2178 } 2179} 2180 2181template <class _CharT, class _InputIterator> 2182void 2183time_get<_CharT, _InputIterator>::__get_year4(int& __y, 2184 iter_type& __b, iter_type __e, 2185 ios_base::iostate& __err, 2186 const ctype<char_type>& __ct) const 2187{ 2188 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 4); 2189 if (!(__err & ios_base::failbit)) 2190 __y = __t - 1900; 2191} 2192 2193template <class _CharT, class _InputIterator> 2194void 2195time_get<_CharT, _InputIterator>::__get_hour(int& __h, 2196 iter_type& __b, iter_type __e, 2197 ios_base::iostate& __err, 2198 const ctype<char_type>& __ct) const 2199{ 2200 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2201 if (!(__err & ios_base::failbit) && __t <= 23) 2202 __h = __t; 2203 else 2204 __err |= ios_base::failbit; 2205} 2206 2207template <class _CharT, class _InputIterator> 2208void 2209time_get<_CharT, _InputIterator>::__get_12_hour(int& __h, 2210 iter_type& __b, iter_type __e, 2211 ios_base::iostate& __err, 2212 const ctype<char_type>& __ct) const 2213{ 2214 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2215 if (!(__err & ios_base::failbit) && 1 <= __t && __t <= 12) 2216 __h = __t; 2217 else 2218 __err |= ios_base::failbit; 2219} 2220 2221template <class _CharT, class _InputIterator> 2222void 2223time_get<_CharT, _InputIterator>::__get_minute(int& __m, 2224 iter_type& __b, iter_type __e, 2225 ios_base::iostate& __err, 2226 const ctype<char_type>& __ct) const 2227{ 2228 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2229 if (!(__err & ios_base::failbit) && __t <= 59) 2230 __m = __t; 2231 else 2232 __err |= ios_base::failbit; 2233} 2234 2235template <class _CharT, class _InputIterator> 2236void 2237time_get<_CharT, _InputIterator>::__get_second(int& __s, 2238 iter_type& __b, iter_type __e, 2239 ios_base::iostate& __err, 2240 const ctype<char_type>& __ct) const 2241{ 2242 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 2); 2243 if (!(__err & ios_base::failbit) && __t <= 60) 2244 __s = __t; 2245 else 2246 __err |= ios_base::failbit; 2247} 2248 2249template <class _CharT, class _InputIterator> 2250void 2251time_get<_CharT, _InputIterator>::__get_weekday(int& __w, 2252 iter_type& __b, iter_type __e, 2253 ios_base::iostate& __err, 2254 const ctype<char_type>& __ct) const 2255{ 2256 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 1); 2257 if (!(__err & ios_base::failbit) && __t <= 6) 2258 __w = __t; 2259 else 2260 __err |= ios_base::failbit; 2261} 2262 2263template <class _CharT, class _InputIterator> 2264void 2265time_get<_CharT, _InputIterator>::__get_day_year_num(int& __d, 2266 iter_type& __b, iter_type __e, 2267 ios_base::iostate& __err, 2268 const ctype<char_type>& __ct) const 2269{ 2270 int __t = __get_up_to_n_digits(__b, __e, __err, __ct, 3); 2271 if (!(__err & ios_base::failbit) && __t <= 365) 2272 __d = __t; 2273 else 2274 __err |= ios_base::failbit; 2275} 2276 2277template <class _CharT, class _InputIterator> 2278void 2279time_get<_CharT, _InputIterator>::__get_white_space(iter_type& __b, iter_type __e, 2280 ios_base::iostate& __err, 2281 const ctype<char_type>& __ct) const 2282{ 2283 for (; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) 2284 ; 2285 if (__b == __e) 2286 __err |= ios_base::eofbit; 2287} 2288 2289template <class _CharT, class _InputIterator> 2290void 2291time_get<_CharT, _InputIterator>::__get_am_pm(int& __h, 2292 iter_type& __b, iter_type __e, 2293 ios_base::iostate& __err, 2294 const ctype<char_type>& __ct) const 2295{ 2296 const string_type* __ap = this->__am_pm(); 2297 if (__ap[0].size() + __ap[1].size() == 0) 2298 { 2299 __err |= ios_base::failbit; 2300 return; 2301 } 2302 ptrdiff_t __i = __scan_keyword(__b, __e, __ap, __ap+2, __ct, __err, false) - __ap; 2303 if (__i == 0 && __h == 12) 2304 __h = 0; 2305 else if (__i == 1 && __h < 12) 2306 __h += 12; 2307} 2308 2309template <class _CharT, class _InputIterator> 2310void 2311time_get<_CharT, _InputIterator>::__get_percent(iter_type& __b, iter_type __e, 2312 ios_base::iostate& __err, 2313 const ctype<char_type>& __ct) const 2314{ 2315 if (__b == __e) 2316 { 2317 __err |= ios_base::eofbit | ios_base::failbit; 2318 return; 2319 } 2320 if (__ct.narrow(*__b, 0) != '%') 2321 __err |= ios_base::failbit; 2322 else if(++__b == __e) 2323 __err |= ios_base::eofbit; 2324} 2325 2326// time_get end primatives 2327 2328template <class _CharT, class _InputIterator> 2329_InputIterator 2330time_get<_CharT, _InputIterator>::get(iter_type __b, iter_type __e, 2331 ios_base& __iob, 2332 ios_base::iostate& __err, tm* __tm, 2333 const char_type* __fmtb, const char_type* __fmte) const 2334{ 2335 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2336 __err = ios_base::goodbit; 2337 while (__fmtb != __fmte && __err == ios_base::goodbit) 2338 { 2339 if (__b == __e) 2340 { 2341 __err = ios_base::failbit; 2342 break; 2343 } 2344 if (__ct.narrow(*__fmtb, 0) == '%') 2345 { 2346 if (++__fmtb == __fmte) 2347 { 2348 __err = ios_base::failbit; 2349 break; 2350 } 2351 char __cmd = __ct.narrow(*__fmtb, 0); 2352 char __opt = '\0'; 2353 if (__cmd == 'E' || __cmd == '0') 2354 { 2355 if (++__fmtb == __fmte) 2356 { 2357 __err = ios_base::failbit; 2358 break; 2359 } 2360 __opt = __cmd; 2361 __cmd = __ct.narrow(*__fmtb, 0); 2362 } 2363 __b = do_get(__b, __e, __iob, __err, __tm, __cmd, __opt); 2364 ++__fmtb; 2365 } 2366 else if (__ct.is(ctype_base::space, *__fmtb)) 2367 { 2368 for (++__fmtb; __fmtb != __fmte && __ct.is(ctype_base::space, *__fmtb); ++__fmtb) 2369 ; 2370 for ( ; __b != __e && __ct.is(ctype_base::space, *__b); ++__b) 2371 ; 2372 } 2373 else if (__ct.toupper(*__b) == __ct.toupper(*__fmtb)) 2374 { 2375 ++__b; 2376 ++__fmtb; 2377 } 2378 else 2379 __err = ios_base::failbit; 2380 } 2381 if (__b == __e) 2382 __err |= ios_base::eofbit; 2383 return __b; 2384} 2385 2386template <class _CharT, class _InputIterator> 2387typename time_get<_CharT, _InputIterator>::dateorder 2388time_get<_CharT, _InputIterator>::do_date_order() const 2389{ 2390 return mdy; 2391} 2392 2393template <class _CharT, class _InputIterator> 2394_InputIterator 2395time_get<_CharT, _InputIterator>::do_get_time(iter_type __b, iter_type __e, 2396 ios_base& __iob, 2397 ios_base::iostate& __err, 2398 tm* __tm) const 2399{ 2400 const char_type __fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; 2401 return get(__b, __e, __iob, __err, __tm, __fmt, __fmt + sizeof(__fmt)/sizeof(__fmt[0])); 2402} 2403 2404template <class _CharT, class _InputIterator> 2405_InputIterator 2406time_get<_CharT, _InputIterator>::do_get_date(iter_type __b, iter_type __e, 2407 ios_base& __iob, 2408 ios_base::iostate& __err, 2409 tm* __tm) const 2410{ 2411 const string_type& __fmt = this->__x(); 2412 return get(__b, __e, __iob, __err, __tm, __fmt.data(), __fmt.data() + __fmt.size()); 2413} 2414 2415template <class _CharT, class _InputIterator> 2416_InputIterator 2417time_get<_CharT, _InputIterator>::do_get_weekday(iter_type __b, iter_type __e, 2418 ios_base& __iob, 2419 ios_base::iostate& __err, 2420 tm* __tm) const 2421{ 2422 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2423 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); 2424 return __b; 2425} 2426 2427template <class _CharT, class _InputIterator> 2428_InputIterator 2429time_get<_CharT, _InputIterator>::do_get_monthname(iter_type __b, iter_type __e, 2430 ios_base& __iob, 2431 ios_base::iostate& __err, 2432 tm* __tm) const 2433{ 2434 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2435 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); 2436 return __b; 2437} 2438 2439template <class _CharT, class _InputIterator> 2440_InputIterator 2441time_get<_CharT, _InputIterator>::do_get_year(iter_type __b, iter_type __e, 2442 ios_base& __iob, 2443 ios_base::iostate& __err, 2444 tm* __tm) const 2445{ 2446 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2447 __get_year(__tm->tm_year, __b, __e, __err, __ct); 2448 return __b; 2449} 2450 2451template <class _CharT, class _InputIterator> 2452_InputIterator 2453time_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 2454 ios_base& __iob, 2455 ios_base::iostate& __err, tm* __tm, 2456 char __fmt, char) const 2457{ 2458 __err = ios_base::goodbit; 2459 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2460 switch (__fmt) 2461 { 2462 case 'a': 2463 case 'A': 2464 __get_weekdayname(__tm->tm_wday, __b, __e, __err, __ct); 2465 break; 2466 case 'b': 2467 case 'B': 2468 case 'h': 2469 __get_monthname(__tm->tm_mon, __b, __e, __err, __ct); 2470 break; 2471 case 'c': 2472 { 2473 const string_type& __fm = this->__c(); 2474 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); 2475 } 2476 break; 2477 case 'd': 2478 case 'e': 2479 __get_day(__tm->tm_mday, __b, __e, __err, __ct); 2480 break; 2481 case 'D': 2482 { 2483 const char_type __fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'}; 2484 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2485 } 2486 break; 2487 case 'F': 2488 { 2489 const char_type __fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'}; 2490 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2491 } 2492 break; 2493 case 'H': 2494 __get_hour(__tm->tm_hour, __b, __e, __err, __ct); 2495 break; 2496 case 'I': 2497 __get_12_hour(__tm->tm_hour, __b, __e, __err, __ct); 2498 break; 2499 case 'j': 2500 __get_day_year_num(__tm->tm_yday, __b, __e, __err, __ct); 2501 break; 2502 case 'm': 2503 __get_month(__tm->tm_mon, __b, __e, __err, __ct); 2504 break; 2505 case 'M': 2506 __get_minute(__tm->tm_min, __b, __e, __err, __ct); 2507 break; 2508 case 'n': 2509 case 't': 2510 __get_white_space(__b, __e, __err, __ct); 2511 break; 2512 case 'p': 2513 __get_am_pm(__tm->tm_hour, __b, __e, __err, __ct); 2514 break; 2515 case 'r': 2516 { 2517 const char_type __fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'}; 2518 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2519 } 2520 break; 2521 case 'R': 2522 { 2523 const char_type __fm[] = {'%', 'H', ':', '%', 'M'}; 2524 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2525 } 2526 break; 2527 case 'S': 2528 __get_second(__tm->tm_sec, __b, __e, __err, __ct); 2529 break; 2530 case 'T': 2531 { 2532 const char_type __fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; 2533 __b = get(__b, __e, __iob, __err, __tm, __fm, __fm + sizeof(__fm)/sizeof(__fm[0])); 2534 } 2535 break; 2536 case 'w': 2537 __get_weekday(__tm->tm_wday, __b, __e, __err, __ct); 2538 break; 2539 case 'x': 2540 return do_get_date(__b, __e, __iob, __err, __tm); 2541 case 'X': 2542 { 2543 const string_type& __fm = this->__X(); 2544 __b = get(__b, __e, __iob, __err, __tm, __fm.data(), __fm.data() + __fm.size()); 2545 } 2546 break; 2547 case 'y': 2548 __get_year(__tm->tm_year, __b, __e, __err, __ct); 2549 break; 2550 case 'Y': 2551 __get_year4(__tm->tm_year, __b, __e, __err, __ct); 2552 break; 2553 case '%': 2554 __get_percent(__b, __e, __err, __ct); 2555 break; 2556 default: 2557 __err |= ios_base::failbit; 2558 } 2559 return __b; 2560} 2561 2562extern template class time_get<char>; 2563extern template class time_get<wchar_t>; 2564 2565class __time_get 2566{ 2567protected: 2568 locale_t __loc_; 2569 2570 __time_get(const char* __nm); 2571 __time_get(const string& __nm); 2572 ~__time_get(); 2573}; 2574 2575template <class _CharT> 2576class __time_get_storage 2577 : public __time_get 2578{ 2579protected: 2580 typedef basic_string<_CharT> string_type; 2581 2582 string_type __weeks_[14]; 2583 string_type __months_[24]; 2584 string_type __am_pm_[2]; 2585 string_type __c_; 2586 string_type __r_; 2587 string_type __x_; 2588 string_type __X_; 2589 2590 explicit __time_get_storage(const char* __nm); 2591 explicit __time_get_storage(const string& __nm); 2592 2593 _LIBCPP_ALWAYS_INLINE ~__time_get_storage() {} 2594 2595 time_base::dateorder __do_date_order() const; 2596 2597private: 2598 void init(const ctype<_CharT>&); 2599 string_type __analyze(char __fmt, const ctype<_CharT>&); 2600}; 2601 2602template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 2603class _LIBCPP_VISIBLE time_get_byname 2604 : public time_get<_CharT, _InputIterator>, 2605 private __time_get_storage<_CharT> 2606{ 2607public: 2608 typedef time_base::dateorder dateorder; 2609 typedef _InputIterator iter_type; 2610 typedef _CharT char_type; 2611 typedef basic_string<char_type> string_type; 2612 2613 _LIBCPP_INLINE_VISIBILITY 2614 explicit time_get_byname(const char* __nm, size_t __refs = 0) 2615 : time_get<_CharT, _InputIterator>(__refs), 2616 __time_get_storage<_CharT>(__nm) {} 2617 _LIBCPP_INLINE_VISIBILITY 2618 explicit time_get_byname(const string& __nm, size_t __refs = 0) 2619 : time_get<_CharT, _InputIterator>(__refs), 2620 __time_get_storage<_CharT>(__nm) {} 2621 2622protected: 2623 _LIBCPP_INLINE_VISIBILITY 2624 ~time_get_byname() {} 2625 2626 _LIBCPP_INLINE_VISIBILITY 2627 virtual dateorder do_date_order() const {return this->__do_date_order();} 2628private: 2629 _LIBCPP_INLINE_VISIBILITY 2630 virtual const string_type* __weeks() const {return this->__weeks_;} 2631 _LIBCPP_INLINE_VISIBILITY 2632 virtual const string_type* __months() const {return this->__months_;} 2633 _LIBCPP_INLINE_VISIBILITY 2634 virtual const string_type* __am_pm() const {return this->__am_pm_;} 2635 _LIBCPP_INLINE_VISIBILITY 2636 virtual const string_type& __c() const {return this->__c_;} 2637 _LIBCPP_INLINE_VISIBILITY 2638 virtual const string_type& __r() const {return this->__r_;} 2639 _LIBCPP_INLINE_VISIBILITY 2640 virtual const string_type& __x() const {return this->__x_;} 2641 _LIBCPP_INLINE_VISIBILITY 2642 virtual const string_type& __X() const {return this->__X_;} 2643}; 2644 2645extern template class time_get_byname<char>; 2646extern template class time_get_byname<wchar_t>; 2647 2648class __time_put 2649{ 2650 locale_t __loc_; 2651protected: 2652 _LIBCPP_ALWAYS_INLINE __time_put() : __loc_(_LIBCPP_GET_C_LOCALE) {} 2653 __time_put(const char* __nm); 2654 __time_put(const string& __nm); 2655 ~__time_put(); 2656 void __do_put(char* __nb, char*& __ne, const tm* __tm, 2657 char __fmt, char __mod) const; 2658 void __do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, 2659 char __fmt, char __mod) const; 2660}; 2661 2662template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 2663class _LIBCPP_VISIBLE time_put 2664 : public locale::facet, 2665 private __time_put 2666{ 2667public: 2668 typedef _CharT char_type; 2669 typedef _OutputIterator iter_type; 2670 2671 _LIBCPP_ALWAYS_INLINE 2672 explicit time_put(size_t __refs = 0) 2673 : locale::facet(__refs) {} 2674 2675 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, const tm* __tm, 2676 const char_type* __pb, const char_type* __pe) const; 2677 2678 _LIBCPP_ALWAYS_INLINE 2679 iter_type put(iter_type __s, ios_base& __iob, char_type __fl, 2680 const tm* __tm, char __fmt, char __mod = 0) const 2681 { 2682 return do_put(__s, __iob, __fl, __tm, __fmt, __mod); 2683 } 2684 2685 static locale::id id; 2686 2687protected: 2688 _LIBCPP_ALWAYS_INLINE 2689 ~time_put() {} 2690 virtual iter_type do_put(iter_type __s, ios_base&, char_type, const tm* __tm, 2691 char __fmt, char __mod) const; 2692 2693 _LIBCPP_ALWAYS_INLINE 2694 explicit time_put(const char* __nm, size_t __refs) 2695 : locale::facet(__refs), 2696 __time_put(__nm) {} 2697 _LIBCPP_ALWAYS_INLINE 2698 explicit time_put(const string& __nm, size_t __refs) 2699 : locale::facet(__refs), 2700 __time_put(__nm) {} 2701}; 2702 2703template <class _CharT, class _OutputIterator> 2704locale::id 2705time_put<_CharT, _OutputIterator>::id; 2706 2707template <class _CharT, class _OutputIterator> 2708_OutputIterator 2709time_put<_CharT, _OutputIterator>::put(iter_type __s, ios_base& __iob, 2710 char_type __fl, const tm* __tm, 2711 const char_type* __pb, 2712 const char_type* __pe) const 2713{ 2714 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__iob.getloc()); 2715 for (; __pb != __pe; ++__pb) 2716 { 2717 if (__ct.narrow(*__pb, 0) == '%') 2718 { 2719 if (++__pb == __pe) 2720 { 2721 *__s++ = __pb[-1]; 2722 break; 2723 } 2724 char __mod = 0; 2725 char __fmt = __ct.narrow(*__pb, 0); 2726 if (__fmt == 'E' || __fmt == 'O') 2727 { 2728 if (++__pb == __pe) 2729 { 2730 *__s++ = __pb[-2]; 2731 *__s++ = __pb[-1]; 2732 break; 2733 } 2734 __mod = __fmt; 2735 __fmt = __ct.narrow(*__pb, 0); 2736 } 2737 __s = do_put(__s, __iob, __fl, __tm, __fmt, __mod); 2738 } 2739 else 2740 *__s++ = *__pb; 2741 } 2742 return __s; 2743} 2744 2745template <class _CharT, class _OutputIterator> 2746_OutputIterator 2747time_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base&, 2748 char_type, const tm* __tm, 2749 char __fmt, char __mod) const 2750{ 2751 char_type __nar[100]; 2752 char_type* __nb = __nar; 2753 char_type* __ne = __nb + 100; 2754 __do_put(__nb, __ne, __tm, __fmt, __mod); 2755 return _VSTD::copy(__nb, __ne, __s); 2756} 2757 2758extern template class time_put<char>; 2759extern template class time_put<wchar_t>; 2760 2761template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 2762class _LIBCPP_VISIBLE time_put_byname 2763 : public time_put<_CharT, _OutputIterator> 2764{ 2765public: 2766 _LIBCPP_ALWAYS_INLINE 2767 explicit time_put_byname(const char* __nm, size_t __refs = 0) 2768 : time_put<_CharT, _OutputIterator>(__nm, __refs) {} 2769 2770 _LIBCPP_ALWAYS_INLINE 2771 explicit time_put_byname(const string& __nm, size_t __refs = 0) 2772 : time_put<_CharT, _OutputIterator>(__nm, __refs) {} 2773 2774protected: 2775 _LIBCPP_ALWAYS_INLINE 2776 ~time_put_byname() {} 2777}; 2778 2779extern template class time_put_byname<char>; 2780extern template class time_put_byname<wchar_t>; 2781 2782// money_base 2783 2784class _LIBCPP_VISIBLE money_base 2785{ 2786public: 2787 enum part {none, space, symbol, sign, value}; 2788 struct pattern {char field[4];}; 2789 2790 _LIBCPP_ALWAYS_INLINE money_base() {} 2791}; 2792 2793// moneypunct 2794 2795template <class _CharT, bool _International = false> 2796class _LIBCPP_VISIBLE moneypunct 2797 : public locale::facet, 2798 public money_base 2799{ 2800public: 2801 typedef _CharT char_type; 2802 typedef basic_string<char_type> string_type; 2803 2804 _LIBCPP_ALWAYS_INLINE 2805 explicit moneypunct(size_t __refs = 0) 2806 : locale::facet(__refs) {} 2807 2808 _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();} 2809 _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();} 2810 _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();} 2811 _LIBCPP_ALWAYS_INLINE string_type curr_symbol() const {return do_curr_symbol();} 2812 _LIBCPP_ALWAYS_INLINE string_type positive_sign() const {return do_positive_sign();} 2813 _LIBCPP_ALWAYS_INLINE string_type negative_sign() const {return do_negative_sign();} 2814 _LIBCPP_ALWAYS_INLINE int frac_digits() const {return do_frac_digits();} 2815 _LIBCPP_ALWAYS_INLINE pattern pos_format() const {return do_pos_format();} 2816 _LIBCPP_ALWAYS_INLINE pattern neg_format() const {return do_neg_format();} 2817 2818 static locale::id id; 2819 static const bool intl = _International; 2820 2821protected: 2822 _LIBCPP_ALWAYS_INLINE 2823 ~moneypunct() {} 2824 2825 virtual char_type do_decimal_point() const {return numeric_limits<char_type>::max();} 2826 virtual char_type do_thousands_sep() const {return numeric_limits<char_type>::max();} 2827 virtual string do_grouping() const {return string();} 2828 virtual string_type do_curr_symbol() const {return string_type();} 2829 virtual string_type do_positive_sign() const {return string_type();} 2830 virtual string_type do_negative_sign() const {return string_type(1, '-');} 2831 virtual int do_frac_digits() const {return 0;} 2832 virtual pattern do_pos_format() const 2833 {pattern __p = {symbol, sign, none, value}; return __p;} 2834 virtual pattern do_neg_format() const 2835 {pattern __p = {symbol, sign, none, value}; return __p;} 2836}; 2837 2838template <class _CharT, bool _International> 2839locale::id 2840moneypunct<_CharT, _International>::id; 2841 2842extern template class moneypunct<char, false>; 2843extern template class moneypunct<char, true>; 2844extern template class moneypunct<wchar_t, false>; 2845extern template class moneypunct<wchar_t, true>; 2846 2847// moneypunct_byname 2848 2849template <class _CharT, bool _International = false> 2850class _LIBCPP_VISIBLE moneypunct_byname 2851 : public moneypunct<_CharT, _International> 2852{ 2853public: 2854 typedef money_base::pattern pattern; 2855 typedef _CharT char_type; 2856 typedef basic_string<char_type> string_type; 2857 2858 _LIBCPP_ALWAYS_INLINE 2859 explicit moneypunct_byname(const char* __nm, size_t __refs = 0) 2860 : moneypunct<_CharT, _International>(__refs) {init(__nm);} 2861 2862 _LIBCPP_ALWAYS_INLINE 2863 explicit moneypunct_byname(const string& __nm, size_t __refs = 0) 2864 : moneypunct<_CharT, _International>(__refs) {init(__nm.c_str());} 2865 2866protected: 2867 _LIBCPP_ALWAYS_INLINE 2868 ~moneypunct_byname() {} 2869 2870 virtual char_type do_decimal_point() const {return __decimal_point_;} 2871 virtual char_type do_thousands_sep() const {return __thousands_sep_;} 2872 virtual string do_grouping() const {return __grouping_;} 2873 virtual string_type do_curr_symbol() const {return __curr_symbol_;} 2874 virtual string_type do_positive_sign() const {return __positive_sign_;} 2875 virtual string_type do_negative_sign() const {return __negative_sign_;} 2876 virtual int do_frac_digits() const {return __frac_digits_;} 2877 virtual pattern do_pos_format() const {return __pos_format_;} 2878 virtual pattern do_neg_format() const {return __neg_format_;} 2879 2880private: 2881 char_type __decimal_point_; 2882 char_type __thousands_sep_; 2883 string __grouping_; 2884 string_type __curr_symbol_; 2885 string_type __positive_sign_; 2886 string_type __negative_sign_; 2887 int __frac_digits_; 2888 pattern __pos_format_; 2889 pattern __neg_format_; 2890 2891 void init(const char*); 2892}; 2893 2894template<> void moneypunct_byname<char, false>::init(const char*); 2895template<> void moneypunct_byname<char, true>::init(const char*); 2896template<> void moneypunct_byname<wchar_t, false>::init(const char*); 2897template<> void moneypunct_byname<wchar_t, true>::init(const char*); 2898 2899extern template class moneypunct_byname<char, false>; 2900extern template class moneypunct_byname<char, true>; 2901extern template class moneypunct_byname<wchar_t, false>; 2902extern template class moneypunct_byname<wchar_t, true>; 2903 2904// money_get 2905 2906template <class _CharT> 2907class __money_get 2908{ 2909protected: 2910 typedef _CharT char_type; 2911 typedef basic_string<char_type> string_type; 2912 2913 _LIBCPP_ALWAYS_INLINE __money_get() {} 2914 2915 static void __gather_info(bool __intl, const locale& __loc, 2916 money_base::pattern& __pat, char_type& __dp, 2917 char_type& __ts, string& __grp, 2918 string_type& __sym, string_type& __psn, 2919 string_type& __nsn, int& __fd); 2920}; 2921 2922template <class _CharT> 2923void 2924__money_get<_CharT>::__gather_info(bool __intl, const locale& __loc, 2925 money_base::pattern& __pat, char_type& __dp, 2926 char_type& __ts, string& __grp, 2927 string_type& __sym, string_type& __psn, 2928 string_type& __nsn, int& __fd) 2929{ 2930 if (__intl) 2931 { 2932 const moneypunct<char_type, true>& __mp = 2933 use_facet<moneypunct<char_type, true> >(__loc); 2934 __pat = __mp.neg_format(); 2935 __nsn = __mp.negative_sign(); 2936 __psn = __mp.positive_sign(); 2937 __dp = __mp.decimal_point(); 2938 __ts = __mp.thousands_sep(); 2939 __grp = __mp.grouping(); 2940 __sym = __mp.curr_symbol(); 2941 __fd = __mp.frac_digits(); 2942 } 2943 else 2944 { 2945 const moneypunct<char_type, false>& __mp = 2946 use_facet<moneypunct<char_type, false> >(__loc); 2947 __pat = __mp.neg_format(); 2948 __nsn = __mp.negative_sign(); 2949 __psn = __mp.positive_sign(); 2950 __dp = __mp.decimal_point(); 2951 __ts = __mp.thousands_sep(); 2952 __grp = __mp.grouping(); 2953 __sym = __mp.curr_symbol(); 2954 __fd = __mp.frac_digits(); 2955 } 2956} 2957 2958extern template class __money_get<char>; 2959extern template class __money_get<wchar_t>; 2960 2961template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> > 2962class _LIBCPP_VISIBLE money_get 2963 : public locale::facet, 2964 private __money_get<_CharT> 2965{ 2966public: 2967 typedef _CharT char_type; 2968 typedef _InputIterator iter_type; 2969 typedef basic_string<char_type> string_type; 2970 2971 _LIBCPP_ALWAYS_INLINE 2972 explicit money_get(size_t __refs = 0) 2973 : locale::facet(__refs) {} 2974 2975 _LIBCPP_ALWAYS_INLINE 2976 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, 2977 ios_base::iostate& __err, long double& __v) const 2978 { 2979 return do_get(__b, __e, __intl, __iob, __err, __v); 2980 } 2981 2982 _LIBCPP_ALWAYS_INLINE 2983 iter_type get(iter_type __b, iter_type __e, bool __intl, ios_base& __iob, 2984 ios_base::iostate& __err, string_type& __v) const 2985 { 2986 return do_get(__b, __e, __intl, __iob, __err, __v); 2987 } 2988 2989 static locale::id id; 2990 2991protected: 2992 2993 _LIBCPP_ALWAYS_INLINE 2994 ~money_get() {} 2995 2996 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl, 2997 ios_base& __iob, ios_base::iostate& __err, 2998 long double& __v) const; 2999 virtual iter_type do_get(iter_type __b, iter_type __e, bool __intl, 3000 ios_base& __iob, ios_base::iostate& __err, 3001 string_type& __v) const; 3002 3003private: 3004 static bool __do_get(iter_type& __b, iter_type __e, 3005 bool __intl, const locale& __loc, 3006 ios_base::fmtflags __flags, ios_base::iostate& __err, 3007 bool& __neg, const ctype<char_type>& __ct, 3008 unique_ptr<char_type, void(*)(void*)>& __wb, 3009 char_type*& __wn, char_type* __we); 3010}; 3011 3012template <class _CharT, class _InputIterator> 3013locale::id 3014money_get<_CharT, _InputIterator>::id; 3015 3016void __do_nothing(void*); 3017 3018template <class _Tp> 3019_LIBCPP_HIDDEN 3020void 3021__double_or_nothing(unique_ptr<_Tp, void(*)(void*)>& __b, _Tp*& __n, _Tp*& __e) 3022{ 3023 bool __owns = __b.get_deleter() != __do_nothing; 3024 size_t __cur_cap = static_cast<size_t>(__e-__b.get()) * sizeof(_Tp); 3025 size_t __new_cap = __cur_cap < numeric_limits<size_t>::max() / 2 ? 3026 2 * __cur_cap : numeric_limits<size_t>::max(); 3027 size_t __n_off = static_cast<size_t>(__n - __b.get()); 3028 _Tp* __t = (_Tp*)realloc(__owns ? __b.get() : 0, __new_cap); 3029 if (__t == 0) 3030 __throw_bad_alloc(); 3031 if (__owns) 3032 __b.release(); 3033 __b = unique_ptr<_Tp, void(*)(void*)>(__t, free); 3034 __new_cap /= sizeof(_Tp); 3035 __n = __b.get() + __n_off; 3036 __e = __b.get() + __new_cap; 3037} 3038 3039// true == success 3040template <class _CharT, class _InputIterator> 3041bool 3042money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e, 3043 bool __intl, const locale& __loc, 3044 ios_base::fmtflags __flags, 3045 ios_base::iostate& __err, 3046 bool& __neg, 3047 const ctype<char_type>& __ct, 3048 unique_ptr<char_type, void(*)(void*)>& __wb, 3049 char_type*& __wn, char_type* __we) 3050{ 3051 const unsigned __bz = 100; 3052 unsigned __gbuf[__bz]; 3053 unique_ptr<unsigned, void(*)(void*)> __gb(__gbuf, __do_nothing); 3054 unsigned* __gn = __gb.get(); 3055 unsigned* __ge = __gn + __bz; 3056 money_base::pattern __pat; 3057 char_type __dp; 3058 char_type __ts; 3059 string __grp; 3060 string_type __sym; 3061 string_type __psn; 3062 string_type __nsn; 3063 // Capture the spaces read into money_base::{space,none} so they 3064 // can be compared to initial spaces in __sym. 3065 string_type __spaces; 3066 int __fd; 3067 __money_get<_CharT>::__gather_info(__intl, __loc, __pat, __dp, __ts, __grp, 3068 __sym, __psn, __nsn, __fd); 3069 const string_type* __trailing_sign = 0; 3070 __wn = __wb.get(); 3071 for (unsigned __p = 0; __p < 4 && __b != __e; ++__p) 3072 { 3073 switch (__pat.field[__p]) 3074 { 3075 case money_base::space: 3076 if (__p != 3) 3077 { 3078 if (__ct.is(ctype_base::space, *__b)) 3079 __spaces.push_back(*__b++); 3080 else 3081 { 3082 __err |= ios_base::failbit; 3083 return false; 3084 } 3085 } 3086 // drop through 3087 case money_base::none: 3088 if (__p != 3) 3089 { 3090 while (__b != __e && __ct.is(ctype_base::space, *__b)) 3091 __spaces.push_back(*__b++); 3092 } 3093 break; 3094 case money_base::sign: 3095 if (__psn.size() + __nsn.size() > 0) 3096 { 3097 if (__psn.size() == 0 || __nsn.size() == 0) 3098 { // sign is optional 3099 if (__psn.size() > 0) 3100 { // __nsn.size() == 0 3101 if (*__b == __psn[0]) 3102 { 3103 ++__b; 3104 if (__psn.size() > 1) 3105 __trailing_sign = &__psn; 3106 } 3107 else 3108 __neg = true; 3109 } 3110 else if (*__b == __nsn[0]) // __nsn.size() > 0 && __psn.size() == 0 3111 { 3112 ++__b; 3113 __neg = true; 3114 if (__nsn.size() > 1) 3115 __trailing_sign = &__nsn; 3116 } 3117 } 3118 else // sign is required 3119 { 3120 if (*__b == __psn[0]) 3121 { 3122 ++__b; 3123 if (__psn.size() > 1) 3124 __trailing_sign = &__psn; 3125 } 3126 else if (*__b == __nsn[0]) 3127 { 3128 ++__b; 3129 __neg = true; 3130 if (__nsn.size() > 1) 3131 __trailing_sign = &__nsn; 3132 } 3133 else 3134 { 3135 __err |= ios_base::failbit; 3136 return false; 3137 } 3138 } 3139 } 3140 break; 3141 case money_base::symbol: 3142 { 3143 bool __more_needed = __trailing_sign || 3144 (__p < 2) || 3145 (__p == 2 && __pat.field[3] != static_cast<char>(money_base::none)); 3146 bool __sb = __flags & ios_base::showbase; 3147 if (__sb || __more_needed) 3148 { 3149 ios_base::iostate __et = ios_base::goodbit; 3150 typename string_type::const_iterator __sym_space_end = __sym.begin(); 3151 if (__p > 0 && (__pat.field[__p - 1] == money_base::none || 3152 __pat.field[__p - 1] == money_base::space)) { 3153 // Match spaces we've already read against spaces at 3154 // the beginning of __sym. 3155 while (__sym_space_end != __sym.end() && 3156 __ct.is(ctype_base::space, *__sym_space_end)) 3157 ++__sym_space_end; 3158 const size_t __num_spaces = __sym_space_end - __sym.begin(); 3159 if (__num_spaces > __spaces.size() || 3160 !equal(__spaces.end() - __num_spaces, __spaces.end(), 3161 __sym.begin())) { 3162 // No match. Put __sym_space_end back at the 3163 // beginning of __sym, which will prevent a 3164 // match in the next loop. 3165 __sym_space_end = __sym.begin(); 3166 } 3167 } 3168 typename string_type::const_iterator __sym_curr_char = __sym_space_end; 3169 while (__sym_curr_char != __sym.end() && __b != __e && 3170 *__b == *__sym_curr_char) { 3171 ++__b; 3172 ++__sym_curr_char; 3173 } 3174 if (__sb && __sym_curr_char != __sym.end()) 3175 { 3176 __err |= ios_base::failbit; 3177 return false; 3178 } 3179 } 3180 } 3181 break; 3182 case money_base::value: 3183 { 3184 unsigned __ng = 0; 3185 for (; __b != __e; ++__b) 3186 { 3187 char_type __c = *__b; 3188 if (__ct.is(ctype_base::digit, __c)) 3189 { 3190 if (__wn == __we) 3191 __double_or_nothing(__wb, __wn, __we); 3192 *__wn++ = __c; 3193 ++__ng; 3194 } 3195 else if (__grp.size() > 0 && __ng > 0 && __c == __ts) 3196 { 3197 if (__gn == __ge) 3198 __double_or_nothing(__gb, __gn, __ge); 3199 *__gn++ = __ng; 3200 __ng = 0; 3201 } 3202 else 3203 break; 3204 } 3205 if (__gb.get() != __gn && __ng > 0) 3206 { 3207 if (__gn == __ge) 3208 __double_or_nothing(__gb, __gn, __ge); 3209 *__gn++ = __ng; 3210 } 3211 if (__fd > 0) 3212 { 3213 if (__b == __e || *__b != __dp) 3214 { 3215 __err |= ios_base::failbit; 3216 return false; 3217 } 3218 for (++__b; __fd > 0; --__fd, ++__b) 3219 { 3220 if (__b == __e || !__ct.is(ctype_base::digit, *__b)) 3221 { 3222 __err |= ios_base::failbit; 3223 return false; 3224 } 3225 if (__wn == __we) 3226 __double_or_nothing(__wb, __wn, __we); 3227 *__wn++ = *__b; 3228 } 3229 } 3230 if (__wn == __wb.get()) 3231 { 3232 __err |= ios_base::failbit; 3233 return false; 3234 } 3235 } 3236 break; 3237 } 3238 } 3239 if (__trailing_sign) 3240 { 3241 for (unsigned __i = 1; __i < __trailing_sign->size(); ++__i, ++__b) 3242 { 3243 if (__b == __e || *__b != (*__trailing_sign)[__i]) 3244 { 3245 __err |= ios_base::failbit; 3246 return false; 3247 } 3248 } 3249 } 3250 if (__gb.get() != __gn) 3251 { 3252 ios_base::iostate __et = ios_base::goodbit; 3253 __check_grouping(__grp, __gb.get(), __gn, __et); 3254 if (__et) 3255 { 3256 __err |= ios_base::failbit; 3257 return false; 3258 } 3259 } 3260 return true; 3261} 3262 3263template <class _CharT, class _InputIterator> 3264_InputIterator 3265money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 3266 bool __intl, ios_base& __iob, 3267 ios_base::iostate& __err, 3268 long double& __v) const 3269{ 3270 const int __bz = 100; 3271 char_type __wbuf[__bz]; 3272 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing); 3273 char_type* __wn; 3274 char_type* __we = __wbuf + __bz; 3275 locale __loc = __iob.getloc(); 3276 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3277 bool __neg = false; 3278 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, 3279 __wb, __wn, __we)) 3280 { 3281 const char __src[] = "0123456789"; 3282 char_type __atoms[sizeof(__src)-1]; 3283 __ct.widen(__src, __src + (sizeof(__src)-1), __atoms); 3284 char __nbuf[__bz]; 3285 char* __nc = __nbuf; 3286 unique_ptr<char, void(*)(void*)> __h(0, free); 3287 if (__wn - __wb.get() > __bz-2) 3288 { 3289 __h.reset((char*)malloc(static_cast<size_t>(__wn - __wb.get() + 2))); 3290 if (__h.get() == 0) 3291 __throw_bad_alloc(); 3292 __nc = __h.get(); 3293 } 3294 if (__neg) 3295 *__nc++ = '-'; 3296 for (const char_type* __w = __wb.get(); __w < __wn; ++__w, ++__nc) 3297 *__nc = __src[find(__atoms, __atoms+sizeof(__atoms), *__w) - __atoms]; 3298 *__nc = char(); 3299 if (sscanf(__nbuf, "%Lf", &__v) != 1) 3300 __throw_runtime_error("money_get error"); 3301 } 3302 if (__b == __e) 3303 __err |= ios_base::eofbit; 3304 return __b; 3305} 3306 3307template <class _CharT, class _InputIterator> 3308_InputIterator 3309money_get<_CharT, _InputIterator>::do_get(iter_type __b, iter_type __e, 3310 bool __intl, ios_base& __iob, 3311 ios_base::iostate& __err, 3312 string_type& __v) const 3313{ 3314 const int __bz = 100; 3315 char_type __wbuf[__bz]; 3316 unique_ptr<char_type, void(*)(void*)> __wb(__wbuf, __do_nothing); 3317 char_type* __wn; 3318 char_type* __we = __wbuf + __bz; 3319 locale __loc = __iob.getloc(); 3320 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3321 bool __neg = false; 3322 if (__do_get(__b, __e, __intl, __loc, __iob.flags(), __err, __neg, __ct, 3323 __wb, __wn, __we)) 3324 { 3325 __v.clear(); 3326 if (__neg) 3327 __v.push_back(__ct.widen('-')); 3328 char_type __z = __ct.widen('0'); 3329 char_type* __w; 3330 for (__w = __wb.get(); __w < __wn-1; ++__w) 3331 if (*__w != __z) 3332 break; 3333 __v.append(__w, __wn); 3334 } 3335 if (__b == __e) 3336 __err |= ios_base::eofbit; 3337 return __b; 3338} 3339 3340extern template class money_get<char>; 3341extern template class money_get<wchar_t>; 3342 3343// money_put 3344 3345template <class _CharT> 3346class __money_put 3347{ 3348protected: 3349 typedef _CharT char_type; 3350 typedef basic_string<char_type> string_type; 3351 3352 _LIBCPP_ALWAYS_INLINE __money_put() {} 3353 3354 static void __gather_info(bool __intl, bool __neg, const locale& __loc, 3355 money_base::pattern& __pat, char_type& __dp, 3356 char_type& __ts, string& __grp, 3357 string_type& __sym, string_type& __sn, 3358 int& __fd); 3359 static void __format(char_type* __mb, char_type*& __mi, char_type*& __me, 3360 ios_base::fmtflags __flags, 3361 const char_type* __db, const char_type* __de, 3362 const ctype<char_type>& __ct, bool __neg, 3363 const money_base::pattern& __pat, char_type __dp, 3364 char_type __ts, const string& __grp, 3365 const string_type& __sym, const string_type& __sn, 3366 int __fd); 3367}; 3368 3369template <class _CharT> 3370void 3371__money_put<_CharT>::__gather_info(bool __intl, bool __neg, const locale& __loc, 3372 money_base::pattern& __pat, char_type& __dp, 3373 char_type& __ts, string& __grp, 3374 string_type& __sym, string_type& __sn, 3375 int& __fd) 3376{ 3377 if (__intl) 3378 { 3379 const moneypunct<char_type, true>& __mp = 3380 use_facet<moneypunct<char_type, true> >(__loc); 3381 if (__neg) 3382 { 3383 __pat = __mp.neg_format(); 3384 __sn = __mp.negative_sign(); 3385 } 3386 else 3387 { 3388 __pat = __mp.pos_format(); 3389 __sn = __mp.positive_sign(); 3390 } 3391 __dp = __mp.decimal_point(); 3392 __ts = __mp.thousands_sep(); 3393 __grp = __mp.grouping(); 3394 __sym = __mp.curr_symbol(); 3395 __fd = __mp.frac_digits(); 3396 } 3397 else 3398 { 3399 const moneypunct<char_type, false>& __mp = 3400 use_facet<moneypunct<char_type, false> >(__loc); 3401 if (__neg) 3402 { 3403 __pat = __mp.neg_format(); 3404 __sn = __mp.negative_sign(); 3405 } 3406 else 3407 { 3408 __pat = __mp.pos_format(); 3409 __sn = __mp.positive_sign(); 3410 } 3411 __dp = __mp.decimal_point(); 3412 __ts = __mp.thousands_sep(); 3413 __grp = __mp.grouping(); 3414 __sym = __mp.curr_symbol(); 3415 __fd = __mp.frac_digits(); 3416 } 3417} 3418 3419template <class _CharT> 3420void 3421__money_put<_CharT>::__format(char_type* __mb, char_type*& __mi, char_type*& __me, 3422 ios_base::fmtflags __flags, 3423 const char_type* __db, const char_type* __de, 3424 const ctype<char_type>& __ct, bool __neg, 3425 const money_base::pattern& __pat, char_type __dp, 3426 char_type __ts, const string& __grp, 3427 const string_type& __sym, const string_type& __sn, 3428 int __fd) 3429{ 3430 __me = __mb; 3431 for (unsigned __p = 0; __p < 4; ++__p) 3432 { 3433 switch (__pat.field[__p]) 3434 { 3435 case money_base::none: 3436 __mi = __me; 3437 break; 3438 case money_base::space: 3439 __mi = __me; 3440 *__me++ = __ct.widen(' '); 3441 break; 3442 case money_base::sign: 3443 if (!__sn.empty()) 3444 *__me++ = __sn[0]; 3445 break; 3446 case money_base::symbol: 3447 if (!__sym.empty() && (__flags & ios_base::showbase)) 3448 __me = _VSTD::copy(__sym.begin(), __sym.end(), __me); 3449 break; 3450 case money_base::value: 3451 { 3452 // remember start of value so we can reverse it 3453 char_type* __t = __me; 3454 // find beginning of digits 3455 if (__neg) 3456 ++__db; 3457 // find end of digits 3458 const char_type* __d; 3459 for (__d = __db; __d < __de; ++__d) 3460 if (!__ct.is(ctype_base::digit, *__d)) 3461 break; 3462 // print fractional part 3463 if (__fd > 0) 3464 { 3465 int __f; 3466 for (__f = __fd; __d > __db && __f > 0; --__f) 3467 *__me++ = *--__d; 3468 char_type __z = __f > 0 ? __ct.widen('0') : char_type(); 3469 for (; __f > 0; --__f) 3470 *__me++ = __z; 3471 *__me++ = __dp; 3472 } 3473 // print units part 3474 if (__d == __db) 3475 { 3476 *__me++ = __ct.widen('0'); 3477 } 3478 else 3479 { 3480 unsigned __ng = 0; 3481 unsigned __ig = 0; 3482 unsigned __gl = __grp.empty() ? numeric_limits<unsigned>::max() 3483 : static_cast<unsigned>(__grp[__ig]); 3484 while (__d != __db) 3485 { 3486 if (__ng == __gl) 3487 { 3488 *__me++ = __ts; 3489 __ng = 0; 3490 if (++__ig < __grp.size()) 3491 __gl = __grp[__ig] == numeric_limits<char>::max() ? 3492 numeric_limits<unsigned>::max() : 3493 static_cast<unsigned>(__grp[__ig]); 3494 } 3495 *__me++ = *--__d; 3496 ++__ng; 3497 } 3498 } 3499 // reverse it 3500 reverse(__t, __me); 3501 } 3502 break; 3503 } 3504 } 3505 // print rest of sign, if any 3506 if (__sn.size() > 1) 3507 __me = _VSTD::copy(__sn.begin()+1, __sn.end(), __me); 3508 // set alignment 3509 if ((__flags & ios_base::adjustfield) == ios_base::left) 3510 __mi = __me; 3511 else if ((__flags & ios_base::adjustfield) != ios_base::internal) 3512 __mi = __mb; 3513} 3514 3515extern template class __money_put<char>; 3516extern template class __money_put<wchar_t>; 3517 3518template <class _CharT, class _OutputIterator = ostreambuf_iterator<_CharT> > 3519class _LIBCPP_VISIBLE money_put 3520 : public locale::facet, 3521 private __money_put<_CharT> 3522{ 3523public: 3524 typedef _CharT char_type; 3525 typedef _OutputIterator iter_type; 3526 typedef basic_string<char_type> string_type; 3527 3528 _LIBCPP_ALWAYS_INLINE 3529 explicit money_put(size_t __refs = 0) 3530 : locale::facet(__refs) {} 3531 3532 _LIBCPP_ALWAYS_INLINE 3533 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, 3534 long double __units) const 3535 { 3536 return do_put(__s, __intl, __iob, __fl, __units); 3537 } 3538 3539 _LIBCPP_ALWAYS_INLINE 3540 iter_type put(iter_type __s, bool __intl, ios_base& __iob, char_type __fl, 3541 const string_type& __digits) const 3542 { 3543 return do_put(__s, __intl, __iob, __fl, __digits); 3544 } 3545 3546 static locale::id id; 3547 3548protected: 3549 _LIBCPP_ALWAYS_INLINE 3550 ~money_put() {} 3551 3552 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob, 3553 char_type __fl, long double __units) const; 3554 virtual iter_type do_put(iter_type __s, bool __intl, ios_base& __iob, 3555 char_type __fl, const string_type& __digits) const; 3556}; 3557 3558template <class _CharT, class _OutputIterator> 3559locale::id 3560money_put<_CharT, _OutputIterator>::id; 3561 3562template <class _CharT, class _OutputIterator> 3563_OutputIterator 3564money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, 3565 ios_base& __iob, char_type __fl, 3566 long double __units) const 3567{ 3568 // convert to char 3569 const size_t __bs = 100; 3570 char __buf[__bs]; 3571 char* __bb = __buf; 3572 char_type __digits[__bs]; 3573 char_type* __db = __digits; 3574 size_t __n = static_cast<size_t>(snprintf(__bb, __bs, "%.0Lf", __units)); 3575 unique_ptr<char, void(*)(void*)> __hn(0, free); 3576 unique_ptr<char_type, void(*)(void*)> __hd(0, free); 3577 // secure memory for digit storage 3578 if (__n > __bs-1) 3579 { 3580#ifdef _LIBCPP_LOCALE__L_EXTENSIONS 3581 __n = static_cast<size_t>(asprintf_l(&__bb, _LIBCPP_GET_C_LOCALE, "%.0Lf", __units)); 3582#else 3583 __n = __asprintf_l(&__bb, __cloc(), "%.0Lf", __units); 3584#endif 3585 if (__bb == 0) 3586 __throw_bad_alloc(); 3587 __hn.reset(__bb); 3588 __hd.reset((char_type*)malloc(__n * sizeof(char_type))); 3589 if (__hd == nullptr) 3590 __throw_bad_alloc(); 3591 __db = __hd.get(); 3592 } 3593 // gather info 3594 locale __loc = __iob.getloc(); 3595 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3596 __ct.widen(__bb, __bb + __n, __db); 3597 bool __neg = __n > 0 && __bb[0] == '-'; 3598 money_base::pattern __pat; 3599 char_type __dp; 3600 char_type __ts; 3601 string __grp; 3602 string_type __sym; 3603 string_type __sn; 3604 int __fd; 3605 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3606 // secure memory for formatting 3607 char_type __mbuf[__bs]; 3608 char_type* __mb = __mbuf; 3609 unique_ptr<char_type, void(*)(void*)> __hw(0, free); 3610 size_t __exn = static_cast<int>(__n) > __fd ? 3611 (__n - static_cast<size_t>(__fd)) * 2 + __sn.size() + 3612 __sym.size() + static_cast<size_t>(__fd) + 1 3613 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2; 3614 if (__exn > __bs) 3615 { 3616 __hw.reset((char_type*)malloc(__exn * sizeof(char_type))); 3617 __mb = __hw.get(); 3618 if (__mb == 0) 3619 __throw_bad_alloc(); 3620 } 3621 // format 3622 char_type* __mi; 3623 char_type* __me; 3624 this->__format(__mb, __mi, __me, __iob.flags(), 3625 __db, __db + __n, __ct, 3626 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3627 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl); 3628} 3629 3630template <class _CharT, class _OutputIterator> 3631_OutputIterator 3632money_put<_CharT, _OutputIterator>::do_put(iter_type __s, bool __intl, 3633 ios_base& __iob, char_type __fl, 3634 const string_type& __digits) const 3635{ 3636 // gather info 3637 locale __loc = __iob.getloc(); 3638 const ctype<char_type>& __ct = use_facet<ctype<char_type> >(__loc); 3639 bool __neg = __digits.size() > 0 && __digits[0] == __ct.widen('-'); 3640 money_base::pattern __pat; 3641 char_type __dp; 3642 char_type __ts; 3643 string __grp; 3644 string_type __sym; 3645 string_type __sn; 3646 int __fd; 3647 this->__gather_info(__intl, __neg, __loc, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3648 // secure memory for formatting 3649 char_type __mbuf[100]; 3650 char_type* __mb = __mbuf; 3651 unique_ptr<char_type, void(*)(void*)> __h(0, free); 3652 size_t __exn = static_cast<int>(__digits.size()) > __fd ? 3653 (__digits.size() - static_cast<size_t>(__fd)) * 2 + 3654 __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 1 3655 : __sn.size() + __sym.size() + static_cast<size_t>(__fd) + 2; 3656 if (__exn > 100) 3657 { 3658 __h.reset((char_type*)malloc(__exn * sizeof(char_type))); 3659 __mb = __h.get(); 3660 if (__mb == 0) 3661 __throw_bad_alloc(); 3662 } 3663 // format 3664 char_type* __mi; 3665 char_type* __me; 3666 this->__format(__mb, __mi, __me, __iob.flags(), 3667 __digits.data(), __digits.data() + __digits.size(), __ct, 3668 __neg, __pat, __dp, __ts, __grp, __sym, __sn, __fd); 3669 return __pad_and_output(__s, __mb, __mi, __me, __iob, __fl); 3670} 3671 3672extern template class money_put<char>; 3673extern template class money_put<wchar_t>; 3674 3675// messages 3676 3677class _LIBCPP_VISIBLE messages_base 3678{ 3679public: 3680 typedef ptrdiff_t catalog; 3681 3682 _LIBCPP_ALWAYS_INLINE messages_base() {} 3683}; 3684 3685template <class _CharT> 3686class _LIBCPP_VISIBLE messages 3687 : public locale::facet, 3688 public messages_base 3689{ 3690public: 3691 typedef _CharT char_type; 3692 typedef basic_string<_CharT> string_type; 3693 3694 _LIBCPP_ALWAYS_INLINE 3695 explicit messages(size_t __refs = 0) 3696 : locale::facet(__refs) {} 3697 3698 _LIBCPP_ALWAYS_INLINE 3699 catalog open(const basic_string<char>& __nm, const locale& __loc) const 3700 { 3701 return do_open(__nm, __loc); 3702 } 3703 3704 _LIBCPP_ALWAYS_INLINE 3705 string_type get(catalog __c, int __set, int __msgid, 3706 const string_type& __dflt) const 3707 { 3708 return do_get(__c, __set, __msgid, __dflt); 3709 } 3710 3711 _LIBCPP_ALWAYS_INLINE 3712 void close(catalog __c) const 3713 { 3714 do_close(__c); 3715 } 3716 3717 static locale::id id; 3718 3719protected: 3720 _LIBCPP_ALWAYS_INLINE 3721 ~messages() {} 3722 3723 virtual catalog do_open(const basic_string<char>&, const locale&) const; 3724 virtual string_type do_get(catalog, int __set, int __msgid, 3725 const string_type& __dflt) const; 3726 virtual void do_close(catalog) const; 3727}; 3728 3729template <class _CharT> 3730locale::id 3731messages<_CharT>::id; 3732 3733template <class _CharT> 3734typename messages<_CharT>::catalog 3735messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const 3736{ 3737#if _WIN32 3738 return -1; 3739#else // _WIN32 3740 catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE); 3741 if (__cat != -1) 3742 __cat = static_cast<catalog>((static_cast<size_t>(__cat) >> 1)); 3743 return __cat; 3744#endif // _WIN32 3745} 3746 3747template <class _CharT> 3748typename messages<_CharT>::string_type 3749messages<_CharT>::do_get(catalog __c, int __set, int __msgid, 3750 const string_type& __dflt) const 3751{ 3752#if _WIN32 3753 return __dflt; 3754#else // _WIN32 3755 string __ndflt; 3756 __narrow_to_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__ndflt), 3757 __dflt.c_str(), 3758 __dflt.c_str() + __dflt.size()); 3759 if (__c != -1) 3760 __c <<= 1; 3761 nl_catd __cat = (nl_catd)__c; 3762 char* __n = catgets(__cat, __set, __msgid, __ndflt.c_str()); 3763 string_type __w; 3764 __widen_from_utf8<sizeof(char_type)*__CHAR_BIT__>()(back_inserter(__w), 3765 __n, __n + strlen(__n)); 3766 return __w; 3767#endif // _WIN32 3768} 3769 3770template <class _CharT> 3771void 3772messages<_CharT>::do_close(catalog __c) const 3773{ 3774#if !_WIN32 3775 if (__c != -1) 3776 __c <<= 1; 3777 nl_catd __cat = (nl_catd)__c; 3778 catclose(__cat); 3779#endif // !_WIN32 3780} 3781 3782extern template class messages<char>; 3783extern template class messages<wchar_t>; 3784 3785template <class _CharT> 3786class _LIBCPP_VISIBLE messages_byname 3787 : public messages<_CharT> 3788{ 3789public: 3790 typedef messages_base::catalog catalog; 3791 typedef basic_string<_CharT> string_type; 3792 3793 _LIBCPP_ALWAYS_INLINE 3794 explicit messages_byname(const char*, size_t __refs = 0) 3795 : messages<_CharT>(__refs) {} 3796 3797 _LIBCPP_ALWAYS_INLINE 3798 explicit messages_byname(const string&, size_t __refs = 0) 3799 : messages<_CharT>(__refs) {} 3800 3801protected: 3802 _LIBCPP_ALWAYS_INLINE 3803 ~messages_byname() {} 3804}; 3805 3806extern template class messages_byname<char>; 3807extern template class messages_byname<wchar_t>; 3808 3809template<class _Codecvt, class _Elem = wchar_t, 3810 class _Wide_alloc = allocator<_Elem>, 3811 class _Byte_alloc = allocator<char> > 3812class _LIBCPP_VISIBLE wstring_convert 3813{ 3814public: 3815 typedef basic_string<char, char_traits<char>, _Byte_alloc> byte_string; 3816 typedef basic_string<_Elem, char_traits<_Elem>, _Wide_alloc> wide_string; 3817 typedef typename _Codecvt::state_type state_type; 3818 typedef typename wide_string::traits_type::int_type int_type; 3819 3820private: 3821 byte_string __byte_err_string_; 3822 wide_string __wide_err_string_; 3823 _Codecvt* __cvtptr_; 3824 state_type __cvtstate_; 3825 size_t __cvtcount_; 3826 3827 wstring_convert(const wstring_convert& __wc); 3828 wstring_convert& operator=(const wstring_convert& __wc); 3829public: 3830 wstring_convert(_Codecvt* __pcvt = new _Codecvt); 3831 wstring_convert(_Codecvt* __pcvt, state_type __state); 3832 wstring_convert(const byte_string& __byte_err, 3833 const wide_string& __wide_err = wide_string()); 3834#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 3835 wstring_convert(wstring_convert&& __wc); 3836#endif 3837 ~wstring_convert(); 3838 3839 _LIBCPP_ALWAYS_INLINE 3840 wide_string from_bytes(char __byte) 3841 {return from_bytes(&__byte, &__byte+1);} 3842 _LIBCPP_ALWAYS_INLINE 3843 wide_string from_bytes(const char* __ptr) 3844 {return from_bytes(__ptr, __ptr + char_traits<char>::length(__ptr));} 3845 _LIBCPP_ALWAYS_INLINE 3846 wide_string from_bytes(const byte_string& __str) 3847 {return from_bytes(__str.data(), __str.data() + __str.size());} 3848 wide_string from_bytes(const char* __first, const char* __last); 3849 3850 _LIBCPP_ALWAYS_INLINE 3851 byte_string to_bytes(_Elem __wchar) 3852 {return to_bytes(&__wchar, &__wchar+1);} 3853 _LIBCPP_ALWAYS_INLINE 3854 byte_string to_bytes(const _Elem* __wptr) 3855 {return to_bytes(__wptr, __wptr + char_traits<_Elem>::length(__wptr));} 3856 _LIBCPP_ALWAYS_INLINE 3857 byte_string to_bytes(const wide_string& __wstr) 3858 {return to_bytes(__wstr.data(), __wstr.data() + __wstr.size());} 3859 byte_string to_bytes(const _Elem* __first, const _Elem* __last); 3860 3861 _LIBCPP_ALWAYS_INLINE 3862 size_t converted() const {return __cvtcount_;} 3863 _LIBCPP_ALWAYS_INLINE 3864 state_type state() const {return __cvtstate_;} 3865}; 3866 3867template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3868inline _LIBCPP_ALWAYS_INLINE 3869wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3870 wstring_convert(_Codecvt* __pcvt) 3871 : __cvtptr_(__pcvt), __cvtstate_(), __cvtcount_(0) 3872{ 3873} 3874 3875template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3876inline _LIBCPP_ALWAYS_INLINE 3877wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3878 wstring_convert(_Codecvt* __pcvt, state_type __state) 3879 : __cvtptr_(__pcvt), __cvtstate_(__state), __cvtcount_(0) 3880{ 3881} 3882 3883template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3884wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3885 wstring_convert(const byte_string& __byte_err, const wide_string& __wide_err) 3886 : __byte_err_string_(__byte_err), __wide_err_string_(__wide_err), 3887 __cvtstate_(), __cvtcount_(0) 3888{ 3889 __cvtptr_ = new _Codecvt; 3890} 3891 3892#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 3893 3894template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3895inline _LIBCPP_ALWAYS_INLINE 3896wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3897 wstring_convert(wstring_convert&& __wc) 3898 : __byte_err_string_(_VSTD::move(__wc.__byte_err_string_)), 3899 __wide_err_string_(_VSTD::move(__wc.__wide_err_string_)), 3900 __cvtptr_(__wc.__cvtptr_), 3901 __cvtstate_(__wc.__cvtstate_), __cvtcount_(__wc.__cvtstate_) 3902{ 3903 __wc.__cvtptr_ = nullptr; 3904} 3905 3906#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 3907 3908template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3909wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::~wstring_convert() 3910{ 3911 delete __cvtptr_; 3912} 3913 3914template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3915typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::wide_string 3916wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3917 from_bytes(const char* __frm, const char* __frm_end) 3918{ 3919 __cvtcount_ = 0; 3920 if (__cvtptr_ != nullptr) 3921 { 3922 wide_string __ws(2*(__frm_end - __frm), _Elem()); 3923 __ws.resize(__ws.capacity()); 3924 codecvt_base::result __r = codecvt_base::ok; 3925 state_type __st = __cvtstate_; 3926 if (__frm != __frm_end) 3927 { 3928 _Elem* __to = &__ws[0]; 3929 _Elem* __to_end = __to + __ws.size(); 3930 const char* __frm_nxt; 3931 do 3932 { 3933 _Elem* __to_nxt; 3934 __r = __cvtptr_->in(__st, __frm, __frm_end, __frm_nxt, 3935 __to, __to_end, __to_nxt); 3936 __cvtcount_ += __frm_nxt - __frm; 3937 if (__frm_nxt == __frm) 3938 { 3939 __r = codecvt_base::error; 3940 } 3941 else if (__r == codecvt_base::noconv) 3942 { 3943 __ws.resize(__to - &__ws[0]); 3944 // This only gets executed if _Elem is char 3945 __ws.append((const _Elem*)__frm, (const _Elem*)__frm_end); 3946 __frm = __frm_nxt; 3947 __r = codecvt_base::ok; 3948 } 3949 else if (__r == codecvt_base::ok) 3950 { 3951 __ws.resize(__to_nxt - &__ws[0]); 3952 __frm = __frm_nxt; 3953 } 3954 else if (__r == codecvt_base::partial) 3955 { 3956 ptrdiff_t __s = __to_nxt - &__ws[0]; 3957 __ws.resize(2 * __s); 3958 __to = &__ws[0] + __s; 3959 __to_end = &__ws[0] + __ws.size(); 3960 __frm = __frm_nxt; 3961 } 3962 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end); 3963 } 3964 if (__r == codecvt_base::ok) 3965 return __ws; 3966 } 3967#ifndef _LIBCPP_NO_EXCEPTIONS 3968 if (__wide_err_string_.empty()) 3969 throw range_error("wstring_convert: from_bytes error"); 3970#endif // _LIBCPP_NO_EXCEPTIONS 3971 return __wide_err_string_; 3972} 3973 3974template<class _Codecvt, class _Elem, class _Wide_alloc, class _Byte_alloc> 3975typename wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>::byte_string 3976wstring_convert<_Codecvt, _Elem, _Wide_alloc, _Byte_alloc>:: 3977 to_bytes(const _Elem* __frm, const _Elem* __frm_end) 3978{ 3979 __cvtcount_ = 0; 3980 if (__cvtptr_ != nullptr) 3981 { 3982 byte_string __bs(2*(__frm_end - __frm), char()); 3983 __bs.resize(__bs.capacity()); 3984 codecvt_base::result __r = codecvt_base::ok; 3985 state_type __st = __cvtstate_; 3986 if (__frm != __frm_end) 3987 { 3988 char* __to = &__bs[0]; 3989 char* __to_end = __to + __bs.size(); 3990 const _Elem* __frm_nxt; 3991 do 3992 { 3993 char* __to_nxt; 3994 __r = __cvtptr_->out(__st, __frm, __frm_end, __frm_nxt, 3995 __to, __to_end, __to_nxt); 3996 __cvtcount_ += __frm_nxt - __frm; 3997 if (__frm_nxt == __frm) 3998 { 3999 __r = codecvt_base::error; 4000 } 4001 else if (__r == codecvt_base::noconv) 4002 { 4003 __bs.resize(__to - &__bs[0]); 4004 // This only gets executed if _Elem is char 4005 __bs.append((const char*)__frm, (const char*)__frm_end); 4006 __frm = __frm_nxt; 4007 __r = codecvt_base::ok; 4008 } 4009 else if (__r == codecvt_base::ok) 4010 { 4011 __bs.resize(__to_nxt - &__bs[0]); 4012 __frm = __frm_nxt; 4013 } 4014 else if (__r == codecvt_base::partial) 4015 { 4016 ptrdiff_t __s = __to_nxt - &__bs[0]; 4017 __bs.resize(2 * __s); 4018 __to = &__bs[0] + __s; 4019 __to_end = &__bs[0] + __bs.size(); 4020 __frm = __frm_nxt; 4021 } 4022 } while (__r == codecvt_base::partial && __frm_nxt < __frm_end); 4023 } 4024 if (__r == codecvt_base::ok) 4025 { 4026 size_t __s = __bs.size(); 4027 __bs.resize(__bs.capacity()); 4028 char* __to = &__bs[0] + __s; 4029 char* __to_end = __to + __bs.size(); 4030 do 4031 { 4032 char* __to_nxt; 4033 __r = __cvtptr_->unshift(__st, __to, __to_end, __to_nxt); 4034 if (__r == codecvt_base::noconv) 4035 { 4036 __bs.resize(__to - &__bs[0]); 4037 __r = codecvt_base::ok; 4038 } 4039 else if (__r == codecvt_base::ok) 4040 { 4041 __bs.resize(__to_nxt - &__bs[0]); 4042 } 4043 else if (__r == codecvt_base::partial) 4044 { 4045 ptrdiff_t __sp = __to_nxt - &__bs[0]; 4046 __bs.resize(2 * __sp); 4047 __to = &__bs[0] + __sp; 4048 __to_end = &__bs[0] + __bs.size(); 4049 } 4050 } while (__r == codecvt_base::partial); 4051 if (__r == codecvt_base::ok) 4052 return __bs; 4053 } 4054 } 4055#ifndef _LIBCPP_NO_EXCEPTIONS 4056 if (__byte_err_string_.empty()) 4057 throw range_error("wstring_convert: to_bytes error"); 4058#endif // _LIBCPP_NO_EXCEPTIONS 4059 return __byte_err_string_; 4060} 4061 4062template <class _Codecvt, class _Elem = wchar_t, class _Tr = char_traits<_Elem> > 4063class _LIBCPP_VISIBLE wbuffer_convert 4064 : public basic_streambuf<_Elem, _Tr> 4065{ 4066public: 4067 // types: 4068 typedef _Elem char_type; 4069 typedef _Tr traits_type; 4070 typedef typename traits_type::int_type int_type; 4071 typedef typename traits_type::pos_type pos_type; 4072 typedef typename traits_type::off_type off_type; 4073 typedef typename _Codecvt::state_type state_type; 4074 4075private: 4076 char* __extbuf_; 4077 const char* __extbufnext_; 4078 const char* __extbufend_; 4079 char __extbuf_min_[8]; 4080 size_t __ebs_; 4081 char_type* __intbuf_; 4082 size_t __ibs_; 4083 streambuf* __bufptr_; 4084 _Codecvt* __cv_; 4085 state_type __st_; 4086 ios_base::openmode __cm_; 4087 bool __owns_eb_; 4088 bool __owns_ib_; 4089 bool __always_noconv_; 4090 4091 wbuffer_convert(const wbuffer_convert&); 4092 wbuffer_convert& operator=(const wbuffer_convert&); 4093public: 4094 wbuffer_convert(streambuf* __bytebuf = 0, _Codecvt* __pcvt = new _Codecvt, 4095 state_type __state = state_type()); 4096 ~wbuffer_convert(); 4097 4098 _LIBCPP_INLINE_VISIBILITY 4099 streambuf* rdbuf() const {return __bufptr_;} 4100 _LIBCPP_INLINE_VISIBILITY 4101 streambuf* rdbuf(streambuf* __bytebuf) 4102 { 4103 streambuf* __r = __bufptr_; 4104 __bufptr_ = __bytebuf; 4105 return __r; 4106 } 4107 4108 _LIBCPP_INLINE_VISIBILITY 4109 state_type state() const {return __st_;} 4110 4111protected: 4112 virtual int_type underflow(); 4113 virtual int_type pbackfail(int_type __c = traits_type::eof()); 4114 virtual int_type overflow (int_type __c = traits_type::eof()); 4115 virtual basic_streambuf<char_type, traits_type>* setbuf(char_type* __s, 4116 streamsize __n); 4117 virtual pos_type seekoff(off_type __off, ios_base::seekdir __way, 4118 ios_base::openmode __wch = ios_base::in | ios_base::out); 4119 virtual pos_type seekpos(pos_type __sp, 4120 ios_base::openmode __wch = ios_base::in | ios_base::out); 4121 virtual int sync(); 4122 4123private: 4124 bool __read_mode(); 4125 void __write_mode(); 4126 wbuffer_convert* __close(); 4127}; 4128 4129template <class _Codecvt, class _Elem, class _Tr> 4130wbuffer_convert<_Codecvt, _Elem, _Tr>:: 4131 wbuffer_convert(streambuf* __bytebuf, _Codecvt* __pcvt, state_type __state) 4132 : __extbuf_(0), 4133 __extbufnext_(0), 4134 __extbufend_(0), 4135 __ebs_(0), 4136 __intbuf_(0), 4137 __ibs_(0), 4138 __bufptr_(__bytebuf), 4139 __cv_(__pcvt), 4140 __st_(__state), 4141 __cm_(0), 4142 __owns_eb_(false), 4143 __owns_ib_(false), 4144 __always_noconv_(__cv_ ? __cv_->always_noconv() : false) 4145{ 4146 setbuf(0, 4096); 4147} 4148 4149template <class _Codecvt, class _Elem, class _Tr> 4150wbuffer_convert<_Codecvt, _Elem, _Tr>::~wbuffer_convert() 4151{ 4152 __close(); 4153 delete __cv_; 4154 if (__owns_eb_) 4155 delete [] __extbuf_; 4156 if (__owns_ib_) 4157 delete [] __intbuf_; 4158} 4159 4160template <class _Codecvt, class _Elem, class _Tr> 4161typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 4162wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow() 4163{ 4164 if (__cv_ == 0 || __bufptr_ == 0) 4165 return traits_type::eof(); 4166 bool __initial = __read_mode(); 4167 char_type __1buf; 4168 if (this->gptr() == 0) 4169 this->setg(&__1buf, &__1buf+1, &__1buf+1); 4170 const size_t __unget_sz = __initial ? 0 : min<size_t>((this->egptr() - this->eback()) / 2, 4); 4171 int_type __c = traits_type::eof(); 4172 if (this->gptr() == this->egptr()) 4173 { 4174 memmove(this->eback(), this->egptr() - __unget_sz, __unget_sz * sizeof(char_type)); 4175 if (__always_noconv_) 4176 { 4177 streamsize __nmemb = static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz); 4178 __nmemb = __bufptr_->sgetn((char*)this->eback() + __unget_sz, __nmemb); 4179 if (__nmemb != 0) 4180 { 4181 this->setg(this->eback(), 4182 this->eback() + __unget_sz, 4183 this->eback() + __unget_sz + __nmemb); 4184 __c = *this->gptr(); 4185 } 4186 } 4187 else 4188 { 4189 memmove(__extbuf_, __extbufnext_, __extbufend_ - __extbufnext_); 4190 __extbufnext_ = __extbuf_ + (__extbufend_ - __extbufnext_); 4191 __extbufend_ = __extbuf_ + (__extbuf_ == __extbuf_min_ ? sizeof(__extbuf_min_) : __ebs_); 4192 streamsize __nmemb = _VSTD::min(static_cast<streamsize>(this->egptr() - this->eback() - __unget_sz), 4193 static_cast<streamsize>(__extbufend_ - __extbufnext_)); 4194 codecvt_base::result __r; 4195 state_type __svs = __st_; 4196 streamsize __nr = __bufptr_->sgetn(const_cast<char*>(__extbufnext_), __nmemb); 4197 if (__nr != 0) 4198 { 4199 __extbufend_ = __extbufnext_ + __nr; 4200 char_type* __inext; 4201 __r = __cv_->in(__st_, __extbuf_, __extbufend_, __extbufnext_, 4202 this->eback() + __unget_sz, 4203 this->egptr(), __inext); 4204 if (__r == codecvt_base::noconv) 4205 { 4206 this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_); 4207 __c = *this->gptr(); 4208 } 4209 else if (__inext != this->eback() + __unget_sz) 4210 { 4211 this->setg(this->eback(), this->eback() + __unget_sz, __inext); 4212 __c = *this->gptr(); 4213 } 4214 } 4215 } 4216 } 4217 else 4218 __c = *this->gptr(); 4219 if (this->eback() == &__1buf) 4220 this->setg(0, 0, 0); 4221 return __c; 4222} 4223 4224template <class _Codecvt, class _Elem, class _Tr> 4225typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 4226wbuffer_convert<_Codecvt, _Elem, _Tr>::pbackfail(int_type __c) 4227{ 4228 if (__cv_ != 0 && __bufptr_ != 0 && this->eback() < this->gptr()) 4229 { 4230 if (traits_type::eq_int_type(__c, traits_type::eof())) 4231 { 4232 this->gbump(-1); 4233 return traits_type::not_eof(__c); 4234 } 4235 if (traits_type::eq(traits_type::to_char_type(__c), this->gptr()[-1])) 4236 { 4237 this->gbump(-1); 4238 *this->gptr() = traits_type::to_char_type(__c); 4239 return __c; 4240 } 4241 } 4242 return traits_type::eof(); 4243} 4244 4245template <class _Codecvt, class _Elem, class _Tr> 4246typename wbuffer_convert<_Codecvt, _Elem, _Tr>::int_type 4247wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c) 4248{ 4249 if (__cv_ == 0 || __bufptr_ == 0) 4250 return traits_type::eof(); 4251 __write_mode(); 4252 char_type __1buf; 4253 char_type* __pb_save = this->pbase(); 4254 char_type* __epb_save = this->epptr(); 4255 if (!traits_type::eq_int_type(__c, traits_type::eof())) 4256 { 4257 if (this->pptr() == 0) 4258 this->setp(&__1buf, &__1buf+1); 4259 *this->pptr() = traits_type::to_char_type(__c); 4260 this->pbump(1); 4261 } 4262 if (this->pptr() != this->pbase()) 4263 { 4264 if (__always_noconv_) 4265 { 4266 streamsize __nmemb = static_cast<streamsize>(this->pptr() - this->pbase()); 4267 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb) 4268 return traits_type::eof(); 4269 } 4270 else 4271 { 4272 char* __extbe = __extbuf_; 4273 codecvt_base::result __r; 4274 do 4275 { 4276 const char_type* __e; 4277 __r = __cv_->out(__st_, this->pbase(), this->pptr(), __e, 4278 __extbuf_, __extbuf_ + __ebs_, __extbe); 4279 if (__e == this->pbase()) 4280 return traits_type::eof(); 4281 if (__r == codecvt_base::noconv) 4282 { 4283 streamsize __nmemb = static_cast<size_t>(this->pptr() - this->pbase()); 4284 if (__bufptr_->sputn((const char*)this->pbase(), __nmemb) != __nmemb) 4285 return traits_type::eof(); 4286 } 4287 else if (__r == codecvt_base::ok || __r == codecvt_base::partial) 4288 { 4289 streamsize __nmemb = static_cast<size_t>(__extbe - __extbuf_); 4290 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb) 4291 return traits_type::eof(); 4292 if (__r == codecvt_base::partial) 4293 { 4294 this->setp((char_type*)__e, this->pptr()); 4295 this->pbump(this->epptr() - this->pbase()); 4296 } 4297 } 4298 else 4299 return traits_type::eof(); 4300 } while (__r == codecvt_base::partial); 4301 } 4302 this->setp(__pb_save, __epb_save); 4303 } 4304 return traits_type::not_eof(__c); 4305} 4306 4307template <class _Codecvt, class _Elem, class _Tr> 4308basic_streambuf<_Elem, _Tr>* 4309wbuffer_convert<_Codecvt, _Elem, _Tr>::setbuf(char_type* __s, streamsize __n) 4310{ 4311 this->setg(0, 0, 0); 4312 this->setp(0, 0); 4313 if (__owns_eb_) 4314 delete [] __extbuf_; 4315 if (__owns_ib_) 4316 delete [] __intbuf_; 4317 __ebs_ = __n; 4318 if (__ebs_ > sizeof(__extbuf_min_)) 4319 { 4320 if (__always_noconv_ && __s) 4321 { 4322 __extbuf_ = (char*)__s; 4323 __owns_eb_ = false; 4324 } 4325 else 4326 { 4327 __extbuf_ = new char[__ebs_]; 4328 __owns_eb_ = true; 4329 } 4330 } 4331 else 4332 { 4333 __extbuf_ = __extbuf_min_; 4334 __ebs_ = sizeof(__extbuf_min_); 4335 __owns_eb_ = false; 4336 } 4337 if (!__always_noconv_) 4338 { 4339 __ibs_ = max<streamsize>(__n, sizeof(__extbuf_min_)); 4340 if (__s && __ibs_ >= sizeof(__extbuf_min_)) 4341 { 4342 __intbuf_ = __s; 4343 __owns_ib_ = false; 4344 } 4345 else 4346 { 4347 __intbuf_ = new char_type[__ibs_]; 4348 __owns_ib_ = true; 4349 } 4350 } 4351 else 4352 { 4353 __ibs_ = 0; 4354 __intbuf_ = 0; 4355 __owns_ib_ = false; 4356 } 4357 return this; 4358} 4359 4360template <class _Codecvt, class _Elem, class _Tr> 4361typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type 4362wbuffer_convert<_Codecvt, _Elem, _Tr>::seekoff(off_type __off, ios_base::seekdir __way, 4363 ios_base::openmode __om) 4364{ 4365 int __width = __cv_->encoding(); 4366 if (__cv_ == 0 || __bufptr_ == 0 || (__width <= 0 && __off != 0) || sync()) 4367 return pos_type(off_type(-1)); 4368 // __width > 0 || __off == 0 4369 switch (__way) 4370 { 4371 case ios_base::beg: 4372 break; 4373 case ios_base::cur: 4374 break; 4375 case ios_base::end: 4376 break; 4377 default: 4378 return pos_type(off_type(-1)); 4379 } 4380 pos_type __r = __bufptr_->pubseekoff(__width * __off, __way, __om); 4381 __r.state(__st_); 4382 return __r; 4383} 4384 4385template <class _Codecvt, class _Elem, class _Tr> 4386typename wbuffer_convert<_Codecvt, _Elem, _Tr>::pos_type 4387wbuffer_convert<_Codecvt, _Elem, _Tr>::seekpos(pos_type __sp, ios_base::openmode __wch) 4388{ 4389 if (__cv_ == 0 || __bufptr_ == 0 || sync()) 4390 return pos_type(off_type(-1)); 4391 if (__bufptr_->pubseekpos(__sp, __wch) == pos_type(off_type(-1))) 4392 return pos_type(off_type(-1)); 4393 return __sp; 4394} 4395 4396template <class _Codecvt, class _Elem, class _Tr> 4397int 4398wbuffer_convert<_Codecvt, _Elem, _Tr>::sync() 4399{ 4400 if (__cv_ == 0 || __bufptr_ == 0) 4401 return 0; 4402 if (__cm_ & ios_base::out) 4403 { 4404 if (this->pptr() != this->pbase()) 4405 if (overflow() == traits_type::eof()) 4406 return -1; 4407 codecvt_base::result __r; 4408 do 4409 { 4410 char* __extbe; 4411 __r = __cv_->unshift(__st_, __extbuf_, __extbuf_ + __ebs_, __extbe); 4412 streamsize __nmemb = static_cast<streamsize>(__extbe - __extbuf_); 4413 if (__bufptr_->sputn(__extbuf_, __nmemb) != __nmemb) 4414 return -1; 4415 } while (__r == codecvt_base::partial); 4416 if (__r == codecvt_base::error) 4417 return -1; 4418 if (__bufptr_->pubsync()) 4419 return -1; 4420 } 4421 else if (__cm_ & ios_base::in) 4422 { 4423 off_type __c; 4424 if (__always_noconv_) 4425 __c = this->egptr() - this->gptr(); 4426 else 4427 { 4428 int __width = __cv_->encoding(); 4429 __c = __extbufend_ - __extbufnext_; 4430 if (__width > 0) 4431 __c += __width * (this->egptr() - this->gptr()); 4432 else 4433 { 4434 if (this->gptr() != this->egptr()) 4435 { 4436 reverse(this->gptr(), this->egptr()); 4437 codecvt_base::result __r; 4438 const char_type* __e = this->gptr(); 4439 char* __extbe; 4440 do 4441 { 4442 __r = __cv_->out(__st_, __e, this->egptr(), __e, 4443 __extbuf_, __extbuf_ + __ebs_, __extbe); 4444 switch (__r) 4445 { 4446 case codecvt_base::noconv: 4447 __c += this->egptr() - this->gptr(); 4448 break; 4449 case codecvt_base::ok: 4450 case codecvt_base::partial: 4451 __c += __extbe - __extbuf_; 4452 break; 4453 default: 4454 return -1; 4455 } 4456 } while (__r == codecvt_base::partial); 4457 } 4458 } 4459 } 4460 if (__bufptr_->pubseekoff(-__c, ios_base::cur, __cm_) == pos_type(off_type(-1))) 4461 return -1; 4462 this->setg(0, 0, 0); 4463 __cm_ = 0; 4464 } 4465 return 0; 4466} 4467 4468template <class _Codecvt, class _Elem, class _Tr> 4469bool 4470wbuffer_convert<_Codecvt, _Elem, _Tr>::__read_mode() 4471{ 4472 if (!(__cm_ & ios_base::in)) 4473 { 4474 this->setp(0, 0); 4475 if (__always_noconv_) 4476 this->setg((char_type*)__extbuf_, 4477 (char_type*)__extbuf_ + __ebs_, 4478 (char_type*)__extbuf_ + __ebs_); 4479 else 4480 this->setg(__intbuf_, __intbuf_ + __ibs_, __intbuf_ + __ibs_); 4481 __cm_ = ios_base::in; 4482 return true; 4483 } 4484 return false; 4485} 4486 4487template <class _Codecvt, class _Elem, class _Tr> 4488void 4489wbuffer_convert<_Codecvt, _Elem, _Tr>::__write_mode() 4490{ 4491 if (!(__cm_ & ios_base::out)) 4492 { 4493 this->setg(0, 0, 0); 4494 if (__ebs_ > sizeof(__extbuf_min_)) 4495 { 4496 if (__always_noconv_) 4497 this->setp((char_type*)__extbuf_, 4498 (char_type*)__extbuf_ + (__ebs_ - 1)); 4499 else 4500 this->setp(__intbuf_, __intbuf_ + (__ibs_ - 1)); 4501 } 4502 else 4503 this->setp(0, 0); 4504 __cm_ = ios_base::out; 4505 } 4506} 4507 4508template <class _Codecvt, class _Elem, class _Tr> 4509wbuffer_convert<_Codecvt, _Elem, _Tr>* 4510wbuffer_convert<_Codecvt, _Elem, _Tr>::__close() 4511{ 4512 wbuffer_convert* __rt = 0; 4513 if (__cv_ != 0 && __bufptr_ != 0) 4514 { 4515 __rt = this; 4516 if ((__cm_ & ios_base::out) && sync()) 4517 __rt = 0; 4518 } 4519 return __rt; 4520} 4521 4522_LIBCPP_END_NAMESPACE_STD 4523 4524#endif // _LIBCPP_LOCALE 4525