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