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