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