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