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