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