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