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