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