Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/13/bits/locale_facets_nonio.tcc
$ cat -n /usr/include/c++/13/bits/locale_facets_nonio.tcc 1 // Locale support -*- C++ -*- 2 3 // Copyright (C) 2007-2023 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 //
. 24 25 /** @file bits/locale_facets_nonio.tcc 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{locale} 28 */ 29 30 #ifndef _LOCALE_FACETS_NONIO_TCC 31 #define _LOCALE_FACETS_NONIO_TCC 1 32 33 #pragma GCC system_header 34 35 namespace std _GLIBCXX_VISIBILITY(default) 36 { 37 _GLIBCXX_BEGIN_NAMESPACE_VERSION 38 39 template
40 struct __use_cache<__moneypunct_cache<_CharT, _Intl> > 41 { 42 const __moneypunct_cache<_CharT, _Intl>* 43 operator() (const locale& __loc) const 44 { 45 const size_t __i = moneypunct<_CharT, _Intl>::id._M_id(); 46 const locale::facet** __caches = __loc._M_impl->_M_caches; 47 if (!__caches[__i]) 48 { 49 __moneypunct_cache<_CharT, _Intl>* __tmp = 0; 50 __try 51 { 52 __tmp = new __moneypunct_cache<_CharT, _Intl>; 53 __tmp->_M_cache(__loc); 54 } 55 __catch(...) 56 { 57 delete __tmp; 58 __throw_exception_again; 59 } 60 __loc._M_impl->_M_install_cache(__tmp, __i); 61 } 62 return static_cast< 63 const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]); 64 } 65 }; 66 67 template
68 void 69 __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc) 70 { 71 const moneypunct<_CharT, _Intl>& __mp = 72 use_facet
>(__loc); 73 74 struct _Scoped_str 75 { 76 size_t _M_len; 77 _CharT* _M_str; 78 79 explicit 80 _Scoped_str(const basic_string<_CharT>& __str) 81 : _M_len(__str.size()), _M_str(new _CharT[_M_len]) 82 { __str.copy(_M_str, _M_len); } 83 84 ~_Scoped_str() { delete[] _M_str; } 85 86 void 87 _M_release(const _CharT*& __p, size_t& __n) 88 { 89 __p = _M_str; 90 __n = _M_len; 91 _M_str = 0; 92 } 93 }; 94 95 _Scoped_str __curr_symbol(__mp.curr_symbol()); 96 _Scoped_str __positive_sign(__mp.positive_sign()); 97 _Scoped_str __negative_sign(__mp.negative_sign()); 98 99 const string& __g = __mp.grouping(); 100 const size_t __g_size = __g.size(); 101 char* const __grouping = new char[__g_size]; 102 __g.copy(__grouping, __g_size); 103 104 // All allocations succeeded without throwing, OK to modify *this now. 105 106 _M_grouping = __grouping; 107 _M_grouping_size = __g_size; 108 _M_use_grouping = (__g_size 109 && static_cast
(__grouping[0]) > 0 110 && (__grouping[0] 111 != __gnu_cxx::__numeric_traits
::__max)); 112 113 _M_decimal_point = __mp.decimal_point(); 114 _M_thousands_sep = __mp.thousands_sep(); 115 116 __curr_symbol._M_release(_M_curr_symbol, _M_curr_symbol_size); 117 __positive_sign._M_release(_M_positive_sign, _M_positive_sign_size); 118 __negative_sign._M_release(_M_negative_sign, _M_negative_sign_size); 119 120 _M_frac_digits = __mp.frac_digits(); 121 _M_pos_format = __mp.pos_format(); 122 _M_neg_format = __mp.neg_format(); 123 124 const ctype<_CharT>& __ct = use_facet
>(__loc); 125 __ct.widen(money_base::_S_atoms, 126 money_base::_S_atoms + money_base::_S_end, _M_atoms); 127 128 _M_allocated = true; 129 } 130 131 _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 132 133 template
134 template
135 _InIter 136 money_get<_CharT, _InIter>:: 137 _M_extract(iter_type __beg, iter_type __end, ios_base& __io, 138 ios_base::iostate& __err, string& __units) const 139 { 140 typedef char_traits<_CharT> __traits_type; 141 typedef typename string_type::size_type size_type; 142 typedef money_base::part part; 143 typedef __moneypunct_cache<_CharT, _Intl> __cache_type; 144 145 const locale& __loc = __io._M_getloc(); 146 const ctype<_CharT>& __ctype = use_facet
>(__loc); 147 148 __use_cache<__cache_type> __uc; 149 const __cache_type* __lc = __uc(__loc); 150 const char_type* __lit = __lc->_M_atoms; 151 152 // Deduced sign. 153 bool __negative = false; 154 // Sign size. 155 size_type __sign_size = 0; 156 // True if sign is mandatory. 157 const bool __mandatory_sign = (__lc->_M_positive_sign_size 158 && __lc->_M_negative_sign_size); 159 // String of grouping info from thousands_sep plucked from __units. 160 string __grouping_tmp; 161 if (__lc->_M_use_grouping) 162 __grouping_tmp.reserve(32); 163 // Last position before the decimal point. 164 int __last_pos = 0; 165 // Separator positions, then, possibly, fractional digits. 166 int __n = 0; 167 // If input iterator is in a valid state. 168 bool __testvalid = true; 169 // Flag marking when a decimal point is found. 170 bool __testdecfound = false; 171 172 // The tentative returned string is stored here. 173 string __res; 174 __res.reserve(32); 175 176 const char_type* __lit_zero = __lit + money_base::_S_zero; 177 const money_base::pattern __p = __lc->_M_neg_format; 178 for (int __i = 0; __i < 4 && __testvalid; ++__i) 179 { 180 const part __which = static_cast
(__p.field[__i]); 181 switch (__which) 182 { 183 case money_base::symbol: 184 // According to 22.2.6.1.2, p2, symbol is required 185 // if (__io.flags() & ios_base::showbase), otherwise 186 // is optional and consumed only if other characters 187 // are needed to complete the format. 188 if (__io.flags() & ios_base::showbase || __sign_size > 1 189 || __i == 0 190 || (__i == 1 && (__mandatory_sign 191 || (static_cast
(__p.field[0]) 192 == money_base::sign) 193 || (static_cast
(__p.field[2]) 194 == money_base::space))) 195 || (__i == 2 && ((static_cast
(__p.field[3]) 196 == money_base::value) 197 || (__mandatory_sign 198 && (static_cast
(__p.field[3]) 199 == money_base::sign))))) 200 { 201 const size_type __len = __lc->_M_curr_symbol_size; 202 size_type __j = 0; 203 for (; __beg != __end && __j < __len 204 && *__beg == __lc->_M_curr_symbol[__j]; 205 ++__beg, (void)++__j); 206 if (__j != __len 207 && (__j || __io.flags() & ios_base::showbase)) 208 __testvalid = false; 209 } 210 break; 211 case money_base::sign: 212 // Sign might not exist, or be more than one character long. 213 if (__lc->_M_positive_sign_size && __beg != __end 214 && *__beg == __lc->_M_positive_sign[0]) 215 { 216 __sign_size = __lc->_M_positive_sign_size; 217 ++__beg; 218 } 219 else if (__lc->_M_negative_sign_size && __beg != __end 220 && *__beg == __lc->_M_negative_sign[0]) 221 { 222 __negative = true; 223 __sign_size = __lc->_M_negative_sign_size; 224 ++__beg; 225 } 226 else if (__lc->_M_positive_sign_size 227 && !__lc->_M_negative_sign_size) 228 // "... if no sign is detected, the result is given the sign 229 // that corresponds to the source of the empty string" 230 __negative = true; 231 else if (__mandatory_sign) 232 __testvalid = false; 233 break; 234 case money_base::value: 235 // Extract digits, remove and stash away the 236 // grouping of found thousands separators. 237 for (; __beg != __end; ++__beg) 238 { 239 const char_type __c = *__beg; 240 const char_type* __q = __traits_type::find(__lit_zero, 241 10, __c); 242 if (__q != 0) 243 { 244 __res += money_base::_S_atoms[__q - __lit]; 245 ++__n; 246 } 247 else if (__c == __lc->_M_decimal_point 248 && !__testdecfound) 249 { 250 if (__lc->_M_frac_digits <= 0) 251 break; 252 253 __last_pos = __n; 254 __n = 0; 255 __testdecfound = true; 256 } 257 else if (__lc->_M_use_grouping 258 && __c == __lc->_M_thousands_sep 259 && !__testdecfound) 260 { 261 if (__n) 262 { 263 // Mark position for later analysis. 264 __grouping_tmp += static_cast
(__n); 265 __n = 0; 266 } 267 else 268 { 269 __testvalid = false; 270 break; 271 } 272 } 273 else 274 break; 275 } 276 if (__res.empty()) 277 __testvalid = false; 278 break; 279 case money_base::space: 280 // At least one space is required. 281 if (__beg != __end && __ctype.is(ctype_base::space, *__beg)) 282 ++__beg; 283 else 284 __testvalid = false; 285 // fallthrough 286 case money_base::none: 287 // Only if not at the end of the pattern. 288 if (__i != 3) 289 for (; __beg != __end 290 && __ctype.is(ctype_base::space, *__beg); ++__beg); 291 break; 292 } 293 } 294 295 // Need to get the rest of the sign characters, if they exist. 296 if (__sign_size > 1 && __testvalid) 297 { 298 const char_type* __sign = __negative ? __lc->_M_negative_sign 299 : __lc->_M_positive_sign; 300 size_type __i = 1; 301 for (; __beg != __end && __i < __sign_size 302 && *__beg == __sign[__i]; ++__beg, (void)++__i); 303 304 if (__i != __sign_size) 305 __testvalid = false; 306 } 307 308 if (__testvalid) 309 { 310 // Strip leading zeros. 311 if (__res.size() > 1) 312 { 313 const size_type __first = __res.find_first_not_of('0'); 314 const bool __only_zeros = __first == string::npos; 315 if (__first) 316 __res.erase(0, __only_zeros ? __res.size() - 1 : __first); 317 } 318 319 // 22.2.6.1.2, p4 320 if (__negative && __res[0] != '0') 321 __res.insert(__res.begin(), '-'); 322 323 // Test for grouping fidelity. 324 if (__grouping_tmp.size()) 325 { 326 // Add the ending grouping. 327 __grouping_tmp += static_cast
(__testdecfound ? __last_pos 328 : __n); 329 if (!std::__verify_grouping(__lc->_M_grouping, 330 __lc->_M_grouping_size, 331 __grouping_tmp)) 332 __err |= ios_base::failbit; 333 } 334 335 // Iff not enough digits were supplied after the decimal-point. 336 if (__testdecfound && __n != __lc->_M_frac_digits) 337 __testvalid = false; 338 } 339 340 // Iff valid sequence is not recognized. 341 if (!__testvalid) 342 __err |= ios_base::failbit; 343 else 344 __units.swap(__res); 345 346 // Iff no more characters are available. 347 if (__beg == __end) 348 __err |= ios_base::eofbit; 349 return __beg; 350 } 351 352 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ 353 && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__) 354 template
355 _InIter 356 money_get<_CharT, _InIter>:: 357 __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 358 ios_base::iostate& __err, double& __units) const 359 { 360 string __str; 361 __beg = __intl ? _M_extract
(__beg, __end, __io, __err, __str) 362 : _M_extract
(__beg, __end, __io, __err, __str); 363 std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); 364 return __beg; 365 } 366 #endif 367 368 template
369 _InIter 370 money_get<_CharT, _InIter>:: 371 do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 372 ios_base::iostate& __err, long double& __units) const 373 { 374 string __str; 375 __beg = __intl ? _M_extract
(__beg, __end, __io, __err, __str) 376 : _M_extract
(__beg, __end, __io, __err, __str); 377 std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); 378 return __beg; 379 } 380 381 template
382 _InIter 383 money_get<_CharT, _InIter>:: 384 do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 385 ios_base::iostate& __err, string_type& __digits) const 386 { 387 typedef typename string::size_type size_type; 388 389 const locale& __loc = __io._M_getloc(); 390 const ctype<_CharT>& __ctype = use_facet
>(__loc); 391 392 string __str; 393 __beg = __intl ? _M_extract
(__beg, __end, __io, __err, __str) 394 : _M_extract
(__beg, __end, __io, __err, __str); 395 const size_type __len = __str.size(); 396 if (__len) 397 { 398 __digits.resize(__len); 399 __ctype.widen(__str.data(), __str.data() + __len, &__digits[0]); 400 } 401 return __beg; 402 } 403 404 #if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \ 405 && defined __LONG_DOUBLE_IEEE128__ 406 template
407 _InIter 408 money_get<_CharT, _InIter>:: 409 __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 410 ios_base::iostate& __err, __ibm128& __units) const 411 { 412 string __str; 413 __beg = __intl ? _M_extract
(__beg, __end, __io, __err, __str) 414 : _M_extract
(__beg, __end, __io, __err, __str); 415 std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); 416 return __beg; 417 } 418 #endif 419 420 template
421 template
422 _OutIter 423 money_put<_CharT, _OutIter>:: 424 _M_insert(iter_type __s, ios_base& __io, char_type __fill, 425 const string_type& __digits) const 426 { 427 typedef typename string_type::size_type size_type; 428 typedef money_base::part part; 429 typedef __moneypunct_cache<_CharT, _Intl> __cache_type; 430 431 const locale& __loc = __io._M_getloc(); 432 const ctype<_CharT>& __ctype = use_facet
>(__loc); 433 434 __use_cache<__cache_type> __uc; 435 const __cache_type* __lc = __uc(__loc); 436 const char_type* __lit = __lc->_M_atoms; 437 438 // Determine if negative or positive formats are to be used, and 439 // discard leading negative_sign if it is present. 440 const char_type* __beg = __digits.data(); 441 442 money_base::pattern __p; 443 const char_type* __sign; 444 size_type __sign_size; 445 if (!(*__beg == __lit[money_base::_S_minus])) 446 { 447 __p = __lc->_M_pos_format; 448 __sign = __lc->_M_positive_sign; 449 __sign_size = __lc->_M_positive_sign_size; 450 } 451 else 452 { 453 __p = __lc->_M_neg_format; 454 __sign = __lc->_M_negative_sign; 455 __sign_size = __lc->_M_negative_sign_size; 456 if (__digits.size()) 457 ++__beg; 458 } 459 460 // Look for valid numbers in the ctype facet within input digits. 461 size_type __len = __ctype.scan_not(ctype_base::digit, __beg, 462 __beg + __digits.size()) - __beg; 463 if (__len) 464 { 465 // Assume valid input, and attempt to format. 466 // Break down input numbers into base components, as follows: 467 // final_value = grouped units + (decimal point) + (digits) 468 string_type __value; 469 __value.reserve(2 * __len); 470 471 // Add thousands separators to non-decimal digits, per 472 // grouping rules. 473 long __paddec = __len - __lc->_M_frac_digits; 474 if (__paddec > 0) 475 { 476 if (__lc->_M_frac_digits < 0) 477 __paddec = __len; 478 if (__lc->_M_grouping_size) 479 { 480 __value.assign(2 * __paddec, char_type()); 481 _CharT* __vend = 482 std::__add_grouping(&__value[0], __lc->_M_thousands_sep, 483 __lc->_M_grouping, 484 __lc->_M_grouping_size, 485 __beg, __beg + __paddec); 486 __value.erase(__vend - &__value[0]); 487 } 488 else 489 __value.assign(__beg, __paddec); 490 } 491 492 // Deal with decimal point, decimal digits. 493 if (__lc->_M_frac_digits > 0) 494 { 495 __value += __lc->_M_decimal_point; 496 if (__paddec >= 0) 497 __value.append(__beg + __paddec, __lc->_M_frac_digits); 498 else 499 { 500 // Have to pad zeros in the decimal position. 501 __value.append(-__paddec, __lit[money_base::_S_zero]); 502 __value.append(__beg, __len); 503 } 504 } 505 506 // Calculate length of resulting string. 507 const ios_base::fmtflags __f = __io.flags() 508 & ios_base::adjustfield; 509 __len = __value.size() + __sign_size; 510 __len += ((__io.flags() & ios_base::showbase) 511 ? __lc->_M_curr_symbol_size : 0); 512 513 string_type __res; 514 __res.reserve(2 * __len); 515 516 const size_type __width = static_cast
(__io.width()); 517 const bool __testipad = (__f == ios_base::internal 518 && __len < __width); 519 // Fit formatted digits into the required pattern. 520 for (int __i = 0; __i < 4; ++__i) 521 { 522 const part __which = static_cast
(__p.field[__i]); 523 switch (__which) 524 { 525 case money_base::symbol: 526 if (__io.flags() & ios_base::showbase) 527 __res.append(__lc->_M_curr_symbol, 528 __lc->_M_curr_symbol_size); 529 break; 530 case money_base::sign: 531 // Sign might not exist, or be more than one 532 // character long. In that case, add in the rest 533 // below. 534 if (__sign_size) 535 __res += __sign[0]; 536 break; 537 case money_base::value: 538 __res += __value; 539 break; 540 case money_base::space: 541 // At least one space is required, but if internal 542 // formatting is required, an arbitrary number of 543 // fill spaces will be necessary. 544 if (__testipad) 545 __res.append(__width - __len, __fill); 546 else 547 __res += __fill; 548 break; 549 case money_base::none: 550 if (__testipad) 551 __res.append(__width - __len, __fill); 552 break; 553 } 554 } 555 556 // Special case of multi-part sign parts. 557 if (__sign_size > 1) 558 __res.append(__sign + 1, __sign_size - 1); 559 560 // Pad, if still necessary. 561 __len = __res.size(); 562 if (__width > __len) 563 { 564 if (__f == ios_base::left) 565 // After. 566 __res.append(__width - __len, __fill); 567 else 568 // Before. 569 __res.insert(0, __width - __len, __fill); 570 __len = __width; 571 } 572 573 // Write resulting, fully-formatted string to output iterator. 574 __s = std::__write(__s, __res.data(), __len); 575 } 576 __io.width(0); 577 return __s; 578 } 579 580 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ 581 && (_GLIBCXX_USE_CXX11_ABI == 0 || defined __LONG_DOUBLE_IEEE128__) 582 template
583 _OutIter 584 money_put<_CharT, _OutIter>:: 585 __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 586 double __units) const 587 { return this->do_put(__s, __intl, __io, __fill, (long double) __units); } 588 #endif 589 590 template
591 _OutIter 592 money_put<_CharT, _OutIter>:: 593 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 594 long double __units) const 595 { 596 const locale __loc = __io.getloc(); 597 const ctype<_CharT>& __ctype = use_facet
>(__loc); 598 #if _GLIBCXX_USE_C99_STDIO 599 // First try a buffer perhaps big enough. 600 int __cs_size = 64; 601 char* __cs = static_cast
(__builtin_alloca(__cs_size)); 602 // _GLIBCXX_RESOLVE_LIB_DEFECTS 603 // 328. Bad sprintf format modifier in money_put<>::do_put() 604 int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, 605 "%.*Lf", 0, __units); 606 // If the buffer was not large enough, try again with the correct size. 607 if (__len >= __cs_size) 608 { 609 __cs_size = __len + 1; 610 __cs = static_cast
(__builtin_alloca(__cs_size)); 611 __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, 612 "%.*Lf", 0, __units); 613 } 614 #else 615 // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. 616 const int __cs_size = 617 __gnu_cxx::__numeric_traits
::__max_exponent10 + 3; 618 char* __cs = static_cast
(__builtin_alloca(__cs_size)); 619 int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf", 620 0, __units); 621 #endif 622 string_type __digits(__len, char_type()); 623 __ctype.widen(__cs, __cs + __len, &__digits[0]); 624 return __intl ? _M_insert
(__s, __io, __fill, __digits) 625 : _M_insert
(__s, __io, __fill, __digits); 626 } 627 628 template
629 _OutIter 630 money_put<_CharT, _OutIter>:: 631 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 632 const string_type& __digits) const 633 { return __intl ? _M_insert
(__s, __io, __fill, __digits) 634 : _M_insert
(__s, __io, __fill, __digits); } 635 636 #if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \ 637 && defined __LONG_DOUBLE_IEEE128__ 638 extern "C" 639 __typeof__(__builtin_snprintf) __glibcxx_snprintfibm128 __asm__("snprintf"); 640 641 template
642 _OutIter 643 money_put<_CharT, _OutIter>:: 644 __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 645 __ibm128 __units) const 646 { 647 const locale __loc = __io.getloc(); 648 const ctype<_CharT>& __ctype = use_facet
>(__loc); 649 // First try a buffer perhaps big enough. 650 int __cs_size = 64; 651 char* __cs = static_cast
(__builtin_alloca(__cs_size)); 652 const __c_locale __old = __gnu_cxx::__uselocale(_S_get_c_locale()); 653 654 // _GLIBCXX_RESOLVE_LIB_DEFECTS 655 // 328. Bad sprintf format modifier in money_put<>::do_put() 656 int __len = __glibcxx_snprintfibm128(__cs, __cs_size, "%.*Lf", 0, 657 __units); 658 // If the buffer was not large enough, try again with the correct size. 659 if (__len >= __cs_size) 660 { 661 __cs_size = __len + 1; 662 __cs = static_cast
(__builtin_alloca(__cs_size)); 663 __len = __glibcxx_snprintfibm128(__cs, __cs_size, "%.*Lf", 0, 664 __units); 665 } 666 __gnu_cxx::__uselocale(__old); 667 string_type __digits(__len, char_type()); 668 __ctype.widen(__cs, __cs + __len, &__digits[0]); 669 return __intl ? _M_insert
(__s, __io, __fill, __digits) 670 : _M_insert
(__s, __io, __fill, __digits); 671 } 672 #endif 673 674 _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 675 676 // NB: Not especially useful. Without an ios_base object or some 677 // kind of locale reference, we are left clawing at the air where 678 // the side of the mountain used to be... 679 template
680 time_base::dateorder 681 time_get<_CharT, _InIter>::do_date_order() const 682 { return time_base::no_order; } 683 684 // Expand a strptime format string and parse it. E.g., do_get_date() may 685 // pass %m/%d/%Y => extracted characters. 686 template
687 _InIter 688 time_get<_CharT, _InIter>:: 689 _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, 690 ios_base::iostate& __err, tm* __tm, 691 const _CharT* __format, 692 __time_get_state &__state) const 693 { 694 const locale& __loc = __io._M_getloc(); 695 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 696 const ctype<_CharT>& __ctype = use_facet
>(__loc); 697 const size_t __len = char_traits<_CharT>::length(__format); 698 699 ios_base::iostate __tmperr = ios_base::goodbit; 700 size_t __i = 0; 701 for (; __beg != __end && __i < __len && !__tmperr; ++__i) 702 { 703 if (__ctype.narrow(__format[__i], 0) == '%') 704 { 705 // Verify valid formatting code, attempt to extract. 706 char __c = __ctype.narrow(__format[++__i], 0); 707 int __mem = 0; 708 if (__c == 'E' || __c == 'O') 709 __c = __ctype.narrow(__format[++__i], 0); 710 switch (__c) 711 { 712 const char* __cs; 713 _CharT __wcs[10]; 714 case 'a': 715 case 'A': 716 // Weekday name (possibly abbreviated) [tm_wday] 717 const char_type* __days[14]; 718 __tp._M_days(&__days[0]); 719 __tp._M_days_abbreviated(&__days[7]); 720 __beg = _M_extract_name(__beg, __end, __mem, __days, 721 14, __io, __tmperr); 722 if (!__tmperr) 723 { 724 __tm->tm_wday = __mem % 7; 725 __state._M_have_wday = 1; 726 } 727 break; 728 case 'h': 729 case 'b': 730 case 'B': 731 // Month name (possibly abbreviated) [tm_mon] 732 const char_type* __months[24]; 733 __tp._M_months(&__months[0]); 734 __tp._M_months_abbreviated(&__months[12]); 735 __beg = _M_extract_name(__beg, __end, __mem, 736 __months, 24, __io, __tmperr); 737 if (!__tmperr) 738 { 739 __tm->tm_mon = __mem % 12; 740 __state._M_have_mon = 1; 741 __state._M_want_xday = 1; 742 } 743 break; 744 case 'c': 745 // Default time and date representation. 746 const char_type* __dt[2]; 747 __tp._M_date_time_formats(__dt); 748 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 749 __tm, __dt[0], __state); 750 if (!__tmperr) 751 __state._M_want_xday = 1; 752 break; 753 case 'C': 754 // Century. 755 __beg = _M_extract_num(__beg, __end, __mem, 0, 99, 2, 756 __io, __tmperr); 757 if (!__tmperr) 758 { 759 __state._M_century = __mem; 760 __state._M_have_century = 1; 761 __state._M_want_xday = 1; 762 } 763 break; 764 case 'd': 765 case 'e': 766 // Day [1, 31]. [tm_mday] 767 if (__ctype.is(ctype_base::space, *__beg)) 768 ++__beg; 769 __beg = _M_extract_num(__beg, __end, __mem, 1, 31, 2, 770 __io, __tmperr); 771 if (!__tmperr) 772 { 773 __tm->tm_mday = __mem; 774 __state._M_have_mday = 1; 775 __state._M_want_xday = 1; 776 } 777 break; 778 case 'D': 779 // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] 780 __cs = "%m/%d/%y"; 781 __ctype.widen(__cs, __cs + 9, __wcs); 782 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 783 __tm, __wcs, __state); 784 if (!__tmperr) 785 __state._M_want_xday = 1; 786 break; 787 case 'H': 788 // Hour [00, 23]. [tm_hour] 789 __beg = _M_extract_num(__beg, __end, __mem, 0, 23, 2, 790 __io, __tmperr); 791 if (!__tmperr) 792 { 793 __tm->tm_hour = __mem; 794 __state._M_have_I = 0; 795 } 796 break; 797 case 'I': 798 // Hour [01, 12]. [tm_hour] 799 __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, 800 __io, __tmperr); 801 if (!__tmperr) 802 { 803 __tm->tm_hour = __mem % 12; 804 __state._M_have_I = 1; 805 } 806 break; 807 case 'j': 808 // Day number of year. 809 __beg = _M_extract_num(__beg, __end, __mem, 1, 366, 3, 810 __io, __tmperr); 811 if (!__tmperr) 812 { 813 __tm->tm_yday = __mem - 1; 814 __state._M_have_yday = 1; 815 } 816 break; 817 case 'm': 818 // Month [01, 12]. [tm_mon] 819 __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, 820 __io, __tmperr); 821 if (!__tmperr) 822 { 823 __tm->tm_mon = __mem - 1; 824 __state._M_have_mon = 1; 825 } 826 break; 827 case 'M': 828 // Minute [00, 59]. [tm_min] 829 __beg = _M_extract_num(__beg, __end, __mem, 0, 59, 2, 830 __io, __tmperr); 831 if (!__tmperr) 832 __tm->tm_min = __mem; 833 break; 834 case 'n': 835 case 't': 836 while (__beg != __end 837 && __ctype.is(ctype_base::space, *__beg)) 838 ++__beg; 839 break; 840 case 'p': 841 // Locale's a.m. or p.m. 842 const char_type* __ampm[2]; 843 __tp._M_am_pm(&__ampm[0]); 844 if (!__ampm[0][0] || !__ampm[1][0]) 845 break; 846 __beg = _M_extract_name(__beg, __end, __mem, __ampm, 847 2, __io, __tmperr); 848 if (!__tmperr && __mem) 849 __state._M_is_pm = 1; 850 break; 851 case 'r': 852 // Locale's 12-hour clock time format (in C %I:%M:%S %p). 853 const char_type* __ampm_format; 854 __tp._M_am_pm_format(&__ampm_format); 855 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 856 __tm, __ampm_format, __state); 857 break; 858 case 'R': 859 // Equivalent to (%H:%M). 860 __cs = "%H:%M"; 861 __ctype.widen(__cs, __cs + 6, __wcs); 862 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 863 __tm, __wcs, __state); 864 break; 865 case 'S': 866 // Seconds. [tm_sec] 867 // [00, 60] in C99 (one leap-second), [00, 61] in C89. 868 #if _GLIBCXX_USE_C99 869 __beg = _M_extract_num(__beg, __end, __mem, 0, 60, 2, 870 #else 871 __beg = _M_extract_num(__beg, __end, __mem, 0, 61, 2, 872 #endif 873 __io, __tmperr); 874 if (!__tmperr) 875 __tm->tm_sec = __mem; 876 break; 877 case 'T': 878 // Equivalent to (%H:%M:%S). 879 __cs = "%H:%M:%S"; 880 __ctype.widen(__cs, __cs + 9, __wcs); 881 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 882 __tm, __wcs, __state); 883 break; 884 case 'U': 885 // Week number of the year (Sunday as first day of week). 886 __beg = _M_extract_num(__beg, __end, __mem, 0, 53, 2, 887 __io, __tmperr); 888 if (!__tmperr) 889 { 890 __state._M_week_no = __mem; 891 __state._M_have_uweek = 1; 892 } 893 break; 894 case 'w': 895 // Weekday [tm_wday] 896 __beg = _M_extract_num(__beg, __end, __mem, 0, 6, 1, 897 __io, __tmperr); 898 if (!__tmperr) 899 { 900 __tm->tm_wday = __mem; 901 __state._M_have_wday = 1; 902 } 903 break; 904 case 'W': 905 // Week number of the year (Monday as first day of week). 906 __beg = _M_extract_num(__beg, __end, __mem, 0, 53, 2, 907 __io, __tmperr); 908 if (!__tmperr) 909 { 910 __state._M_week_no = __mem; 911 __state._M_have_wweek = 1; 912 } 913 break; 914 case 'x': 915 // Locale's date. 916 const char_type* __dates[2]; 917 __tp._M_date_formats(__dates); 918 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 919 __tm, __dates[0], __state); 920 break; 921 case 'X': 922 // Locale's time. 923 const char_type* __times[2]; 924 __tp._M_time_formats(__times); 925 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 926 __tm, __times[0], __state); 927 break; 928 case 'y': 929 // The last 2 digits of year. 930 __beg = _M_extract_num(__beg, __end, __mem, 0, 99, 2, 931 __io, __tmperr); 932 if (!__tmperr) 933 { 934 __state._M_want_century = 1; 935 __state._M_want_xday = 1; 936 // As an extension, if the 2 digits are followed by 937 // 1-2 further digits, treat it like %Y. 938 __c = 0; 939 if (__beg != __end) 940 __c = __ctype.narrow(*__beg, '*'); 941 if (__c >= '0' && __c <= '9') 942 { 943 ++__beg; 944 __mem = __mem * 10 + (__c - '0'); 945 if (__beg != __end) 946 { 947 __c = __ctype.narrow(*__beg, '*'); 948 if (__c >= '0' && __c <= '9') 949 { 950 ++__beg; 951 __mem = __mem * 10 + (__c - '0'); 952 } 953 } 954 __mem -= 1900; 955 __state._M_want_century = 0; 956 } 957 // Otherwise, as per POSIX 2008, 00-68 is 2000-2068, 958 // while 69-99 is 1969-1999. 959 else if (__mem < 69) 960 __mem += 100; 961 __tm->tm_year = __mem; 962 } 963 break; 964 case 'Y': 965 // Year. 966 __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4, 967 __io, __tmperr); 968 if (!__tmperr) 969 { 970 __tm->tm_year = __mem - 1900; 971 __state._M_want_century = 0; 972 __state._M_want_xday = 1; 973 } 974 break; 975 case 'Z': 976 // Timezone info. 977 if (__ctype.is(ctype_base::upper, *__beg)) 978 { 979 int __tmp; 980 __beg = _M_extract_name(__beg, __end, __tmp, 981 __timepunct_cache<_CharT>::_S_timezones, 982 14, __io, __tmperr); 983 984 // GMT requires special effort. 985 if (__beg != __end && !__tmperr && __tmp == 0 986 && (*__beg == __ctype.widen('-') 987 || *__beg == __ctype.widen('+'))) 988 { 989 __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2, 990 __io, __tmperr); 991 __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2, 992 __io, __tmperr); 993 } 994 } 995 else 996 __tmperr |= ios_base::failbit; 997 break; 998 case '%': 999 if (*__beg == __ctype.widen('%')) 1000 ++__beg; 1001 else 1002 __tmperr |= ios_base::failbit; 1003 break; 1004 default: 1005 // Not recognized. 1006 __tmperr |= ios_base::failbit; 1007 } 1008 } 1009 else if (__ctype.is(ctype_base::space, __format[__i])) 1010 { 1011 // Skip any whitespace. 1012 while (__beg != __end 1013 && __ctype.is(ctype_base::space, *__beg)) 1014 ++__beg; 1015 } 1016 else 1017 { 1018 // Verify format and input match, extract and discard. 1019 // TODO real case-insensitive comparison 1020 if (__ctype.tolower(__format[__i]) == __ctype.tolower(*__beg) 1021 || __ctype.toupper(__format[__i]) == __ctype.toupper(*__beg)) 1022 ++__beg; 1023 else 1024 __tmperr |= ios_base::failbit; 1025 } 1026 } 1027 1028 if (__tmperr || __i != __len) 1029 __err |= ios_base::failbit; 1030 1031 return __beg; 1032 } 1033 1034 template
1035 _InIter 1036 time_get<_CharT, _InIter>:: 1037 _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, 1038 ios_base::iostate& __err, tm* __tm, 1039 const _CharT* __format) const 1040 { 1041 __time_get_state __state = __time_get_state(); 1042 return _M_extract_via_format(__beg, __end, __io, __err, __tm, 1043 __format, __state); 1044 } 1045 1046 template
1047 _InIter 1048 time_get<_CharT, _InIter>:: 1049 _M_extract_num(iter_type __beg, iter_type __end, int& __member, 1050 int __min, int __max, size_t __len, 1051 ios_base& __io, ios_base::iostate& __err) const 1052 { 1053 const locale& __loc = __io._M_getloc(); 1054 const ctype<_CharT>& __ctype = use_facet
>(__loc); 1055 1056 size_t __i = 0; 1057 int __value = 0; 1058 for (; __beg != __end && __i < __len; ++__beg, (void)++__i) 1059 { 1060 const char __c = __ctype.narrow(*__beg, '*'); 1061 if (__c >= '0' && __c <= '9') 1062 { 1063 __value = __value * 10 + (__c - '0'); 1064 if (__value > __max) 1065 break; 1066 } 1067 else 1068 break; 1069 } 1070 if (__i && __value >= __min && __value <= __max) 1071 __member = __value; 1072 else 1073 __err |= ios_base::failbit; 1074 1075 return __beg; 1076 } 1077 1078 // Assumptions: 1079 // All elements in __names are unique, except if __indexlen is 1080 // even __names in the first half could be the same as corresponding 1081 // __names in the second half (May is abbreviated as May). Some __names 1082 // elements could be prefixes of other __names elements. 1083 template
1084 _InIter 1085 time_get<_CharT, _InIter>:: 1086 _M_extract_name(iter_type __beg, iter_type __end, int& __member, 1087 const _CharT** __names, size_t __indexlen, 1088 ios_base& __io, ios_base::iostate& __err) const 1089 { 1090 typedef char_traits<_CharT> __traits_type; 1091 const locale& __loc = __io._M_getloc(); 1092 const ctype<_CharT>& __ctype = use_facet
>(__loc); 1093 1094 size_t* __matches 1095 = static_cast
(__builtin_alloca(2 * sizeof(size_t) 1096 * __indexlen)); 1097 size_t* __lengths = __matches + __indexlen; 1098 size_t __nmatches = 0; 1099 size_t __pos = 0; 1100 bool __testvalid = true; 1101 const char_type* __name; 1102 bool __begupdated = false; 1103 1104 // Look for initial matches. 1105 if (__beg != __end) 1106 { 1107 const char_type __c = *__beg; 1108 // TODO real case-insensitive comparison 1109 const char_type __cl = __ctype.tolower(__c); 1110 const char_type __cu = __ctype.toupper(__c); 1111 for (size_t __i1 = 0; __i1 < __indexlen; ++__i1) 1112 if (__cl == __ctype.tolower(__names[__i1][0]) 1113 || __cu == __ctype.toupper(__names[__i1][0])) 1114 { 1115 __lengths[__nmatches] 1116 = __traits_type::length(__names[__i1]); 1117 __matches[__nmatches++] = __i1; 1118 } 1119 } 1120 1121 while (__nmatches > 1) 1122 { 1123 // Find smallest matching string. 1124 size_t __minlen = __lengths[0]; 1125 for (size_t __i2 = 1; __i2 < __nmatches; ++__i2) 1126 __minlen = std::min(__minlen, __lengths[__i2]); 1127 ++__pos; 1128 ++__beg; 1129 if (__pos == __minlen) 1130 { 1131 // If some match has remaining length of 0, 1132 // need to decide if any match with remaining 1133 // length non-zero matches the next character. 1134 // If so, remove all matches with remaining length 1135 // 0 from consideration, otherwise keep only matches 1136 // with remaining length 0. 1137 bool __match_longer = false; 1138 1139 if (__beg != __end) 1140 { 1141 // TODO real case-insensitive comparison 1142 const char_type __cl = __ctype.tolower(*__beg); 1143 const char_type __cu = __ctype.toupper(*__beg); 1144 for (size_t __i3 = 0; __i3 < __nmatches; ++__i3) 1145 { 1146 __name = __names[__matches[__i3]]; 1147 if (__lengths[__i3] > __pos 1148 && (__ctype.tolower(__name[__pos]) == __cl 1149 || __ctype.toupper(__name[__pos]) == __cu)) 1150 { 1151 __match_longer = true; 1152 break; 1153 } 1154 } 1155 } 1156 for (size_t __i4 = 0; __i4 < __nmatches;) 1157 if (__match_longer == (__lengths[__i4] == __pos)) 1158 { 1159 __matches[__i4] = __matches[--__nmatches]; 1160 __lengths[__i4] = __lengths[__nmatches]; 1161 } 1162 else 1163 ++__i4; 1164 if (__match_longer) 1165 { 1166 __minlen = __lengths[0]; 1167 for (size_t __i5 = 1; __i5 < __nmatches; ++__i5) 1168 __minlen = std::min(__minlen, __lengths[__i5]); 1169 } 1170 else 1171 { 1172 // Deal with May being full as well as abbreviated month 1173 // name. Pick the smaller index. 1174 if (__nmatches == 2 && (__indexlen & 1) == 0) 1175 { 1176 if (__matches[0] < __indexlen / 2) 1177 { 1178 if (__matches[1] == __matches[0] + __indexlen / 2) 1179 __nmatches = 1; 1180 } 1181 else if (__matches[1] == __matches[0] - __indexlen / 2) 1182 { 1183 __matches[0] = __matches[1]; 1184 __lengths[0] = __lengths[1]; 1185 __nmatches = 1; 1186 } 1187 } 1188 __begupdated = true; 1189 break; 1190 } 1191 } 1192 if (__pos < __minlen && __beg != __end) 1193 { 1194 // TODO real case-insensitive comparison 1195 const char_type __cl = __ctype.tolower(*__beg); 1196 const char_type __cu = __ctype.toupper(*__beg); 1197 for (size_t __i6 = 0; __i6 < __nmatches;) 1198 { 1199 __name = __names[__matches[__i6]]; 1200 if (__ctype.tolower(__name[__pos]) != __cl 1201 && __ctype.toupper(__name[__pos]) != __cu) 1202 { 1203 __matches[__i6] = __matches[--__nmatches]; 1204 __lengths[__i6] = __lengths[__nmatches]; 1205 } 1206 else 1207 ++__i6; 1208 } 1209 } 1210 else 1211 break; 1212 } 1213 1214 if (__nmatches == 1) 1215 { 1216 // Make sure found name is completely extracted. 1217 if (!__begupdated) 1218 { 1219 ++__beg; 1220 ++__pos; 1221 } 1222 __name = __names[__matches[0]]; 1223 const size_t __len = __lengths[0]; 1224 while (__pos < __len 1225 && __beg != __end 1226 // TODO real case-insensitive comparison 1227 && (__ctype.tolower(__name[__pos]) == __ctype.tolower(*__beg) 1228 || (__ctype.toupper(__name[__pos]) 1229 == __ctype.toupper(*__beg)))) 1230 ++__beg, (void)++__pos; 1231 1232 if (__len == __pos) 1233 __member = __matches[0]; 1234 else 1235 __testvalid = false; 1236 } 1237 else 1238 __testvalid = false; 1239 if (!__testvalid) 1240 __err |= ios_base::failbit; 1241 1242 return __beg; 1243 } 1244 1245 template
1246 _InIter 1247 time_get<_CharT, _InIter>:: 1248 _M_extract_wday_or_month(iter_type __beg, iter_type __end, int& __member, 1249 const _CharT** __names, size_t __indexlen, 1250 ios_base& __io, ios_base::iostate& __err) const 1251 { 1252 typedef char_traits<_CharT> __traits_type; 1253 const locale& __loc = __io._M_getloc(); 1254 const ctype<_CharT>& __ctype = use_facet
>(__loc); 1255 1256 int* __matches = static_cast
(__builtin_alloca(2 * sizeof(int) 1257 * __indexlen)); 1258 size_t __nmatches = 0; 1259 size_t* __matches_lengths = 0; 1260 size_t __pos = 0; 1261 1262 if (__beg != __end) 1263 { 1264 const char_type __c = *__beg; 1265 for (size_t __i = 0; __i < 2 * __indexlen; ++__i) 1266 if (__c == __names[__i][0] 1267 || __c == __ctype.toupper(__names[__i][0])) 1268 __matches[__nmatches++] = __i; 1269 } 1270 1271 if (__nmatches) 1272 { 1273 ++__beg; 1274 ++__pos; 1275 1276 __matches_lengths 1277 = static_cast
(__builtin_alloca(sizeof(size_t) 1278 * __nmatches)); 1279 for (size_t __i = 0; __i < __nmatches; ++__i) 1280 __matches_lengths[__i] 1281 = __traits_type::length(__names[__matches[__i]]); 1282 } 1283 1284 for (; __beg != __end; ++__beg, (void)++__pos) 1285 { 1286 size_t __nskipped = 0; 1287 const char_type __c = *__beg; 1288 for (size_t __i = 0; __i < __nmatches;) 1289 { 1290 const char_type* __name = __names[__matches[__i]]; 1291 if (__pos >= __matches_lengths[__i]) 1292 ++__nskipped, ++__i; 1293 else if (!(__name[__pos] == __c)) 1294 { 1295 --__nmatches; 1296 __matches[__i] = __matches[__nmatches]; 1297 __matches_lengths[__i] = __matches_lengths[__nmatches]; 1298 } 1299 else 1300 ++__i; 1301 } 1302 if (__nskipped == __nmatches) 1303 break; 1304 } 1305 1306 if ((__nmatches == 1 && __matches_lengths[0] == __pos) 1307 || (__nmatches == 2 && (__matches_lengths[0] == __pos 1308 || __matches_lengths[1] == __pos))) 1309 __member = (__matches[0] >= (int)__indexlen 1310 ? __matches[0] - (int)__indexlen : __matches[0]); 1311 else 1312 __err |= ios_base::failbit; 1313 1314 return __beg; 1315 } 1316 1317 template
1318 _InIter 1319 time_get<_CharT, _InIter>:: 1320 do_get_time(iter_type __beg, iter_type __end, ios_base& __io, 1321 ios_base::iostate& __err, tm* __tm) const 1322 { 1323 const locale& __loc = __io._M_getloc(); 1324 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 1325 const char_type* __times[2]; 1326 __tp._M_time_formats(__times); 1327 __time_get_state __state = __time_get_state(); 1328 __beg = _M_extract_via_format(__beg, __end, __io, __err, 1329 __tm, __times[0], __state); 1330 __state._M_finalize_state(__tm); 1331 if (__beg == __end) 1332 __err |= ios_base::eofbit; 1333 return __beg; 1334 } 1335 1336 template
1337 _InIter 1338 time_get<_CharT, _InIter>:: 1339 do_get_date(iter_type __beg, iter_type __end, ios_base& __io, 1340 ios_base::iostate& __err, tm* __tm) const 1341 { 1342 const locale& __loc = __io._M_getloc(); 1343 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 1344 const char_type* __dates[2]; 1345 __tp._M_date_formats(__dates); 1346 __time_get_state __state = __time_get_state(); 1347 __beg = _M_extract_via_format(__beg, __end, __io, __err, 1348 __tm, __dates[0], __state); 1349 __state._M_finalize_state(__tm); 1350 if (__beg == __end) 1351 __err |= ios_base::eofbit; 1352 return __beg; 1353 } 1354 1355 template
1356 _InIter 1357 time_get<_CharT, _InIter>:: 1358 do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, 1359 ios_base::iostate& __err, tm* __tm) const 1360 { 1361 const locale& __loc = __io._M_getloc(); 1362 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 1363 const char_type* __days[14]; 1364 __tp._M_days_abbreviated(__days); 1365 __tp._M_days(__days + 7); 1366 int __tmpwday; 1367 ios_base::iostate __tmperr = ios_base::goodbit; 1368 1369 __beg = _M_extract_wday_or_month(__beg, __end, __tmpwday, __days, 7, 1370 __io, __tmperr); 1371 if (!__tmperr) 1372 __tm->tm_wday = __tmpwday; 1373 else 1374 __err |= ios_base::failbit; 1375 1376 if (__beg == __end) 1377 __err |= ios_base::eofbit; 1378 return __beg; 1379 } 1380 1381 template
1382 _InIter 1383 time_get<_CharT, _InIter>:: 1384 do_get_monthname(iter_type __beg, iter_type __end, 1385 ios_base& __io, ios_base::iostate& __err, tm* __tm) const 1386 { 1387 const locale& __loc = __io._M_getloc(); 1388 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 1389 const char_type* __months[24]; 1390 __tp._M_months_abbreviated(__months); 1391 __tp._M_months(__months + 12); 1392 int __tmpmon; 1393 ios_base::iostate __tmperr = ios_base::goodbit; 1394 1395 __beg = _M_extract_wday_or_month(__beg, __end, __tmpmon, __months, 12, 1396 __io, __tmperr); 1397 if (!__tmperr) 1398 __tm->tm_mon = __tmpmon; 1399 else 1400 __err |= ios_base::failbit; 1401 1402 if (__beg == __end) 1403 __err |= ios_base::eofbit; 1404 return __beg; 1405 } 1406 1407 template
1408 _InIter 1409 time_get<_CharT, _InIter>:: 1410 do_get_year(iter_type __beg, iter_type __end, ios_base& __io, 1411 ios_base::iostate& __err, tm* __tm) const 1412 { 1413 int __tmpyear; 1414 ios_base::iostate __tmperr = ios_base::goodbit; 1415 const locale& __loc = __io._M_getloc(); 1416 const ctype<_CharT>& __ctype = use_facet
>(__loc); 1417 1418 __beg = _M_extract_num(__beg, __end, __tmpyear, 0, 99, 2, 1419 __io, __tmperr); 1420 if (!__tmperr) 1421 { 1422 char __c = 0; 1423 if (__beg != __end) 1424 __c = __ctype.narrow(*__beg, '*'); 1425 // For 1-2 digit year, assume 69-99 is 1969-1999, 0-68 is 2000-2068. 1426 // For 3-4 digit year, use it as year. 1427 // __tm->tm_year needs year - 1900 though. 1428 if (__c >= '0' && __c <= '9') 1429 { 1430 ++__beg; 1431 __tmpyear = __tmpyear * 10 + (__c - '0'); 1432 if (__beg != __end) 1433 { 1434 __c = __ctype.narrow(*__beg, '*'); 1435 if (__c >= '0' && __c <= '9') 1436 { 1437 ++__beg; 1438 __tmpyear = __tmpyear * 10 + (__c - '0'); 1439 } 1440 } 1441 __tmpyear -= 1900; 1442 } 1443 else if (__tmpyear < 69) 1444 __tmpyear += 100; 1445 __tm->tm_year = __tmpyear; 1446 } 1447 else 1448 __err |= ios_base::failbit; 1449 1450 if (__beg == __end) 1451 __err |= ios_base::eofbit; 1452 return __beg; 1453 } 1454 1455 #if __cplusplus >= 201103L 1456 template
1457 inline 1458 _InIter 1459 time_get<_CharT, _InIter>:: 1460 get(iter_type __s, iter_type __end, ios_base& __io, 1461 ios_base::iostate& __err, tm* __tm, const char_type* __fmt, 1462 const char_type* __fmtend) const 1463 { 1464 const locale& __loc = __io._M_getloc(); 1465 ctype<_CharT> const& __ctype = use_facet
>(__loc); 1466 __err = ios_base::goodbit; 1467 bool __use_state = false; 1468 #if __GNUC__ >= 5 && !defined(__clang__) 1469 #pragma GCC diagnostic push 1470 #pragma GCC diagnostic ignored "-Wpmf-conversions" 1471 // Nasty hack. The C++ standard mandates that get invokes the do_get 1472 // virtual method, but unfortunately at least without an ABI change 1473 // for the facets we can't keep state across the different do_get 1474 // calls. So e.g. if __fmt is "%p %I:%M:%S", we can't handle it 1475 // properly, because we first handle the %p am/pm specifier and only 1476 // later the 12-hour format specifier. 1477 if ((void*)(this->*(&time_get::do_get)) == (void*)(&time_get::do_get)) 1478 __use_state = true; 1479 #pragma GCC diagnostic pop 1480 #endif 1481 __time_get_state __state = __time_get_state(); 1482 while (__fmt != __fmtend && 1483 __err == ios_base::goodbit) 1484 { 1485 if (__s == __end) 1486 { 1487 __err = ios_base::eofbit | ios_base::failbit; 1488 break; 1489 } 1490 else if (__ctype.narrow(*__fmt, 0) == '%') 1491 { 1492 const char_type* __fmt_start = __fmt; 1493 char __format; 1494 char __mod = 0; 1495 if (++__fmt == __fmtend) 1496 { 1497 __err = ios_base::failbit; 1498 break; 1499 } 1500 const char __c = __ctype.narrow(*__fmt, 0); 1501 if (__c != 'E' && __c != 'O') 1502 __format = __c; 1503 else if (++__fmt != __fmtend) 1504 { 1505 __mod = __c; 1506 __format = __ctype.narrow(*__fmt, 0); 1507 } 1508 else 1509 { 1510 __err = ios_base::failbit; 1511 break; 1512 } 1513 if (__use_state) 1514 { 1515 char_type __new_fmt[4]; 1516 __new_fmt[0] = __fmt_start[0]; 1517 __new_fmt[1] = __fmt_start[1]; 1518 if (__mod) 1519 { 1520 __new_fmt[2] = __fmt_start[2]; 1521 __new_fmt[3] = char_type(); 1522 } 1523 else 1524 __new_fmt[2] = char_type(); 1525 __s = _M_extract_via_format(__s, __end, __io, __err, __tm, 1526 __new_fmt, __state); 1527 if (__s == __end) 1528 __err |= ios_base::eofbit; 1529 } 1530 else 1531 __s = this->do_get(__s, __end, __io, __err, __tm, __format, 1532 __mod); 1533 ++__fmt; 1534 } 1535 else if (__ctype.is(ctype_base::space, *__fmt)) 1536 { 1537 ++__fmt; 1538 while (__fmt != __fmtend && 1539 __ctype.is(ctype_base::space, *__fmt)) 1540 ++__fmt; 1541 1542 while (__s != __end && 1543 __ctype.is(ctype_base::space, *__s)) 1544 ++__s; 1545 } 1546 // TODO real case-insensitive comparison 1547 else if (__ctype.tolower(*__s) == __ctype.tolower(*__fmt) || 1548 __ctype.toupper(*__s) == __ctype.toupper(*__fmt)) 1549 { 1550 ++__s; 1551 ++__fmt; 1552 } 1553 else 1554 { 1555 __err = ios_base::failbit; 1556 break; 1557 } 1558 } 1559 if (__use_state) 1560 __state._M_finalize_state(__tm); 1561 return __s; 1562 } 1563 1564 template
1565 inline 1566 _InIter 1567 time_get<_CharT, _InIter>:: 1568 do_get(iter_type __beg, iter_type __end, ios_base& __io, 1569 ios_base::iostate& __err, tm* __tm, 1570 char __format, char __mod) const 1571 { 1572 const locale& __loc = __io._M_getloc(); 1573 ctype<_CharT> const& __ctype = use_facet
>(__loc); 1574 __err = ios_base::goodbit; 1575 1576 char_type __fmt[4]; 1577 __fmt[0] = __ctype.widen('%'); 1578 if (!__mod) 1579 { 1580 __fmt[1] = __format; 1581 __fmt[2] = char_type(); 1582 } 1583 else 1584 { 1585 __fmt[1] = __mod; 1586 __fmt[2] = __format; 1587 __fmt[3] = char_type(); 1588 } 1589 1590 __time_get_state __state = __time_get_state(); 1591 __beg = _M_extract_via_format(__beg, __end, __io, __err, __tm, __fmt, 1592 __state); 1593 __state._M_finalize_state(__tm); 1594 if (__beg == __end) 1595 __err |= ios_base::eofbit; 1596 return __beg; 1597 } 1598 1599 #endif // __cplusplus >= 201103L 1600 1601 template
1602 _OutIter 1603 time_put<_CharT, _OutIter>:: 1604 put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, 1605 const _CharT* __beg, const _CharT* __end) const 1606 { 1607 const locale& __loc = __io._M_getloc(); 1608 ctype<_CharT> const& __ctype = use_facet
>(__loc); 1609 for (; __beg != __end; ++__beg) 1610 if (__ctype.narrow(*__beg, 0) != '%') 1611 { 1612 *__s = *__beg; 1613 ++__s; 1614 } 1615 else if (++__beg != __end) 1616 { 1617 char __format; 1618 char __mod = 0; 1619 const char __c = __ctype.narrow(*__beg, 0); 1620 if (__c != 'E' && __c != 'O') 1621 __format = __c; 1622 else if (++__beg != __end) 1623 { 1624 __mod = __c; 1625 __format = __ctype.narrow(*__beg, 0); 1626 } 1627 else 1628 break; 1629 __s = this->do_put(__s, __io, __fill, __tm, __format, __mod); 1630 } 1631 else 1632 break; 1633 return __s; 1634 } 1635 1636 template
1637 _OutIter 1638 time_put<_CharT, _OutIter>:: 1639 do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, 1640 char __format, char __mod) const 1641 { 1642 const locale& __loc = __io._M_getloc(); 1643 ctype<_CharT> const& __ctype = use_facet
>(__loc); 1644 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); 1645 1646 // NB: This size is arbitrary. Should this be a data member, 1647 // initialized at construction? 1648 const size_t __maxlen = 128; 1649 char_type __res[__maxlen]; 1650 1651 // NB: In IEE 1003.1-200x, and perhaps other locale models, it 1652 // is possible that the format character will be longer than one 1653 // character. Possibilities include 'E' or 'O' followed by a 1654 // format character: if __mod is not the default argument, assume 1655 // it's a valid modifier. 1656 char_type __fmt[4]; 1657 __fmt[0] = __ctype.widen('%'); 1658 if (!__mod) 1659 { 1660 __fmt[1] = __format; 1661 __fmt[2] = char_type(); 1662 } 1663 else 1664 { 1665 __fmt[1] = __mod; 1666 __fmt[2] = __format; 1667 __fmt[3] = char_type(); 1668 } 1669 1670 __tp._M_put(__res, __maxlen, __fmt, __tm); 1671 1672 // Write resulting, fully-formatted string to output iterator. 1673 return std::__write(__s, __res, char_traits
::length(__res)); 1674 } 1675 1676 1677 // Inhibit implicit instantiations for required instantiations, 1678 // which are defined via explicit instantiations elsewhere. 1679 #if _GLIBCXX_EXTERN_TEMPLATE 1680 extern template class moneypunct
; 1681 extern template class moneypunct
; 1682 extern template class moneypunct_byname
; 1683 extern template class moneypunct_byname
; 1684 extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_get
; 1685 extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_put
; 1686 extern template class __timepunct
; 1687 extern template class time_put
; 1688 extern template class time_put_byname
; 1689 extern template class time_get
; 1690 extern template class time_get_byname
; 1691 extern template class messages
; 1692 extern template class messages_byname
; 1693 1694 extern template 1695 const moneypunct
* 1696 __try_use_facet
>(const locale&) _GLIBCXX_NOTHROW; 1697 1698 extern template 1699 const moneypunct
* 1700 __try_use_facet
>(const locale&) _GLIBCXX_NOTHROW; 1701 1702 extern template 1703 const money_put
* 1704 __try_use_facet
>(const locale&) _GLIBCXX_NOTHROW; 1705 1706 extern template 1707 const money_get
* 1708 __try_use_facet
>(const locale&) _GLIBCXX_NOTHROW; 1709 1710 extern template 1711 const __timepunct
* 1712 __try_use_facet<__timepunct
>(const locale&) _GLIBCXX_NOTHROW; 1713 1714 extern template 1715 const time_put
* 1716 __try_use_facet
>(const locale&) _GLIBCXX_NOTHROW; 1717 1718 extern template 1719 const time_get
* 1720 __try_use_facet
>(const locale&) _GLIBCXX_NOTHROW; 1721 1722 extern template 1723 const messages
* 1724 __try_use_facet
>(const locale&) _GLIBCXX_NOTHROW; 1725 1726 extern template 1727 const moneypunct
& 1728 use_facet
>(const locale&); 1729 1730 extern template 1731 const moneypunct
& 1732 use_facet
>(const locale&); 1733 1734 extern template 1735 const money_put
& 1736 use_facet
>(const locale&); 1737 1738 extern template 1739 const money_get
& 1740 use_facet
>(const locale&); 1741 1742 extern template 1743 const __timepunct
& 1744 use_facet<__timepunct
>(const locale&); 1745 1746 extern template 1747 const time_put
& 1748 use_facet
>(const locale&); 1749 1750 extern template 1751 const time_get
& 1752 use_facet
>(const locale&); 1753 1754 extern template 1755 const messages
& 1756 use_facet
>(const locale&); 1757 1758 extern template 1759 bool 1760 has_facet
>(const locale&); 1761 1762 extern template 1763 bool 1764 has_facet
>(const locale&); 1765 1766 extern template 1767 bool 1768 has_facet
>(const locale&); 1769 1770 extern template 1771 bool 1772 has_facet<__timepunct
>(const locale&); 1773 1774 extern template 1775 bool 1776 has_facet
>(const locale&); 1777 1778 extern template 1779 bool 1780 has_facet
>(const locale&); 1781 1782 extern template 1783 bool 1784 has_facet
>(const locale&); 1785 1786 #ifdef _GLIBCXX_USE_WCHAR_T 1787 extern template class moneypunct
; 1788 extern template class moneypunct
; 1789 extern template class moneypunct_byname
; 1790 extern template class moneypunct_byname
; 1791 extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_get
; 1792 extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_put
; 1793 extern template class __timepunct
; 1794 extern template class time_put
; 1795 extern template class time_put_byname
; 1796 extern template class time_get
; 1797 extern template class time_get_byname
; 1798 extern template class messages
; 1799 extern template class messages_byname
; 1800 1801 extern template 1802 const moneypunct
* 1803 __try_use_facet
>(const locale&) _GLIBCXX_NOTHROW; 1804 1805 extern template 1806 const moneypunct
* 1807 __try_use_facet
>(const locale&) _GLIBCXX_NOTHROW; 1808 1809 extern template 1810 const money_put
* 1811 __try_use_facet
>(const locale&) _GLIBCXX_NOTHROW; 1812 1813 extern template 1814 const money_get
* 1815 __try_use_facet
>(const locale&) _GLIBCXX_NOTHROW; 1816 1817 extern template 1818 const __timepunct
* 1819 __try_use_facet<__timepunct
>(const locale&) _GLIBCXX_NOTHROW; 1820 1821 extern template 1822 const time_put
* 1823 __try_use_facet
>(const locale&) _GLIBCXX_NOTHROW; 1824 1825 extern template 1826 const time_get
* 1827 __try_use_facet
>(const locale&) _GLIBCXX_NOTHROW; 1828 1829 extern template 1830 const messages
* 1831 __try_use_facet
>(const locale&) _GLIBCXX_NOTHROW; 1832 1833 extern template 1834 const moneypunct
& 1835 use_facet
>(const locale&); 1836 1837 extern template 1838 const moneypunct
& 1839 use_facet
>(const locale&); 1840 1841 extern template 1842 const money_put
& 1843 use_facet
>(const locale&); 1844 1845 extern template 1846 const money_get
& 1847 use_facet
>(const locale&); 1848 1849 extern template 1850 const __timepunct
& 1851 use_facet<__timepunct
>(const locale&); 1852 1853 extern template 1854 const time_put
& 1855 use_facet
>(const locale&); 1856 1857 extern template 1858 const time_get
& 1859 use_facet
>(const locale&); 1860 1861 extern template 1862 const messages
& 1863 use_facet
>(const locale&); 1864 1865 extern template 1866 bool 1867 has_facet
>(const locale&); 1868 1869 extern template 1870 bool 1871 has_facet
>(const locale&); 1872 1873 extern template 1874 bool 1875 has_facet
>(const locale&); 1876 1877 extern template 1878 bool 1879 has_facet<__timepunct
>(const locale&); 1880 1881 extern template 1882 bool 1883 has_facet
>(const locale&); 1884 1885 extern template 1886 bool 1887 has_facet
>(const locale&); 1888 1889 extern template 1890 bool 1891 has_facet
>(const locale&); 1892 #endif 1893 #endif 1894 1895 _GLIBCXX_END_NAMESPACE_VERSION 1896 } // namespace std 1897 1898 #endif
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™