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