1 // Locale support -*- C++ -*- 2 3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 4 // Free Software Foundation, Inc. 5 // 6 // This file is part of the GNU ISO C++ Library. This library is free 7 // software; you can redistribute it and/or modify it under the 8 // terms of the GNU General Public License as published by the 9 // Free Software Foundation; either version 2, or (at your option) 10 // any later version. 11 12 // This library is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU General Public License for more details. 16 17 // You should have received a copy of the GNU General Public License along 18 // with this library; see the file COPYING. If not, write to the Free 19 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 20 // USA. 21 22 // As a special exception, you may use this file as part of a free software 23 // library without restriction. Specifically, if other files instantiate 24 // templates or use macros or inline functions from this file, or you compile 25 // this file and link it with other files to produce an executable, this 26 // file does not by itself cause the resulting executable to be covered by 27 // the GNU General Public License. This exception does not however 28 // invalidate any other reasons why the executable file might be covered by 29 // the GNU General Public License. 30 31 /** @file locale_facets.tcc 32 * This is an internal header file, included by other library headers. 33 * You should not attempt to use it directly. 34 */ 35 36 #ifndef _LOCALE_FACETS_TCC 37 #define _LOCALE_FACETS_TCC 1 38 39 #pragma GCC system_header 40 41 #include <limits> // For numeric_limits 42 #include <typeinfo> // For bad_cast. 43 #include <bits/streambuf_iterator.h> 44 #include <ext/type_traits.h> 45 46 _GLIBCXX_BEGIN_NAMESPACE(std) 47 48 template<typename _Facet> 49 locale 50 locale::combine(const locale& __other) const 51 { 52 _Impl* __tmp = new _Impl(*_M_impl, 1); 53 try 54 { 55 __tmp->_M_replace_facet(__other._M_impl, &_Facet::id); 56 } 57 catch(...) 58 { 59 __tmp->_M_remove_reference(); 60 __throw_exception_again; 61 } 62 return locale(__tmp); 63 } 64 65 template<typename _CharT, typename _Traits, typename _Alloc> 66 bool 67 locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1, 68 const basic_string<_CharT, _Traits, _Alloc>& __s2) const 69 { 70 typedef std::collate<_CharT> __collate_type; 71 const __collate_type& __collate = use_facet<__collate_type>(*this); 72 return (__collate.compare(__s1.data(), __s1.data() + __s1.length(), 73 __s2.data(), __s2.data() + __s2.length()) < 0); 74 } 75 76 /** 77 * @brief Test for the presence of a facet. 78 * 79 * has_facet tests the locale argument for the presence of the facet type 80 * provided as the template parameter. Facets derived from the facet 81 * parameter will also return true. 82 * 83 * @param Facet The facet type to test the presence of. 84 * @param locale The locale to test. 85 * @return true if locale contains a facet of type Facet, else false. 86 */ 87 template<typename _Facet> 88 inline bool 89 has_facet(const locale& __loc) throw() 90 { 91 const size_t __i = _Facet::id._M_id(); 92 const locale::facet** __facets = __loc._M_impl->_M_facets; 93 return (__i < __loc._M_impl->_M_facets_size && __facets[__i]); 94 } 95 96 /** 97 * @brief Return a facet. 98 * 99 * use_facet looks for and returns a reference to a facet of type Facet 100 * where Facet is the template parameter. If has_facet(locale) is true, 101 * there is a suitable facet to return. It throws std::bad_cast if the 102 * locale doesn't contain a facet of type Facet. 103 * 104 * @param Facet The facet type to access. 105 * @param locale The locale to use. 106 * @return Reference to facet of type Facet. 107 * @throw std::bad_cast if locale doesn't contain a facet of type Facet. 108 */ 109 template<typename _Facet> 110 inline const _Facet& 111 use_facet(const locale& __loc) 112 { 113 const size_t __i = _Facet::id._M_id(); 114 const locale::facet** __facets = __loc._M_impl->_M_facets; 115 if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i])) 116 __throw_bad_cast(); 117 return static_cast<const _Facet&>(*__facets[__i]); 118 } 119 120 // Routine to access a cache for the facet. If the cache didn't 121 // exist before, it gets constructed on the fly. 122 template<typename _Facet> 123 struct __use_cache 124 { 125 const _Facet* 126 operator() (const locale& __loc) const; 127 }; 128 129 // Specializations. 130 template<typename _CharT> 131 struct __use_cache<__numpunct_cache<_CharT> > 132 { 133 const __numpunct_cache<_CharT>* 134 operator() (const locale& __loc) const 135 { 136 const size_t __i = numpunct<_CharT>::id._M_id(); 137 const locale::facet** __caches = __loc._M_impl->_M_caches; 138 if (!__caches[__i]) 139 { 140 __numpunct_cache<_CharT>* __tmp = NULL; 141 try 142 { 143 __tmp = new __numpunct_cache<_CharT>; 144 __tmp->_M_cache(__loc); 145 } 146 catch(...) 147 { 148 delete __tmp; 149 __throw_exception_again; 150 } 151 __loc._M_impl->_M_install_cache(__tmp, __i); 152 } 153 return static_cast<const __numpunct_cache<_CharT>*>(__caches[__i]); 154 } 155 }; 156 157 template<typename _CharT, bool _Intl> 158 struct __use_cache<__moneypunct_cache<_CharT, _Intl> > 159 { 160 const __moneypunct_cache<_CharT, _Intl>* 161 operator() (const locale& __loc) const 162 { 163 const size_t __i = moneypunct<_CharT, _Intl>::id._M_id(); 164 const locale::facet** __caches = __loc._M_impl->_M_caches; 165 if (!__caches[__i]) 166 { 167 __moneypunct_cache<_CharT, _Intl>* __tmp = NULL; 168 try 169 { 170 __tmp = new __moneypunct_cache<_CharT, _Intl>; 171 __tmp->_M_cache(__loc); 172 } 173 catch(...) 174 { 175 delete __tmp; 176 __throw_exception_again; 177 } 178 __loc._M_impl->_M_install_cache(__tmp, __i); 179 } 180 return static_cast< 181 const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]); 182 } 183 }; 184 185 template<typename _CharT> 186 void 187 __numpunct_cache<_CharT>::_M_cache(const locale& __loc) 188 { 189 _M_allocated = true; 190 191 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 192 193 _M_grouping_size = __np.grouping().size(); 194 char* __grouping = new char[_M_grouping_size]; 195 __np.grouping().copy(__grouping, _M_grouping_size); 196 _M_grouping = __grouping; 197 _M_use_grouping = (_M_grouping_size 198 && static_cast<signed char>(__np.grouping()[0]) > 0); 199 200 _M_truename_size = __np.truename().size(); 201 _CharT* __truename = new _CharT[_M_truename_size]; 202 __np.truename().copy(__truename, _M_truename_size); 203 _M_truename = __truename; 204 205 _M_falsename_size = __np.falsename().size(); 206 _CharT* __falsename = new _CharT[_M_falsename_size]; 207 __np.falsename().copy(__falsename, _M_falsename_size); 208 _M_falsename = __falsename; 209 210 _M_decimal_point = __np.decimal_point(); 211 _M_thousands_sep = __np.thousands_sep(); 212 213 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc); 214 __ct.widen(__num_base::_S_atoms_out, 215 __num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out); 216 __ct.widen(__num_base::_S_atoms_in, 217 __num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in); 218 } 219 220 template<typename _CharT, bool _Intl> 221 void 222 __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc) 223 { 224 _M_allocated = true; 225 226 const moneypunct<_CharT, _Intl>& __mp = 227 use_facet<moneypunct<_CharT, _Intl> >(__loc); 228 229 _M_grouping_size = __mp.grouping().size(); 230 char* __grouping = new char[_M_grouping_size]; 231 __mp.grouping().copy(__grouping, _M_grouping_size); 232 _M_grouping = __grouping; 233 _M_use_grouping = (_M_grouping_size 234 && static_cast<signed char>(__mp.grouping()[0]) > 0); 235 236 _M_decimal_point = __mp.decimal_point(); 237 _M_thousands_sep = __mp.thousands_sep(); 238 _M_frac_digits = __mp.frac_digits(); 239 240 _M_curr_symbol_size = __mp.curr_symbol().size(); 241 _CharT* __curr_symbol = new _CharT[_M_curr_symbol_size]; 242 __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size); 243 _M_curr_symbol = __curr_symbol; 244 245 _M_positive_sign_size = __mp.positive_sign().size(); 246 _CharT* __positive_sign = new _CharT[_M_positive_sign_size]; 247 __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size); 248 _M_positive_sign = __positive_sign; 249 250 _M_negative_sign_size = __mp.negative_sign().size(); 251 _CharT* __negative_sign = new _CharT[_M_negative_sign_size]; 252 __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size); 253 _M_negative_sign = __negative_sign; 254 255 _M_pos_format = __mp.pos_format(); 256 _M_neg_format = __mp.neg_format(); 257 258 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc); 259 __ct.widen(money_base::_S_atoms, 260 money_base::_S_atoms + money_base::_S_end, _M_atoms); 261 } 262 263 264 // Used by both numeric and monetary facets. 265 // Check to make sure that the __grouping_tmp string constructed in 266 // money_get or num_get matches the canonical grouping for a given 267 // locale. 268 // __grouping_tmp is parsed L to R 269 // 1,222,444 == __grouping_tmp of "\1\3\3" 270 // __grouping is parsed R to L 271 // 1,222,444 == __grouping of "\3" == "\3\3\3" 272 static bool 273 __verify_grouping(const char* __grouping, size_t __grouping_size, 274 const string& __grouping_tmp); 275 276 _GLIBCXX_BEGIN_LDBL_NAMESPACE 277 278 template<typename _CharT, typename _InIter> 279 _InIter 280 num_get<_CharT, _InIter>:: 281 _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io, 282 ios_base::iostate& __err, string& __xtrc) const 283 { 284 typedef char_traits<_CharT> __traits_type; 285 typedef __numpunct_cache<_CharT> __cache_type; 286 __use_cache<__cache_type> __uc; 287 const locale& __loc = __io._M_getloc(); 288 const __cache_type* __lc = __uc(__loc); 289 const _CharT* __lit = __lc->_M_atoms_in; 290 char_type __c = char_type(); 291 292 // True if __beg becomes equal to __end. 293 bool __testeof = __beg == __end; 294 295 // First check for sign. 296 if (!__testeof) 297 { 298 __c = *__beg; 299 const bool __plus = __c == __lit[__num_base::_S_iplus]; 300 if ((__plus || __c == __lit[__num_base::_S_iminus]) 301 && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) 302 && !(__c == __lc->_M_decimal_point)) 303 { 304 __xtrc += __plus ? '+' : '-'; 305 if (++__beg != __end) 306 __c = *__beg; 307 else 308 __testeof = true; 309 } 310 } 311 312 // Next, look for leading zeros. 313 bool __found_mantissa = false; 314 int __sep_pos = 0; 315 while (!__testeof) 316 { 317 if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep 318 || __c == __lc->_M_decimal_point) 319 break; 320 else if (__c == __lit[__num_base::_S_izero]) 321 { 322 if (!__found_mantissa) 323 { 324 __xtrc += '0'; 325 __found_mantissa = true; 326 } 327 ++__sep_pos; 328 329 if (++__beg != __end) 330 __c = *__beg; 331 else 332 __testeof = true; 333 } 334 else 335 break; 336 } 337 338 // Only need acceptable digits for floating point numbers. 339 bool __found_dec = false; 340 bool __found_sci = false; 341 string __found_grouping; 342 if (__lc->_M_use_grouping) 343 __found_grouping.reserve(32); 344 const char_type* __lit_zero = __lit + __num_base::_S_izero; 345 346 if (!__lc->_M_allocated) 347 // "C" locale 348 while (!__testeof) 349 { 350 const int __digit = _M_find(__lit_zero, 10, __c); 351 if (__digit != -1) 352 { 353 __xtrc += '0' + __digit; 354 __found_mantissa = true; 355 } 356 else if (__c == __lc->_M_decimal_point 357 && !__found_dec && !__found_sci) 358 { 359 __xtrc += '.'; 360 __found_dec = true; 361 } 362 else if ((__c == __lit[__num_base::_S_ie] 363 || __c == __lit[__num_base::_S_iE]) 364 && !__found_sci && __found_mantissa) 365 { 366 // Scientific notation. 367 __xtrc += 'e'; 368 __found_sci = true; 369 370 // Remove optional plus or minus sign, if they exist. 371 if (++__beg != __end) 372 { 373 __c = *__beg; 374 const bool __plus = __c == __lit[__num_base::_S_iplus]; 375 if (__plus || __c == __lit[__num_base::_S_iminus]) 376 __xtrc += __plus ? '+' : '-'; 377 else 378 continue; 379 } 380 else 381 { 382 __testeof = true; 383 break; 384 } 385 } 386 else 387 break; 388 389 if (++__beg != __end) 390 __c = *__beg; 391 else 392 __testeof = true; 393 } 394 else 395 while (!__testeof) 396 { 397 // According to 22.2.2.1.2, p8-9, first look for thousands_sep 398 // and decimal_point. 399 if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) 400 { 401 if (!__found_dec && !__found_sci) 402 { 403 // NB: Thousands separator at the beginning of a string 404 // is a no-no, as is two consecutive thousands separators. 405 if (__sep_pos) 406 { 407 __found_grouping += static_cast<char>(__sep_pos); 408 __sep_pos = 0; 409 } 410 else 411 { 412 // NB: __convert_to_v will not assign __v and will 413 // set the failbit. 414 __xtrc.clear(); 415 break; 416 } 417 } 418 else 419 break; 420 } 421 else if (__c == __lc->_M_decimal_point) 422 { 423 if (!__found_dec && !__found_sci) 424 { 425 // If no grouping chars are seen, no grouping check 426 // is applied. Therefore __found_grouping is adjusted 427 // only if decimal_point comes after some thousands_sep. 428 if (__found_grouping.size()) 429 __found_grouping += static_cast<char>(__sep_pos); 430 __xtrc += '.'; 431 __found_dec = true; 432 } 433 else 434 break; 435 } 436 else 437 { 438 const char_type* __q = 439 __traits_type::find(__lit_zero, 10, __c); 440 if (__q) 441 { 442 __xtrc += '0' + (__q - __lit_zero); 443 __found_mantissa = true; 444 ++__sep_pos; 445 } 446 else if ((__c == __lit[__num_base::_S_ie] 447 || __c == __lit[__num_base::_S_iE]) 448 && !__found_sci && __found_mantissa) 449 { 450 // Scientific notation. 451 if (__found_grouping.size() && !__found_dec) 452 __found_grouping += static_cast<char>(__sep_pos); 453 __xtrc += 'e'; 454 __found_sci = true; 455 456 // Remove optional plus or minus sign, if they exist. 457 if (++__beg != __end) 458 { 459 __c = *__beg; 460 const bool __plus = __c == __lit[__num_base::_S_iplus]; 461 if ((__plus || __c == __lit[__num_base::_S_iminus]) 462 && !(__lc->_M_use_grouping 463 && __c == __lc->_M_thousands_sep) 464 && !(__c == __lc->_M_decimal_point)) 465 __xtrc += __plus ? '+' : '-'; 466 else 467 continue; 468 } 469 else 470 { 471 __testeof = true; 472 break; 473 } 474 } 475 else 476 break; 477 } 478 479 if (++__beg != __end) 480 __c = *__beg; 481 else 482 __testeof = true; 483 } 484 485 // Digit grouping is checked. If grouping and found_grouping don't 486 // match, then get very very upset, and set failbit. 487 if (__found_grouping.size()) 488 { 489 // Add the ending grouping if a decimal or 'e'/'E' wasn't found. 490 if (!__found_dec && !__found_sci) 491 __found_grouping += static_cast<char>(__sep_pos); 492 493 if (!std::__verify_grouping(__lc->_M_grouping, 494 __lc->_M_grouping_size, 495 __found_grouping)) 496 __err |= ios_base::failbit; 497 } 498 499 // Finish up. 500 if (__testeof) 501 __err |= ios_base::eofbit; 502 return __beg; 503 } 504 505 _GLIBCXX_END_LDBL_NAMESPACE 506 507 _GLIBCXX_BEGIN_LDBL_NAMESPACE 508 509 template<typename _CharT, typename _InIter> 510 template<typename _ValueT> 511 _InIter 512 num_get<_CharT, _InIter>:: 513 _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io, 514 ios_base::iostate& __err, _ValueT& __v) const 515 { 516 typedef char_traits<_CharT> __traits_type; 517 using __gnu_cxx::__add_unsigned; 518 typedef typename __add_unsigned<_ValueT>::__type __unsigned_type; 519 typedef __numpunct_cache<_CharT> __cache_type; 520 __use_cache<__cache_type> __uc; 521 const locale& __loc = __io._M_getloc(); 522 const __cache_type* __lc = __uc(__loc); 523 const _CharT* __lit = __lc->_M_atoms_in; 524 char_type __c = char_type(); 525 526 // NB: Iff __basefield == 0, __base can change based on contents. 527 const ios_base::fmtflags __basefield = __io.flags() 528 & ios_base::basefield; 529 const bool __oct = __basefield == ios_base::oct; 530 int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10); 531 532 // True if __beg becomes equal to __end. 533 bool __testeof = __beg == __end; 534 535 // First check for sign. 536 bool __negative = false; 537 if (!__testeof) 538 { 539 __c = *__beg; 540 if (numeric_limits<_ValueT>::is_signed) 541 __negative = __c == __lit[__num_base::_S_iminus]; 542 if ((__negative || __c == __lit[__num_base::_S_iplus]) 543 && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) 544 && !(__c == __lc->_M_decimal_point)) 545 { 546 if (++__beg != __end) 547 __c = *__beg; 548 else 549 __testeof = true; 550 } 551 } 552 553 // Next, look for leading zeros and check required digits 554 // for base formats. 555 bool __found_zero = false; 556 int __sep_pos = 0; 557 while (!__testeof) 558 { 559 if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep 560 || __c == __lc->_M_decimal_point) 561 break; 562 else if (__c == __lit[__num_base::_S_izero] 563 && (!__found_zero || __base == 10)) 564 { 565 __found_zero = true; 566 ++__sep_pos; 567 if (__basefield == 0) 568 __base = 8; 569 if (__base == 8) 570 __sep_pos = 0; 571 } 572 else if (__found_zero 573 && (__c == __lit[__num_base::_S_ix] 574 || __c == __lit[__num_base::_S_iX])) 575 { 576 if (__basefield == 0) 577 __base = 16; 578 if (__base == 16) 579 { 580 __found_zero = false; 581 __sep_pos = 0; 582 } 583 else 584 break; 585 } 586 else 587 break; 588 589 if (++__beg != __end) 590 { 591 __c = *__beg; 592 if (!__found_zero) 593 break; 594 } 595 else 596 __testeof = true; 597 } 598 599 // At this point, base is determined. If not hex, only allow 600 // base digits as valid input. 601 const size_t __len = (__base == 16 ? __num_base::_S_iend 602 - __num_base::_S_izero : __base); 603 604 // Extract. 605 string __found_grouping; 606 if (__lc->_M_use_grouping) 607 __found_grouping.reserve(32); 608 bool __testfail = false; 609 const __unsigned_type __max = __negative ? 610 -numeric_limits<_ValueT>::min() : numeric_limits<_ValueT>::max(); 611 const __unsigned_type __smax = __max / __base; 612 __unsigned_type __result = 0; 613 int __digit = 0; 614 const char_type* __lit_zero = __lit + __num_base::_S_izero; 615 616 if (!__lc->_M_allocated) 617 // "C" locale 618 while (!__testeof) 619 { 620 __digit = _M_find(__lit_zero, __len, __c); 621 if (__digit == -1) 622 break; 623 624 if (__result > __smax) 625 __testfail = true; 626 else 627 { 628 __result *= __base; 629 __testfail |= __result > __max - __digit; 630 __result += __digit; 631 ++__sep_pos; 632 } 633 634 if (++__beg != __end) 635 __c = *__beg; 636 else 637 __testeof = true; 638 } 639 else 640 while (!__testeof) 641 { 642 // According to 22.2.2.1.2, p8-9, first look for thousands_sep 643 // and decimal_point. 644 if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) 645 { 646 // NB: Thousands separator at the beginning of a string 647 // is a no-no, as is two consecutive thousands separators. 648 if (__sep_pos) 649 { 650 __found_grouping += static_cast<char>(__sep_pos); 651 __sep_pos = 0; 652 } 653 else 654 { 655 __testfail = true; 656 break; 657 } 658 } 659 else if (__c == __lc->_M_decimal_point) 660 break; 661 else 662 { 663 const char_type* __q = 664 __traits_type::find(__lit_zero, __len, __c); 665 if (!__q) 666 break; 667 668 __digit = __q - __lit_zero; 669 if (__digit > 15) 670 __digit -= 6; 671 if (__result > __smax) 672 __testfail = true; 673 else 674 { 675 __result *= __base; 676 __testfail |= __result > __max - __digit; 677 __result += __digit; 678 ++__sep_pos; 679 } 680 } 681 682 if (++__beg != __end) 683 __c = *__beg; 684 else 685 __testeof = true; 686 } 687 688 // Digit grouping is checked. If grouping and found_grouping don't 689 // match, then get very very upset, and set failbit. 690 if (__found_grouping.size()) 691 { 692 // Add the ending grouping. 693 __found_grouping += static_cast<char>(__sep_pos); 694 695 if (!std::__verify_grouping(__lc->_M_grouping, 696 __lc->_M_grouping_size, 697 __found_grouping)) 698 __err |= ios_base::failbit; 699 } 700 701 if (!__testfail && (__sep_pos || __found_zero 702 || __found_grouping.size())) 703 __v = __negative ? -__result : __result; 704 else 705 __err |= ios_base::failbit; 706 707 if (__testeof) 708 __err |= ios_base::eofbit; 709 return __beg; 710 } 711 712 // _GLIBCXX_RESOLVE_LIB_DEFECTS 713 // 17. Bad bool parsing 714 template<typename _CharT, typename _InIter> 715 _InIter 716 num_get<_CharT, _InIter>:: 717 do_get(iter_type __beg, iter_type __end, ios_base& __io, 718 ios_base::iostate& __err, bool& __v) const 719 { 720 if (!(__io.flags() & ios_base::boolalpha)) 721 { 722 // Parse bool values as long. 723 // NB: We can't just call do_get(long) here, as it might 724 // refer to a derived class. 725 long __l = -1; 726 __beg = _M_extract_int(__beg, __end, __io, __err, __l); 727 if (__l == 0 || __l == 1) 728 __v = __l; 729 else 730 __err |= ios_base::failbit; 731 } 732 else 733 { 734 // Parse bool values as alphanumeric. 735 typedef __numpunct_cache<_CharT> __cache_type; 736 __use_cache<__cache_type> __uc; 737 const locale& __loc = __io._M_getloc(); 738 const __cache_type* __lc = __uc(__loc); 739 740 bool __testf = true; 741 bool __testt = true; 742 size_t __n; 743 bool __testeof = __beg == __end; 744 for (__n = 0; !__testeof; ++__n) 745 { 746 const char_type __c = *__beg; 747 748 if (__testf) 749 if (__n < __lc->_M_falsename_size) 750 __testf = __c == __lc->_M_falsename[__n]; 751 else 752 break; 753 754 if (__testt) 755 if (__n < __lc->_M_truename_size) 756 __testt = __c == __lc->_M_truename[__n]; 757 else 758 break; 759 760 if (!__testf && !__testt) 761 break; 762 763 if (++__beg == __end) 764 __testeof = true; 765 } 766 if (__testf && __n == __lc->_M_falsename_size) 767 __v = 0; 768 else if (__testt && __n == __lc->_M_truename_size) 769 __v = 1; 770 else 771 __err |= ios_base::failbit; 772 773 if (__testeof) 774 __err |= ios_base::eofbit; 775 } 776 return __beg; 777 } 778 779 template<typename _CharT, typename _InIter> 780 _InIter 781 num_get<_CharT, _InIter>:: 782 do_get(iter_type __beg, iter_type __end, ios_base& __io, 783 ios_base::iostate& __err, long& __v) const 784 { return _M_extract_int(__beg, __end, __io, __err, __v); } 785 786 template<typename _CharT, typename _InIter> 787 _InIter 788 num_get<_CharT, _InIter>:: 789 do_get(iter_type __beg, iter_type __end, ios_base& __io, 790 ios_base::iostate& __err, unsigned short& __v) const 791 { return _M_extract_int(__beg, __end, __io, __err, __v); } 792 793 template<typename _CharT, typename _InIter> 794 _InIter 795 num_get<_CharT, _InIter>:: 796 do_get(iter_type __beg, iter_type __end, ios_base& __io, 797 ios_base::iostate& __err, unsigned int& __v) const 798 { return _M_extract_int(__beg, __end, __io, __err, __v); } 799 800 template<typename _CharT, typename _InIter> 801 _InIter 802 num_get<_CharT, _InIter>:: 803 do_get(iter_type __beg, iter_type __end, ios_base& __io, 804 ios_base::iostate& __err, unsigned long& __v) const 805 { return _M_extract_int(__beg, __end, __io, __err, __v); } 806 807 #ifdef _GLIBCXX_USE_LONG_LONG 808 template<typename _CharT, typename _InIter> 809 _InIter 810 num_get<_CharT, _InIter>:: 811 do_get(iter_type __beg, iter_type __end, ios_base& __io, 812 ios_base::iostate& __err, long long& __v) const 813 { return _M_extract_int(__beg, __end, __io, __err, __v); } 814 815 template<typename _CharT, typename _InIter> 816 _InIter 817 num_get<_CharT, _InIter>:: 818 do_get(iter_type __beg, iter_type __end, ios_base& __io, 819 ios_base::iostate& __err, unsigned long long& __v) const 820 { return _M_extract_int(__beg, __end, __io, __err, __v); } 821 #endif 822 823 template<typename _CharT, typename _InIter> 824 _InIter 825 num_get<_CharT, _InIter>:: 826 do_get(iter_type __beg, iter_type __end, ios_base& __io, 827 ios_base::iostate& __err, float& __v) const 828 { 829 string __xtrc; 830 __xtrc.reserve(32); 831 __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); 832 std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); 833 return __beg; 834 } 835 836 template<typename _CharT, typename _InIter> 837 _InIter 838 num_get<_CharT, _InIter>:: 839 do_get(iter_type __beg, iter_type __end, ios_base& __io, 840 ios_base::iostate& __err, double& __v) const 841 { 842 string __xtrc; 843 __xtrc.reserve(32); 844 __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); 845 std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); 846 return __beg; 847 } 848 849 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 850 template<typename _CharT, typename _InIter> 851 _InIter 852 num_get<_CharT, _InIter>:: 853 __do_get(iter_type __beg, iter_type __end, ios_base& __io, 854 ios_base::iostate& __err, double& __v) const 855 { 856 string __xtrc; 857 __xtrc.reserve(32); 858 __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); 859 std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); 860 return __beg; 861 } 862 #endif 863 864 template<typename _CharT, typename _InIter> 865 _InIter 866 num_get<_CharT, _InIter>:: 867 do_get(iter_type __beg, iter_type __end, ios_base& __io, 868 ios_base::iostate& __err, long double& __v) const 869 { 870 string __xtrc; 871 __xtrc.reserve(32); 872 __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); 873 std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); 874 return __beg; 875 } 876 877 template<typename _CharT, typename _InIter> 878 _InIter 879 num_get<_CharT, _InIter>:: 880 do_get(iter_type __beg, iter_type __end, ios_base& __io, 881 ios_base::iostate& __err, void*& __v) const 882 { 883 // Prepare for hex formatted input. 884 typedef ios_base::fmtflags fmtflags; 885 const fmtflags __fmt = __io.flags(); 886 __io.flags(__fmt & ~ios_base::basefield | ios_base::hex); 887 888 unsigned long __ul; 889 __beg = _M_extract_int(__beg, __end, __io, __err, __ul); 890 891 // Reset from hex formatted input. 892 __io.flags(__fmt); 893 894 if (!(__err & ios_base::failbit)) 895 __v = reinterpret_cast<void*>(__ul); 896 return __beg; 897 } 898 899 // For use by integer and floating-point types after they have been 900 // converted into a char_type string. 901 template<typename _CharT, typename _OutIter> 902 void 903 num_put<_CharT, _OutIter>:: 904 _M_pad(_CharT __fill, streamsize __w, ios_base& __io, 905 _CharT* __new, const _CharT* __cs, int& __len) const 906 { 907 // [22.2.2.2.2] Stage 3. 908 // If necessary, pad. 909 __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs, 910 __w, __len, true); 911 __len = static_cast<int>(__w); 912 } 913 914 _GLIBCXX_END_LDBL_NAMESPACE 915 916 template<typename _CharT, typename _ValueT> 917 int 918 __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit, 919 ios_base::fmtflags __flags, bool __dec) 920 { 921 _CharT* __buf = __bufend; 922 if (__builtin_expect(__dec, true)) 923 { 924 // Decimal. 925 do 926 { 927 *--__buf = __lit[(__v % 10) + __num_base::_S_odigits]; 928 __v /= 10; 929 } 930 while (__v != 0); 931 } 932 else if ((__flags & ios_base::basefield) == ios_base::oct) 933 { 934 // Octal. 935 do 936 { 937 *--__buf = __lit[(__v & 0x7) + __num_base::_S_odigits]; 938 __v >>= 3; 939 } 940 while (__v != 0); 941 } 942 else 943 { 944 // Hex. 945 const bool __uppercase = __flags & ios_base::uppercase; 946 const int __case_offset = __uppercase ? __num_base::_S_oudigits 947 : __num_base::_S_odigits; 948 do 949 { 950 *--__buf = __lit[(__v & 0xf) + __case_offset]; 951 __v >>= 4; 952 } 953 while (__v != 0); 954 } 955 return __bufend - __buf; 956 } 957 958 _GLIBCXX_BEGIN_LDBL_NAMESPACE 959 960 template<typename _CharT, typename _OutIter> 961 void 962 num_put<_CharT, _OutIter>:: 963 _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep, 964 ios_base&, _CharT* __new, _CharT* __cs, int& __len) const 965 { 966 _CharT* __p = std::__add_grouping(__new, __sep, __grouping, 967 __grouping_size, __cs, __cs + __len); 968 __len = __p - __new; 969 } 970 971 template<typename _CharT, typename _OutIter> 972 template<typename _ValueT> 973 _OutIter 974 num_put<_CharT, _OutIter>:: 975 _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill, 976 _ValueT __v) const 977 { 978 using __gnu_cxx::__add_unsigned; 979 typedef typename __add_unsigned<_ValueT>::__type __unsigned_type; 980 typedef __numpunct_cache<_CharT> __cache_type; 981 __use_cache<__cache_type> __uc; 982 const locale& __loc = __io._M_getloc(); 983 const __cache_type* __lc = __uc(__loc); 984 const _CharT* __lit = __lc->_M_atoms_out; 985 const ios_base::fmtflags __flags = __io.flags(); 986 987 // Long enough to hold hex, dec, and octal representations. 988 const int __ilen = 5 * sizeof(_ValueT); 989 _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 990 * __ilen)); 991 992 // [22.2.2.2.2] Stage 1, numeric conversion to character. 993 // Result is returned right-justified in the buffer. 994 const ios_base::fmtflags __basefield = __flags & ios_base::basefield; 995 const bool __dec = (__basefield != ios_base::oct 996 && __basefield != ios_base::hex); 997 const __unsigned_type __u = (__v > 0 || !__dec) ? __v : -__v; 998 int __len = __int_to_char(__cs + __ilen, __u, __lit, __flags, __dec); 999 __cs += __ilen - __len; 1000 1001 // Add grouping, if necessary. 1002 if (__lc->_M_use_grouping) 1003 { 1004 // Grouping can add (almost) as many separators as the number 1005 // of digits + space is reserved for numeric base or sign. 1006 _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 1007 * (__len + 1) 1008 * 2)); 1009 _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size, 1010 __lc->_M_thousands_sep, __io, __cs2 + 2, __cs, __len); 1011 __cs = __cs2 + 2; 1012 } 1013 1014 // Complete Stage 1, prepend numeric base or sign. 1015 if (__builtin_expect(__dec, true)) 1016 { 1017 // Decimal. 1018 if (__v >= 0) 1019 { 1020 if (__flags & ios_base::showpos 1021 && numeric_limits<_ValueT>::is_signed) 1022 *--__cs = __lit[__num_base::_S_oplus], ++__len; 1023 } 1024 else 1025 *--__cs = __lit[__num_base::_S_ominus], ++__len; 1026 } 1027 else if (__flags & ios_base::showbase && __v) 1028 { 1029 if (__basefield == ios_base::oct) 1030 *--__cs = __lit[__num_base::_S_odigits], ++__len; 1031 else 1032 { 1033 // 'x' or 'X' 1034 const bool __uppercase = __flags & ios_base::uppercase; 1035 *--__cs = __lit[__num_base::_S_ox + __uppercase]; 1036 // '0' 1037 *--__cs = __lit[__num_base::_S_odigits]; 1038 __len += 2; 1039 } 1040 } 1041 1042 // Pad. 1043 const streamsize __w = __io.width(); 1044 if (__w > static_cast<streamsize>(__len)) 1045 { 1046 _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 1047 * __w)); 1048 _M_pad(__fill, __w, __io, __cs3, __cs, __len); 1049 __cs = __cs3; 1050 } 1051 __io.width(0); 1052 1053 // [22.2.2.2.2] Stage 4. 1054 // Write resulting, fully-formatted string to output iterator. 1055 return std::__write(__s, __cs, __len); 1056 } 1057 1058 template<typename _CharT, typename _OutIter> 1059 void 1060 num_put<_CharT, _OutIter>:: 1061 _M_group_float(const char* __grouping, size_t __grouping_size, 1062 _CharT __sep, const _CharT* __p, _CharT* __new, 1063 _CharT* __cs, int& __len) const 1064 { 1065 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1066 // 282. What types does numpunct grouping refer to? 1067 // Add grouping, if necessary. 1068 const int __declen = __p ? __p - __cs : __len; 1069 _CharT* __p2 = std::__add_grouping(__new, __sep, __grouping, 1070 __grouping_size, 1071 __cs, __cs + __declen); 1072 1073 // Tack on decimal part. 1074 int __newlen = __p2 - __new; 1075 if (__p) 1076 { 1077 char_traits<_CharT>::copy(__p2, __p, __len - __declen); 1078 __newlen += __len - __declen; 1079 } 1080 __len = __newlen; 1081 } 1082 1083 // The following code uses vsnprintf (or vsprintf(), when 1084 // _GLIBCXX_USE_C99 is not defined) to convert floating point values 1085 // for insertion into a stream. An optimization would be to replace 1086 // them with code that works directly on a wide buffer and then use 1087 // __pad to do the padding. It would be good to replace them anyway 1088 // to gain back the efficiency that C++ provides by knowing up front 1089 // the type of the values to insert. Also, sprintf is dangerous 1090 // since may lead to accidental buffer overruns. This 1091 // implementation follows the C++ standard fairly directly as 1092 // outlined in 22.2.2.2 [lib.locale.num.put] 1093 template<typename _CharT, typename _OutIter> 1094 template<typename _ValueT> 1095 _OutIter 1096 num_put<_CharT, _OutIter>:: 1097 _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, 1098 _ValueT __v) const 1099 { 1100 typedef __numpunct_cache<_CharT> __cache_type; 1101 __use_cache<__cache_type> __uc; 1102 const locale& __loc = __io._M_getloc(); 1103 const __cache_type* __lc = __uc(__loc); 1104 1105 // Use default precision if out of range. 1106 const streamsize __prec = __io.precision() < 0 ? 6 : __io.precision(); 1107 1108 const int __max_digits = numeric_limits<_ValueT>::digits10; 1109 1110 // [22.2.2.2.2] Stage 1, numeric conversion to character. 1111 int __len; 1112 // Long enough for the max format spec. 1113 char __fbuf[16]; 1114 __num_base::_S_format_float(__io, __fbuf, __mod); 1115 1116 #ifdef _GLIBCXX_USE_C99 1117 // First try a buffer perhaps big enough (most probably sufficient 1118 // for non-ios_base::fixed outputs) 1119 int __cs_size = __max_digits * 3; 1120 char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 1121 __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, 1122 __fbuf, __prec, __v); 1123 1124 // If the buffer was not large enough, try again with the correct size. 1125 if (__len >= __cs_size) 1126 { 1127 __cs_size = __len + 1; 1128 __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 1129 __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, 1130 __fbuf, __prec, __v); 1131 } 1132 #else 1133 // Consider the possibility of long ios_base::fixed outputs 1134 const bool __fixed = __io.flags() & ios_base::fixed; 1135 const int __max_exp = numeric_limits<_ValueT>::max_exponent10; 1136 1137 // The size of the output string is computed as follows. 1138 // ios_base::fixed outputs may need up to __max_exp + 1 chars 1139 // for the integer part + __prec chars for the fractional part 1140 // + 3 chars for sign, decimal point, '\0'. On the other hand, 1141 // for non-fixed outputs __max_digits * 2 + __prec chars are 1142 // largely sufficient. 1143 const int __cs_size = __fixed ? __max_exp + __prec + 4 1144 : __max_digits * 2 + __prec; 1145 char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 1146 __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, __fbuf, 1147 __prec, __v); 1148 #endif 1149 1150 // [22.2.2.2.2] Stage 2, convert to char_type, using correct 1151 // numpunct.decimal_point() values for '.' and adding grouping. 1152 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 1153 1154 _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 1155 * __len)); 1156 __ctype.widen(__cs, __cs + __len, __ws); 1157 1158 // Replace decimal point. 1159 _CharT* __wp = 0; 1160 const char* __p = char_traits<char>::find(__cs, __len, '.'); 1161 if (__p) 1162 { 1163 __wp = __ws + (__p - __cs); 1164 *__wp = __lc->_M_decimal_point; 1165 } 1166 1167 // Add grouping, if necessary. 1168 // N.B. Make sure to not group things like 2e20, i.e., no decimal 1169 // point, scientific notation. 1170 if (__lc->_M_use_grouping 1171 && (__wp || __len < 3 || (__cs[1] <= '9' && __cs[2] <= '9' 1172 && __cs[1] >= '0' && __cs[2] >= '0'))) 1173 { 1174 // Grouping can add (almost) as many separators as the 1175 // number of digits, but no more. 1176 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 1177 * __len * 2)); 1178 1179 streamsize __off = 0; 1180 if (__cs[0] == '-' || __cs[0] == '+') 1181 { 1182 __off = 1; 1183 __ws2[0] = __ws[0]; 1184 __len -= 1; 1185 } 1186 1187 _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size, 1188 __lc->_M_thousands_sep, __wp, __ws2 + __off, 1189 __ws + __off, __len); 1190 __len += __off; 1191 1192 __ws = __ws2; 1193 } 1194 1195 // Pad. 1196 const streamsize __w = __io.width(); 1197 if (__w > static_cast<streamsize>(__len)) 1198 { 1199 _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 1200 * __w)); 1201 _M_pad(__fill, __w, __io, __ws3, __ws, __len); 1202 __ws = __ws3; 1203 } 1204 __io.width(0); 1205 1206 // [22.2.2.2.2] Stage 4. 1207 // Write resulting, fully-formatted string to output iterator. 1208 return std::__write(__s, __ws, __len); 1209 } 1210 1211 template<typename _CharT, typename _OutIter> 1212 _OutIter 1213 num_put<_CharT, _OutIter>:: 1214 do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const 1215 { 1216 const ios_base::fmtflags __flags = __io.flags(); 1217 if ((__flags & ios_base::boolalpha) == 0) 1218 { 1219 const long __l = __v; 1220 __s = _M_insert_int(__s, __io, __fill, __l); 1221 } 1222 else 1223 { 1224 typedef __numpunct_cache<_CharT> __cache_type; 1225 __use_cache<__cache_type> __uc; 1226 const locale& __loc = __io._M_getloc(); 1227 const __cache_type* __lc = __uc(__loc); 1228 1229 const _CharT* __name = __v ? __lc->_M_truename 1230 : __lc->_M_falsename; 1231 int __len = __v ? __lc->_M_truename_size 1232 : __lc->_M_falsename_size; 1233 1234 const streamsize __w = __io.width(); 1235 if (__w > static_cast<streamsize>(__len)) 1236 { 1237 _CharT* __cs 1238 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 1239 * __w)); 1240 _M_pad(__fill, __w, __io, __cs, __name, __len); 1241 __name = __cs; 1242 } 1243 __io.width(0); 1244 __s = std::__write(__s, __name, __len); 1245 } 1246 return __s; 1247 } 1248 1249 template<typename _CharT, typename _OutIter> 1250 _OutIter 1251 num_put<_CharT, _OutIter>:: 1252 do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const 1253 { return _M_insert_int(__s, __io, __fill, __v); } 1254 1255 template<typename _CharT, typename _OutIter> 1256 _OutIter 1257 num_put<_CharT, _OutIter>:: 1258 do_put(iter_type __s, ios_base& __io, char_type __fill, 1259 unsigned long __v) const 1260 { return _M_insert_int(__s, __io, __fill, __v); } 1261 1262 #ifdef _GLIBCXX_USE_LONG_LONG 1263 template<typename _CharT, typename _OutIter> 1264 _OutIter 1265 num_put<_CharT, _OutIter>:: 1266 do_put(iter_type __s, ios_base& __io, char_type __fill, long long __v) const 1267 { return _M_insert_int(__s, __io, __fill, __v); } 1268 1269 template<typename _CharT, typename _OutIter> 1270 _OutIter 1271 num_put<_CharT, _OutIter>:: 1272 do_put(iter_type __s, ios_base& __io, char_type __fill, 1273 unsigned long long __v) const 1274 { return _M_insert_int(__s, __io, __fill, __v); } 1275 #endif 1276 1277 template<typename _CharT, typename _OutIter> 1278 _OutIter 1279 num_put<_CharT, _OutIter>:: 1280 do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const 1281 { return _M_insert_float(__s, __io, __fill, char(), __v); } 1282 1283 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 1284 template<typename _CharT, typename _OutIter> 1285 _OutIter 1286 num_put<_CharT, _OutIter>:: 1287 __do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const 1288 { return _M_insert_float(__s, __io, __fill, char(), __v); } 1289 #endif 1290 1291 template<typename _CharT, typename _OutIter> 1292 _OutIter 1293 num_put<_CharT, _OutIter>:: 1294 do_put(iter_type __s, ios_base& __io, char_type __fill, 1295 long double __v) const 1296 { return _M_insert_float(__s, __io, __fill, 'L', __v); } 1297 1298 template<typename _CharT, typename _OutIter> 1299 _OutIter 1300 num_put<_CharT, _OutIter>:: 1301 do_put(iter_type __s, ios_base& __io, char_type __fill, 1302 const void* __v) const 1303 { 1304 const ios_base::fmtflags __flags = __io.flags(); 1305 const ios_base::fmtflags __fmt = ~(ios_base::basefield 1306 | ios_base::uppercase 1307 | ios_base::internal); 1308 __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase)); 1309 1310 __s = _M_insert_int(__s, __io, __fill, 1311 reinterpret_cast<unsigned long>(__v)); 1312 __io.flags(__flags); 1313 return __s; 1314 } 1315 1316 template<typename _CharT, typename _InIter> 1317 template<bool _Intl> 1318 _InIter 1319 money_get<_CharT, _InIter>:: 1320 _M_extract(iter_type __beg, iter_type __end, ios_base& __io, 1321 ios_base::iostate& __err, string& __units) const 1322 { 1323 typedef char_traits<_CharT> __traits_type; 1324 typedef typename string_type::size_type size_type; 1325 typedef money_base::part part; 1326 typedef __moneypunct_cache<_CharT, _Intl> __cache_type; 1327 1328 const locale& __loc = __io._M_getloc(); 1329 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 1330 1331 __use_cache<__cache_type> __uc; 1332 const __cache_type* __lc = __uc(__loc); 1333 const char_type* __lit = __lc->_M_atoms; 1334 1335 // Deduced sign. 1336 bool __negative = false; 1337 // Sign size. 1338 size_type __sign_size = 0; 1339 // True if sign is mandatory. 1340 const bool __mandatory_sign = (__lc->_M_positive_sign_size 1341 && __lc->_M_negative_sign_size); 1342 // String of grouping info from thousands_sep plucked from __units. 1343 string __grouping_tmp; 1344 if (__lc->_M_use_grouping) 1345 __grouping_tmp.reserve(32); 1346 // Last position before the decimal point. 1347 int __last_pos = 0; 1348 // Separator positions, then, possibly, fractional digits. 1349 int __n = 0; 1350 // If input iterator is in a valid state. 1351 bool __testvalid = true; 1352 // Flag marking when a decimal point is found. 1353 bool __testdecfound = false; 1354 1355 // The tentative returned string is stored here. 1356 string __res; 1357 __res.reserve(32); 1358 1359 const char_type* __lit_zero = __lit + money_base::_S_zero; 1360 const money_base::pattern __p = __lc->_M_neg_format; 1361 for (int __i = 0; __i < 4 && __testvalid; ++__i) 1362 { 1363 const part __which = static_cast<part>(__p.field[__i]); 1364 switch (__which) 1365 { 1366 case money_base::symbol: 1367 // According to 22.2.6.1.2, p2, symbol is required 1368 // if (__io.flags() & ios_base::showbase), otherwise 1369 // is optional and consumed only if other characters 1370 // are needed to complete the format. 1371 if (__io.flags() & ios_base::showbase || __sign_size > 1 1372 || __i == 0 1373 || (__i == 1 && (__mandatory_sign 1374 || (static_cast<part>(__p.field[0]) 1375 == money_base::sign) 1376 || (static_cast<part>(__p.field[2]) 1377 == money_base::space))) 1378 || (__i == 2 && ((static_cast<part>(__p.field[3]) 1379 == money_base::value) 1380 || __mandatory_sign 1381 && (static_cast<part>(__p.field[3]) 1382 == money_base::sign)))) 1383 { 1384 const size_type __len = __lc->_M_curr_symbol_size; 1385 size_type __j = 0; 1386 for (; __beg != __end && __j < __len 1387 && *__beg == __lc->_M_curr_symbol[__j]; 1388 ++__beg, ++__j); 1389 if (__j != __len 1390 && (__j || __io.flags() & ios_base::showbase)) 1391 __testvalid = false; 1392 } 1393 break; 1394 case money_base::sign: 1395 // Sign might not exist, or be more than one character long. 1396 if (__lc->_M_positive_sign_size && __beg != __end 1397 && *__beg == __lc->_M_positive_sign[0]) 1398 { 1399 __sign_size = __lc->_M_positive_sign_size; 1400 ++__beg; 1401 } 1402 else if (__lc->_M_negative_sign_size && __beg != __end 1403 && *__beg == __lc->_M_negative_sign[0]) 1404 { 1405 __negative = true; 1406 __sign_size = __lc->_M_negative_sign_size; 1407 ++__beg; 1408 } 1409 else if (__lc->_M_positive_sign_size 1410 && !__lc->_M_negative_sign_size) 1411 // "... if no sign is detected, the result is given the sign 1412 // that corresponds to the source of the empty string" 1413 __negative = true; 1414 else if (__mandatory_sign) 1415 __testvalid = false; 1416 break; 1417 case money_base::value: 1418 // Extract digits, remove and stash away the 1419 // grouping of found thousands separators. 1420 for (; __beg != __end; ++__beg) 1421 { 1422 const char_type __c = *__beg; 1423 const char_type* __q = __traits_type::find(__lit_zero, 1424 10, __c); 1425 if (__q != 0) 1426 { 1427 __res += money_base::_S_atoms[__q - __lit]; 1428 ++__n; 1429 } 1430 else if (__c == __lc->_M_decimal_point 1431 && !__testdecfound) 1432 { 1433 __last_pos = __n; 1434 __n = 0; 1435 __testdecfound = true; 1436 } 1437 else if (__lc->_M_use_grouping 1438 && __c == __lc->_M_thousands_sep 1439 && !__testdecfound) 1440 { 1441 if (__n) 1442 { 1443 // Mark position for later analysis. 1444 __grouping_tmp += static_cast<char>(__n); 1445 __n = 0; 1446 } 1447 else 1448 { 1449 __testvalid = false; 1450 break; 1451 } 1452 } 1453 else 1454 break; 1455 } 1456 if (__res.empty()) 1457 __testvalid = false; 1458 break; 1459 case money_base::space: 1460 // At least one space is required. 1461 if (__beg != __end && __ctype.is(ctype_base::space, *__beg)) 1462 ++__beg; 1463 else 1464 __testvalid = false; 1465 case money_base::none: 1466 // Only if not at the end of the pattern. 1467 if (__i != 3) 1468 for (; __beg != __end 1469 && __ctype.is(ctype_base::space, *__beg); ++__beg); 1470 break; 1471 } 1472 } 1473 1474 // Need to get the rest of the sign characters, if they exist. 1475 if (__sign_size > 1 && __testvalid) 1476 { 1477 const char_type* __sign = __negative ? __lc->_M_negative_sign 1478 : __lc->_M_positive_sign; 1479 size_type __i = 1; 1480 for (; __beg != __end && __i < __sign_size 1481 && *__beg == __sign[__i]; ++__beg, ++__i); 1482 1483 if (__i != __sign_size) 1484 __testvalid = false; 1485 } 1486 1487 if (__testvalid) 1488 { 1489 // Strip leading zeros. 1490 if (__res.size() > 1) 1491 { 1492 const size_type __first = __res.find_first_not_of('0'); 1493 const bool __only_zeros = __first == string::npos; 1494 if (__first) 1495 __res.erase(0, __only_zeros ? __res.size() - 1 : __first); 1496 } 1497 1498 // 22.2.6.1.2, p4 1499 if (__negative && __res[0] != '0') 1500 __res.insert(__res.begin(), '-'); 1501 1502 // Test for grouping fidelity. 1503 if (__grouping_tmp.size()) 1504 { 1505 // Add the ending grouping. 1506 __grouping_tmp += static_cast<char>(__testdecfound ? __last_pos 1507 : __n); 1508 if (!std::__verify_grouping(__lc->_M_grouping, 1509 __lc->_M_grouping_size, 1510 __grouping_tmp)) 1511 __err |= ios_base::failbit; 1512 } 1513 1514 // Iff not enough digits were supplied after the decimal-point. 1515 if (__testdecfound && __lc->_M_frac_digits > 0 1516 && __n != __lc->_M_frac_digits) 1517 __testvalid = false; 1518 } 1519 1520 // Iff valid sequence is not recognized. 1521 if (!__testvalid) 1522 __err |= ios_base::failbit; 1523 else 1524 __units.swap(__res); 1525 1526 // Iff no more characters are available. 1527 if (__beg == __end) 1528 __err |= ios_base::eofbit; 1529 return __beg; 1530 } 1531 1532 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 1533 template<typename _CharT, typename _InIter> 1534 _InIter 1535 money_get<_CharT, _InIter>:: 1536 __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 1537 ios_base::iostate& __err, double& __units) const 1538 { 1539 string __str; 1540 __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str) 1541 : _M_extract<false>(__beg, __end, __io, __err, __str); 1542 std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); 1543 return __beg; 1544 } 1545 #endif 1546 1547 template<typename _CharT, typename _InIter> 1548 _InIter 1549 money_get<_CharT, _InIter>:: 1550 do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 1551 ios_base::iostate& __err, long double& __units) const 1552 { 1553 string __str; 1554 __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str) 1555 : _M_extract<false>(__beg, __end, __io, __err, __str); 1556 std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); 1557 return __beg; 1558 } 1559 1560 template<typename _CharT, typename _InIter> 1561 _InIter 1562 money_get<_CharT, _InIter>:: 1563 do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 1564 ios_base::iostate& __err, string_type& __digits) const 1565 { 1566 typedef typename string::size_type size_type; 1567 1568 const locale& __loc = __io._M_getloc(); 1569 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 1570 1571 string __str; 1572 __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str) 1573 : _M_extract<false>(__beg, __end, __io, __err, __str); 1574 const size_type __len = __str.size(); 1575 if (__len) 1576 { 1577 __digits.resize(__len); 1578 __ctype.widen(__str.data(), __str.data() + __len, &__digits[0]); 1579 } 1580 return __beg; 1581 } 1582 1583 template<typename _CharT, typename _OutIter> 1584 template<bool _Intl> 1585 _OutIter 1586 money_put<_CharT, _OutIter>:: 1587 _M_insert(iter_type __s, ios_base& __io, char_type __fill, 1588 const string_type& __digits) const 1589 { 1590 typedef typename string_type::size_type size_type; 1591 typedef money_base::part part; 1592 typedef __moneypunct_cache<_CharT, _Intl> __cache_type; 1593 1594 const locale& __loc = __io._M_getloc(); 1595 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 1596 1597 __use_cache<__cache_type> __uc; 1598 const __cache_type* __lc = __uc(__loc); 1599 const char_type* __lit = __lc->_M_atoms; 1600 1601 // Determine if negative or positive formats are to be used, and 1602 // discard leading negative_sign if it is present. 1603 const char_type* __beg = __digits.data(); 1604 1605 money_base::pattern __p; 1606 const char_type* __sign; 1607 size_type __sign_size; 1608 if (!(*__beg == __lit[money_base::_S_minus])) 1609 { 1610 __p = __lc->_M_pos_format; 1611 __sign = __lc->_M_positive_sign; 1612 __sign_size = __lc->_M_positive_sign_size; 1613 } 1614 else 1615 { 1616 __p = __lc->_M_neg_format; 1617 __sign = __lc->_M_negative_sign; 1618 __sign_size = __lc->_M_negative_sign_size; 1619 if (__digits.size()) 1620 ++__beg; 1621 } 1622 1623 // Look for valid numbers in the ctype facet within input digits. 1624 size_type __len = __ctype.scan_not(ctype_base::digit, __beg, 1625 __beg + __digits.size()) - __beg; 1626 if (__len) 1627 { 1628 // Assume valid input, and attempt to format. 1629 // Break down input numbers into base components, as follows: 1630 // final_value = grouped units + (decimal point) + (digits) 1631 string_type __value; 1632 __value.reserve(2 * __len); 1633 1634 // Add thousands separators to non-decimal digits, per 1635 // grouping rules. 1636 long __paddec = __len - __lc->_M_frac_digits; 1637 if (__paddec > 0) 1638 { 1639 if (__lc->_M_frac_digits < 0) 1640 __paddec = __len; 1641 if (__lc->_M_grouping_size) 1642 { 1643 __value.assign(2 * __paddec, char_type()); 1644 _CharT* __vend = 1645 std::__add_grouping(&__value[0], __lc->_M_thousands_sep, 1646 __lc->_M_grouping, 1647 __lc->_M_grouping_size, 1648 __beg, __beg + __paddec); 1649 __value.erase(__vend - &__value[0]); 1650 } 1651 else 1652 __value.assign(__beg, __paddec); 1653 } 1654 1655 // Deal with decimal point, decimal digits. 1656 if (__lc->_M_frac_digits > 0) 1657 { 1658 __value += __lc->_M_decimal_point; 1659 if (__paddec >= 0) 1660 __value.append(__beg + __paddec, __lc->_M_frac_digits); 1661 else 1662 { 1663 // Have to pad zeros in the decimal position. 1664 __value.append(-__paddec, __lit[money_base::_S_zero]); 1665 __value.append(__beg, __len); 1666 } 1667 } 1668 1669 // Calculate length of resulting string. 1670 const ios_base::fmtflags __f = __io.flags() 1671 & ios_base::adjustfield; 1672 __len = __value.size() + __sign_size; 1673 __len += ((__io.flags() & ios_base::showbase) 1674 ? __lc->_M_curr_symbol_size : 0); 1675 1676 string_type __res; 1677 __res.reserve(2 * __len); 1678 1679 const size_type __width = static_cast<size_type>(__io.width()); 1680 const bool __testipad = (__f == ios_base::internal 1681 && __len < __width); 1682 // Fit formatted digits into the required pattern. 1683 for (int __i = 0; __i < 4; ++__i) 1684 { 1685 const part __which = static_cast<part>(__p.field[__i]); 1686 switch (__which) 1687 { 1688 case money_base::symbol: 1689 if (__io.flags() & ios_base::showbase) 1690 __res.append(__lc->_M_curr_symbol, 1691 __lc->_M_curr_symbol_size); 1692 break; 1693 case money_base::sign: 1694 // Sign might not exist, or be more than one 1695 // charater long. In that case, add in the rest 1696 // below. 1697 if (__sign_size) 1698 __res += __sign[0]; 1699 break; 1700 case money_base::value: 1701 __res += __value; 1702 break; 1703 case money_base::space: 1704 // At least one space is required, but if internal 1705 // formatting is required, an arbitrary number of 1706 // fill spaces will be necessary. 1707 if (__testipad) 1708 __res.append(__width - __len, __fill); 1709 else 1710 __res += __fill; 1711 break; 1712 case money_base::none: 1713 if (__testipad) 1714 __res.append(__width - __len, __fill); 1715 break; 1716 } 1717 } 1718 1719 // Special case of multi-part sign parts. 1720 if (__sign_size > 1) 1721 __res.append(__sign + 1, __sign_size - 1); 1722 1723 // Pad, if still necessary. 1724 __len = __res.size(); 1725 if (__width > __len) 1726 { 1727 if (__f == ios_base::left) 1728 // After. 1729 __res.append(__width - __len, __fill); 1730 else 1731 // Before. 1732 __res.insert(0, __width - __len, __fill); 1733 __len = __width; 1734 } 1735 1736 // Write resulting, fully-formatted string to output iterator. 1737 __s = std::__write(__s, __res.data(), __len); 1738 } 1739 __io.width(0); 1740 return __s; 1741 } 1742 1743 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 1744 template<typename _CharT, typename _OutIter> 1745 _OutIter 1746 money_put<_CharT, _OutIter>:: 1747 __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 1748 double __units) const 1749 { return this->do_put(__s, __intl, __io, __fill, (long double) __units); } 1750 #endif 1751 1752 template<typename _CharT, typename _OutIter> 1753 _OutIter 1754 money_put<_CharT, _OutIter>:: 1755 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 1756 long double __units) const 1757 { 1758 const locale __loc = __io.getloc(); 1759 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 1760 #ifdef _GLIBCXX_USE_C99 1761 // First try a buffer perhaps big enough. 1762 int __cs_size = 64; 1763 char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 1764 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1765 // 328. Bad sprintf format modifier in money_put<>::do_put() 1766 int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, 1767 "%.*Lf", 0, __units); 1768 // If the buffer was not large enough, try again with the correct size. 1769 if (__len >= __cs_size) 1770 { 1771 __cs_size = __len + 1; 1772 __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 1773 __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, 1774 "%.*Lf", 0, __units); 1775 } 1776 #else 1777 // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. 1778 const int __cs_size = numeric_limits<long double>::max_exponent10 + 3; 1779 char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 1780 int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf", 1781 0, __units); 1782 #endif 1783 string_type __digits(__len, char_type()); 1784 __ctype.widen(__cs, __cs + __len, &__digits[0]); 1785 return __intl ? _M_insert<true>(__s, __io, __fill, __digits) 1786 : _M_insert<false>(__s, __io, __fill, __digits); 1787 } 1788 1789 template<typename _CharT, typename _OutIter> 1790 _OutIter 1791 money_put<_CharT, _OutIter>:: 1792 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 1793 const string_type& __digits) const 1794 { return __intl ? _M_insert<true>(__s, __io, __fill, __digits) 1795 : _M_insert<false>(__s, __io, __fill, __digits); } 1796 1797 _GLIBCXX_END_LDBL_NAMESPACE 1798 1799 // NB: Not especially useful. Without an ios_base object or some 1800 // kind of locale reference, we are left clawing at the air where 1801 // the side of the mountain used to be... 1802 template<typename _CharT, typename _InIter> 1803 time_base::dateorder 1804 time_get<_CharT, _InIter>::do_date_order() const 1805 { return time_base::no_order; } 1806 1807 // Expand a strftime format string and parse it. E.g., do_get_date() may 1808 // pass %m/%d/%Y => extracted characters. 1809 template<typename _CharT, typename _InIter> 1810 _InIter 1811 time_get<_CharT, _InIter>:: 1812 _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, 1813 ios_base::iostate& __err, tm* __tm, 1814 const _CharT* __format) const 1815 { 1816 const locale& __loc = __io._M_getloc(); 1817 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 1818 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 1819 const size_t __len = char_traits<_CharT>::length(__format); 1820 1821 ios_base::iostate __tmperr = ios_base::goodbit; 1822 for (size_t __i = 0; __beg != __end && __i < __len && !__tmperr; ++__i) 1823 { 1824 if (__ctype.narrow(__format[__i], 0) == '%') 1825 { 1826 // Verify valid formatting code, attempt to extract. 1827 char __c = __ctype.narrow(__format[++__i], 0); 1828 int __mem = 0; 1829 if (__c == 'E' || __c == 'O') 1830 __c = __ctype.narrow(__format[++__i], 0); 1831 switch (__c) 1832 { 1833 const char* __cs; 1834 _CharT __wcs[10]; 1835 case 'a': 1836 // Abbreviated weekday name [tm_wday] 1837 const char_type* __days1[7]; 1838 __tp._M_days_abbreviated(__days1); 1839 __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 1840 7, __io, __tmperr); 1841 break; 1842 case 'A': 1843 // Weekday name [tm_wday]. 1844 const char_type* __days2[7]; 1845 __tp._M_days(__days2); 1846 __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 1847 7, __io, __tmperr); 1848 break; 1849 case 'h': 1850 case 'b': 1851 // Abbreviated month name [tm_mon] 1852 const char_type* __months1[12]; 1853 __tp._M_months_abbreviated(__months1); 1854 __beg = _M_extract_name(__beg, __end, __tm->tm_mon, 1855 __months1, 12, __io, __tmperr); 1856 break; 1857 case 'B': 1858 // Month name [tm_mon]. 1859 const char_type* __months2[12]; 1860 __tp._M_months(__months2); 1861 __beg = _M_extract_name(__beg, __end, __tm->tm_mon, 1862 __months2, 12, __io, __tmperr); 1863 break; 1864 case 'c': 1865 // Default time and date representation. 1866 const char_type* __dt[2]; 1867 __tp._M_date_time_formats(__dt); 1868 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 1869 __tm, __dt[0]); 1870 break; 1871 case 'd': 1872 // Day [01, 31]. [tm_mday] 1873 __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, 1874 __io, __tmperr); 1875 break; 1876 case 'e': 1877 // Day [1, 31], with single digits preceded by 1878 // space. [tm_mday] 1879 if (__ctype.is(ctype_base::space, *__beg)) 1880 __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9, 1881 1, __io, __tmperr); 1882 else 1883 __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31, 1884 2, __io, __tmperr); 1885 break; 1886 case 'D': 1887 // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] 1888 __cs = "%m/%d/%y"; 1889 __ctype.widen(__cs, __cs + 9, __wcs); 1890 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 1891 __tm, __wcs); 1892 break; 1893 case 'H': 1894 // Hour [00, 23]. [tm_hour] 1895 __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2, 1896 __io, __tmperr); 1897 break; 1898 case 'I': 1899 // Hour [01, 12]. [tm_hour] 1900 __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2, 1901 __io, __tmperr); 1902 break; 1903 case 'm': 1904 // Month [01, 12]. [tm_mon] 1905 __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, 1906 __io, __tmperr); 1907 if (!__tmperr) 1908 __tm->tm_mon = __mem - 1; 1909 break; 1910 case 'M': 1911 // Minute [00, 59]. [tm_min] 1912 __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2, 1913 __io, __tmperr); 1914 break; 1915 case 'n': 1916 if (__ctype.narrow(*__beg, 0) == '\n') 1917 ++__beg; 1918 else 1919 __tmperr |= ios_base::failbit; 1920 break; 1921 case 'R': 1922 // Equivalent to (%H:%M). 1923 __cs = "%H:%M"; 1924 __ctype.widen(__cs, __cs + 6, __wcs); 1925 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 1926 __tm, __wcs); 1927 break; 1928 case 'S': 1929 // Seconds. [tm_sec] 1930 // [00, 60] in C99 (one leap-second), [00, 61] in C89. 1931 #ifdef _GLIBCXX_USE_C99 1932 __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2, 1933 #else 1934 __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2, 1935 #endif 1936 __io, __tmperr); 1937 break; 1938 case 't': 1939 if (__ctype.narrow(*__beg, 0) == '\t') 1940 ++__beg; 1941 else 1942 __tmperr |= ios_base::failbit; 1943 break; 1944 case 'T': 1945 // Equivalent to (%H:%M:%S). 1946 __cs = "%H:%M:%S"; 1947 __ctype.widen(__cs, __cs + 9, __wcs); 1948 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 1949 __tm, __wcs); 1950 break; 1951 case 'x': 1952 // Locale's date. 1953 const char_type* __dates[2]; 1954 __tp._M_date_formats(__dates); 1955 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 1956 __tm, __dates[0]); 1957 break; 1958 case 'X': 1959 // Locale's time. 1960 const char_type* __times[2]; 1961 __tp._M_time_formats(__times); 1962 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 1963 __tm, __times[0]); 1964 break; 1965 case 'y': 1966 case 'C': // C99 1967 // Two digit year. [tm_year] 1968 __beg = _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2, 1969 __io, __tmperr); 1970 break; 1971 case 'Y': 1972 // Year [1900). [tm_year] 1973 __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4, 1974 __io, __tmperr); 1975 if (!__tmperr) 1976 __tm->tm_year = __mem - 1900; 1977 break; 1978 case 'Z': 1979 // Timezone info. 1980 if (__ctype.is(ctype_base::upper, *__beg)) 1981 { 1982 int __tmp; 1983 __beg = _M_extract_name(__beg, __end, __tmp, 1984 __timepunct_cache<_CharT>::_S_timezones, 1985 14, __io, __tmperr); 1986 1987 // GMT requires special effort. 1988 if (__beg != __end && !__tmperr && __tmp == 0 1989 && (*__beg == __ctype.widen('-') 1990 || *__beg == __ctype.widen('+'))) 1991 { 1992 __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2, 1993 __io, __tmperr); 1994 __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2, 1995 __io, __tmperr); 1996 } 1997 } 1998 else 1999 __tmperr |= ios_base::failbit; 2000 break; 2001 default: 2002 // Not recognized. 2003 __tmperr |= ios_base::failbit; 2004 } 2005 } 2006 else 2007 { 2008 // Verify format and input match, extract and discard. 2009 if (__format[__i] == *__beg) 2010 ++__beg; 2011 else 2012 __tmperr |= ios_base::failbit; 2013 } 2014 } 2015 2016 if (__tmperr) 2017 __err |= ios_base::failbit; 2018 2019 return __beg; 2020 } 2021 2022 template<typename _CharT, typename _InIter> 2023 _InIter 2024 time_get<_CharT, _InIter>:: 2025 _M_extract_num(iter_type __beg, iter_type __end, int& __member, 2026 int __min, int __max, size_t __len, 2027 ios_base& __io, ios_base::iostate& __err) const 2028 { 2029 const locale& __loc = __io._M_getloc(); 2030 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 2031 2032 // As-is works for __len = 1, 2, 4, the values actually used. 2033 int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1); 2034 2035 ++__min; 2036 size_t __i = 0; 2037 int __value = 0; 2038 for (; __beg != __end && __i < __len; ++__beg, ++__i) 2039 { 2040 const char __c = __ctype.narrow(*__beg, '*'); 2041 if (__c >= '0' && __c <= '9') 2042 { 2043 __value = __value * 10 + (__c - '0'); 2044 const int __valuec = __value * __mult; 2045 if (__valuec > __max || __valuec + __mult < __min) 2046 break; 2047 __mult /= 10; 2048 } 2049 else 2050 break; 2051 } 2052 if (__i == __len) 2053 __member = __value; 2054 else 2055 __err |= ios_base::failbit; 2056 2057 return __beg; 2058 } 2059 2060 // Assumptions: 2061 // All elements in __names are unique. 2062 template<typename _CharT, typename _InIter> 2063 _InIter 2064 time_get<_CharT, _InIter>:: 2065 _M_extract_name(iter_type __beg, iter_type __end, int& __member, 2066 const _CharT** __names, size_t __indexlen, 2067 ios_base& __io, ios_base::iostate& __err) const 2068 { 2069 typedef char_traits<_CharT> __traits_type; 2070 const locale& __loc = __io._M_getloc(); 2071 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 2072 2073 int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) 2074 * __indexlen)); 2075 size_t __nmatches = 0; 2076 size_t __pos = 0; 2077 bool __testvalid = true; 2078 const char_type* __name; 2079 2080 // Look for initial matches. 2081 // NB: Some of the locale data is in the form of all lowercase 2082 // names, and some is in the form of initially-capitalized 2083 // names. Look for both. 2084 if (__beg != __end) 2085 { 2086 const char_type __c = *__beg; 2087 for (size_t __i1 = 0; __i1 < __indexlen; ++__i1) 2088 if (__c == __names[__i1][0] 2089 || __c == __ctype.toupper(__names[__i1][0])) 2090 __matches[__nmatches++] = __i1; 2091 } 2092 2093 while (__nmatches > 1) 2094 { 2095 // Find smallest matching string. 2096 size_t __minlen = __traits_type::length(__names[__matches[0]]); 2097 for (size_t __i2 = 1; __i2 < __nmatches; ++__i2) 2098 __minlen = std::min(__minlen, 2099 __traits_type::length(__names[__matches[__i2]])); 2100 ++__beg, ++__pos; 2101 if (__pos < __minlen && __beg != __end) 2102 for (size_t __i3 = 0; __i3 < __nmatches;) 2103 { 2104 __name = __names[__matches[__i3]]; 2105 if (!(__name[__pos] == *__beg)) 2106 __matches[__i3] = __matches[--__nmatches]; 2107 else 2108 ++__i3; 2109 } 2110 else 2111 break; 2112 } 2113 2114 if (__nmatches == 1) 2115 { 2116 // Make sure found name is completely extracted. 2117 ++__beg, ++__pos; 2118 __name = __names[__matches[0]]; 2119 const size_t __len = __traits_type::length(__name); 2120 while (__pos < __len && __beg != __end && __name[__pos] == *__beg) 2121 ++__beg, ++__pos; 2122 2123 if (__len == __pos) 2124 __member = __matches[0]; 2125 else 2126 __testvalid = false; 2127 } 2128 else 2129 __testvalid = false; 2130 if (!__testvalid) 2131 __err |= ios_base::failbit; 2132 2133 return __beg; 2134 } 2135 2136 template<typename _CharT, typename _InIter> 2137 _InIter 2138 time_get<_CharT, _InIter>:: 2139 do_get_time(iter_type __beg, iter_type __end, ios_base& __io, 2140 ios_base::iostate& __err, tm* __tm) const 2141 { 2142 const locale& __loc = __io._M_getloc(); 2143 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 2144 const char_type* __times[2]; 2145 __tp._M_time_formats(__times); 2146 __beg = _M_extract_via_format(__beg, __end, __io, __err, 2147 __tm, __times[0]); 2148 if (__beg == __end) 2149 __err |= ios_base::eofbit; 2150 return __beg; 2151 } 2152 2153 template<typename _CharT, typename _InIter> 2154 _InIter 2155 time_get<_CharT, _InIter>:: 2156 do_get_date(iter_type __beg, iter_type __end, ios_base& __io, 2157 ios_base::iostate& __err, tm* __tm) const 2158 { 2159 const locale& __loc = __io._M_getloc(); 2160 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 2161 const char_type* __dates[2]; 2162 __tp._M_date_formats(__dates); 2163 __beg = _M_extract_via_format(__beg, __end, __io, __err, 2164 __tm, __dates[0]); 2165 if (__beg == __end) 2166 __err |= ios_base::eofbit; 2167 return __beg; 2168 } 2169 2170 template<typename _CharT, typename _InIter> 2171 _InIter 2172 time_get<_CharT, _InIter>:: 2173 do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, 2174 ios_base::iostate& __err, tm* __tm) const 2175 { 2176 typedef char_traits<_CharT> __traits_type; 2177 const locale& __loc = __io._M_getloc(); 2178 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 2179 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 2180 const char_type* __days[7]; 2181 __tp._M_days_abbreviated(__days); 2182 int __tmpwday; 2183 ios_base::iostate __tmperr = ios_base::goodbit; 2184 __beg = _M_extract_name(__beg, __end, __tmpwday, __days, 7, 2185 __io, __tmperr); 2186 2187 // Check to see if non-abbreviated name exists, and extract. 2188 // NB: Assumes both _M_days and _M_days_abbreviated organized in 2189 // exact same order, first to last, such that the resulting 2190 // __days array with the same index points to a day, and that 2191 // day's abbreviated form. 2192 // NB: Also assumes that an abbreviated name is a subset of the name. 2193 if (!__tmperr && __beg != __end) 2194 { 2195 size_t __pos = __traits_type::length(__days[__tmpwday]); 2196 __tp._M_days(__days); 2197 const char_type* __name = __days[__tmpwday]; 2198 if (__name[__pos] == *__beg) 2199 { 2200 // Extract the rest of it. 2201 const size_t __len = __traits_type::length(__name); 2202 while (__pos < __len && __beg != __end 2203 && __name[__pos] == *__beg) 2204 ++__beg, ++__pos; 2205 if (__len != __pos) 2206 __tmperr |= ios_base::failbit; 2207 } 2208 } 2209 if (!__tmperr) 2210 __tm->tm_wday = __tmpwday; 2211 else 2212 __err |= ios_base::failbit; 2213 2214 if (__beg == __end) 2215 __err |= ios_base::eofbit; 2216 return __beg; 2217 } 2218 2219 template<typename _CharT, typename _InIter> 2220 _InIter 2221 time_get<_CharT, _InIter>:: 2222 do_get_monthname(iter_type __beg, iter_type __end, 2223 ios_base& __io, ios_base::iostate& __err, tm* __tm) const 2224 { 2225 typedef char_traits<_CharT> __traits_type; 2226 const locale& __loc = __io._M_getloc(); 2227 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 2228 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 2229 const char_type* __months[12]; 2230 __tp._M_months_abbreviated(__months); 2231 int __tmpmon; 2232 ios_base::iostate __tmperr = ios_base::goodbit; 2233 __beg = _M_extract_name(__beg, __end, __tmpmon, __months, 12, 2234 __io, __tmperr); 2235 2236 // Check to see if non-abbreviated name exists, and extract. 2237 // NB: Assumes both _M_months and _M_months_abbreviated organized in 2238 // exact same order, first to last, such that the resulting 2239 // __months array with the same index points to a month, and that 2240 // month's abbreviated form. 2241 // NB: Also assumes that an abbreviated name is a subset of the name. 2242 if (!__tmperr && __beg != __end) 2243 { 2244 size_t __pos = __traits_type::length(__months[__tmpmon]); 2245 __tp._M_months(__months); 2246 const char_type* __name = __months[__tmpmon]; 2247 if (__name[__pos] == *__beg) 2248 { 2249 // Extract the rest of it. 2250 const size_t __len = __traits_type::length(__name); 2251 while (__pos < __len && __beg != __end 2252 && __name[__pos] == *__beg) 2253 ++__beg, ++__pos; 2254 if (__len != __pos) 2255 __tmperr |= ios_base::failbit; 2256 } 2257 } 2258 if (!__tmperr) 2259 __tm->tm_mon = __tmpmon; 2260 else 2261 __err |= ios_base::failbit; 2262 2263 if (__beg == __end) 2264 __err |= ios_base::eofbit; 2265 return __beg; 2266 } 2267 2268 template<typename _CharT, typename _InIter> 2269 _InIter 2270 time_get<_CharT, _InIter>:: 2271 do_get_year(iter_type __beg, iter_type __end, ios_base& __io, 2272 ios_base::iostate& __err, tm* __tm) const 2273 { 2274 const locale& __loc = __io._M_getloc(); 2275 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 2276 2277 size_t __i = 0; 2278 int __value = 0; 2279 for (; __beg != __end && __i < 4; ++__beg, ++__i) 2280 { 2281 const char __c = __ctype.narrow(*__beg, '*'); 2282 if (__c >= '0' && __c <= '9') 2283 __value = __value * 10 + (__c - '0'); 2284 else 2285 break; 2286 } 2287 if (__i == 2 || __i == 4) 2288 __tm->tm_year = __i == 2 ? __value : __value - 1900; 2289 else 2290 __err |= ios_base::failbit; 2291 2292 if (__beg == __end) 2293 __err |= ios_base::eofbit; 2294 return __beg; 2295 } 2296 2297 template<typename _CharT, typename _OutIter> 2298 _OutIter 2299 time_put<_CharT, _OutIter>:: 2300 put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, 2301 const _CharT* __beg, const _CharT* __end) const 2302 { 2303 const locale& __loc = __io._M_getloc(); 2304 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); 2305 for (; __beg != __end; ++__beg) 2306 if (__ctype.narrow(*__beg, 0) != '%') 2307 { 2308 *__s = *__beg; 2309 ++__s; 2310 } 2311 else if (++__beg != __end) 2312 { 2313 char __format; 2314 char __mod = 0; 2315 const char __c = __ctype.narrow(*__beg, 0); 2316 if (__c != 'E' && __c != 'O') 2317 __format = __c; 2318 else if (++__beg != __end) 2319 { 2320 __mod = __c; 2321 __format = __ctype.narrow(*__beg, 0); 2322 } 2323 else 2324 break; 2325 __s = this->do_put(__s, __io, __fill, __tm, __format, __mod); 2326 } 2327 else 2328 break; 2329 return __s; 2330 } 2331 2332 template<typename _CharT, typename _OutIter> 2333 _OutIter 2334 time_put<_CharT, _OutIter>:: 2335 do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, 2336 char __format, char __mod) const 2337 { 2338 const locale& __loc = __io._M_getloc(); 2339 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); 2340 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); 2341 2342 // NB: This size is arbitrary. Should this be a data member, 2343 // initialized at construction? 2344 const size_t __maxlen = 128; 2345 char_type* __res = 2346 static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen)); 2347 2348 // NB: In IEE 1003.1-200x, and perhaps other locale models, it 2349 // is possible that the format character will be longer than one 2350 // character. Possibilities include 'E' or 'O' followed by a 2351 // format character: if __mod is not the default argument, assume 2352 // it's a valid modifier. 2353 char_type __fmt[4]; 2354 __fmt[0] = __ctype.widen('%'); 2355 if (!__mod) 2356 { 2357 __fmt[1] = __format; 2358 __fmt[2] = char_type(); 2359 } 2360 else 2361 { 2362 __fmt[1] = __mod; 2363 __fmt[2] = __format; 2364 __fmt[3] = char_type(); 2365 } 2366 2367 __tp._M_put(__res, __maxlen, __fmt, __tm); 2368 2369 // Write resulting, fully-formatted string to output iterator. 2370 return std::__write(__s, __res, char_traits<char_type>::length(__res)); 2371 } 2372 2373 // Generic version does nothing. 2374 template<typename _CharT> 2375 int 2376 collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const 2377 { return 0; } 2378 2379 // Generic version does nothing. 2380 template<typename _CharT> 2381 size_t 2382 collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const 2383 { return 0; } 2384 2385 template<typename _CharT> 2386 int 2387 collate<_CharT>:: 2388 do_compare(const _CharT* __lo1, const _CharT* __hi1, 2389 const _CharT* __lo2, const _CharT* __hi2) const 2390 { 2391 // strcoll assumes zero-terminated strings so we make a copy 2392 // and then put a zero at the end. 2393 const string_type __one(__lo1, __hi1); 2394 const string_type __two(__lo2, __hi2); 2395 2396 const _CharT* __p = __one.c_str(); 2397 const _CharT* __pend = __one.data() + __one.length(); 2398 const _CharT* __q = __two.c_str(); 2399 const _CharT* __qend = __two.data() + __two.length(); 2400 2401 // strcoll stops when it sees a nul character so we break 2402 // the strings into zero-terminated substrings and pass those 2403 // to strcoll. 2404 for (;;) 2405 { 2406 const int __res = _M_compare(__p, __q); 2407 if (__res) 2408 return __res; 2409 2410 __p += char_traits<_CharT>::length(__p); 2411 __q += char_traits<_CharT>::length(__q); 2412 if (__p == __pend && __q == __qend) 2413 return 0; 2414 else if (__p == __pend) 2415 return -1; 2416 else if (__q == __qend) 2417 return 1; 2418 2419 __p++; 2420 __q++; 2421 } 2422 } 2423 2424 template<typename _CharT> 2425 typename collate<_CharT>::string_type 2426 collate<_CharT>:: 2427 do_transform(const _CharT* __lo, const _CharT* __hi) const 2428 { 2429 string_type __ret; 2430 2431 // strxfrm assumes zero-terminated strings so we make a copy 2432 const string_type __str(__lo, __hi); 2433 2434 const _CharT* __p = __str.c_str(); 2435 const _CharT* __pend = __str.data() + __str.length(); 2436 2437 size_t __len = (__hi - __lo) * 2; 2438 2439 _CharT* __c = new _CharT[__len]; 2440 2441 try 2442 { 2443 // strxfrm stops when it sees a nul character so we break 2444 // the string into zero-terminated substrings and pass those 2445 // to strxfrm. 2446 for (;;) 2447 { 2448 // First try a buffer perhaps big enough. 2449 size_t __res = _M_transform(__c, __p, __len); 2450 // If the buffer was not large enough, try again with the 2451 // correct size. 2452 if (__res >= __len) 2453 { 2454 __len = __res + 1; 2455 delete [] __c, __c = 0; 2456 __c = new _CharT[__len]; 2457 __res = _M_transform(__c, __p, __len); 2458 } 2459 2460 __ret.append(__c, __res); 2461 __p += char_traits<_CharT>::length(__p); 2462 if (__p == __pend) 2463 break; 2464 2465 __p++; 2466 __ret.push_back(_CharT()); 2467 } 2468 } 2469 catch(...) 2470 { 2471 delete [] __c; 2472 __throw_exception_again; 2473 } 2474 2475 delete [] __c; 2476 2477 return __ret; 2478 } 2479 2480 template<typename _CharT> 2481 long 2482 collate<_CharT>:: 2483 do_hash(const _CharT* __lo, const _CharT* __hi) const 2484 { 2485 unsigned long __val = 0; 2486 for (; __lo < __hi; ++__lo) 2487 __val = *__lo + ((__val << 7) | 2488 (__val >> (numeric_limits<unsigned long>::digits - 7))); 2489 return static_cast<long>(__val); 2490 } 2491 2492 // Construct correctly padded string, as per 22.2.2.2.2 2493 // Assumes 2494 // __newlen > __oldlen 2495 // __news is allocated for __newlen size 2496 // Used by both num_put and ostream inserters: if __num, 2497 // internal-adjusted objects are padded according to the rules below 2498 // concerning 0[xX] and +-, otherwise, exactly as right-adjusted 2499 // ones are. 2500 2501 // NB: Of the two parameters, _CharT can be deduced from the 2502 // function arguments. The other (_Traits) has to be explicitly specified. 2503 template<typename _CharT, typename _Traits> 2504 void 2505 __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill, 2506 _CharT* __news, const _CharT* __olds, 2507 const streamsize __newlen, 2508 const streamsize __oldlen, const bool __num) 2509 { 2510 const size_t __plen = static_cast<size_t>(__newlen - __oldlen); 2511 const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield; 2512 2513 // Padding last. 2514 if (__adjust == ios_base::left) 2515 { 2516 _Traits::copy(__news, const_cast<_CharT*>(__olds), __oldlen); 2517 _Traits::assign(__news + __oldlen, __plen, __fill); 2518 return; 2519 } 2520 2521 size_t __mod = 0; 2522 if (__adjust == ios_base::internal && __num) 2523 { 2524 // Pad after the sign, if there is one. 2525 // Pad after 0[xX], if there is one. 2526 // Who came up with these rules, anyway? Jeeze. 2527 const locale& __loc = __io._M_getloc(); 2528 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 2529 2530 const bool __testsign = (__ctype.widen('-') == __olds[0] 2531 || __ctype.widen('+') == __olds[0]); 2532 const bool __testhex = (__ctype.widen('0') == __olds[0] 2533 && __oldlen > 1 2534 && (__ctype.widen('x') == __olds[1] 2535 || __ctype.widen('X') == __olds[1])); 2536 if (__testhex) 2537 { 2538 __news[0] = __olds[0]; 2539 __news[1] = __olds[1]; 2540 __mod = 2; 2541 __news += 2; 2542 } 2543 else if (__testsign) 2544 { 2545 __news[0] = __olds[0]; 2546 __mod = 1; 2547 ++__news; 2548 } 2549 // else Padding first. 2550 } 2551 _Traits::assign(__news, __plen, __fill); 2552 _Traits::copy(__news + __plen, const_cast<_CharT*>(__olds + __mod), 2553 __oldlen - __mod); 2554 } 2555 2556 bool 2557 __verify_grouping(const char* __grouping, size_t __grouping_size, 2558 const string& __grouping_tmp) 2559 { 2560 const size_t __n = __grouping_tmp.size() - 1; 2561 const size_t __min = std::min(__n, size_t(__grouping_size - 1)); 2562 size_t __i = __n; 2563 bool __test = true; 2564 2565 // Parsed number groupings have to match the 2566 // numpunct::grouping string exactly, starting at the 2567 // right-most point of the parsed sequence of elements ... 2568 for (size_t __j = 0; __j < __min && __test; --__i, ++__j) 2569 __test = __grouping_tmp[__i] == __grouping[__j]; 2570 for (; __i && __test; --__i) 2571 __test = __grouping_tmp[__i] == __grouping[__min]; 2572 // ... but the first parsed grouping can be <= numpunct 2573 // grouping (only do the check if the numpunct char is > 0 2574 // because <= 0 means any size is ok). 2575 if (static_cast<signed char>(__grouping[__min]) > 0) 2576 __test &= __grouping_tmp[0] <= __grouping[__min]; 2577 return __test; 2578 } 2579 2580 template<typename _CharT> 2581 _CharT* 2582 __add_grouping(_CharT* __s, _CharT __sep, 2583 const char* __gbeg, size_t __gsize, 2584 const _CharT* __first, const _CharT* __last) 2585 { 2586 size_t __idx = 0; 2587 size_t __ctr = 0; 2588 2589 while (__last - __first > __gbeg[__idx] 2590 && static_cast<signed char>(__gbeg[__idx]) > 0) 2591 { 2592 __last -= __gbeg[__idx]; 2593 __idx < __gsize - 1 ? ++__idx : ++__ctr; 2594 } 2595 2596 while (__first != __last) 2597 *__s++ = *__first++; 2598 2599 while (__ctr--) 2600 { 2601 *__s++ = __sep; 2602 for (char __i = __gbeg[__idx]; __i > 0; --__i) 2603 *__s++ = *__first++; 2604 } 2605 2606 while (__idx--) 2607 { 2608 *__s++ = __sep; 2609 for (char __i = __gbeg[__idx]; __i > 0; --__i) 2610 *__s++ = *__first++; 2611 } 2612 2613 return __s; 2614 } 2615 2616 // Inhibit implicit instantiations for required instantiations, 2617 // which are defined via explicit instantiations elsewhere. 2618 // NB: This syntax is a GNU extension. 2619 #if _GLIBCXX_EXTERN_TEMPLATE 2620 extern template class moneypunct<char, false>; 2621 extern template class moneypunct<char, true>; 2622 extern template class moneypunct_byname<char, false>; 2623 extern template class moneypunct_byname<char, true>; 2624 extern template class _GLIBCXX_LDBL_NAMESPACE money_get<char>; 2625 extern template class _GLIBCXX_LDBL_NAMESPACE money_put<char>; 2626 extern template class numpunct<char>; 2627 extern template class numpunct_byname<char>; 2628 extern template class _GLIBCXX_LDBL_NAMESPACE num_get<char>; 2629 extern template class _GLIBCXX_LDBL_NAMESPACE num_put<char>; 2630 extern template class __timepunct<char>; 2631 extern template class time_put<char>; 2632 extern template class time_put_byname<char>; 2633 extern template class time_get<char>; 2634 extern template class time_get_byname<char>; 2635 extern template class messages<char>; 2636 extern template class messages_byname<char>; 2637 extern template class ctype_byname<char>; 2638 extern template class codecvt_byname<char, char, mbstate_t>; 2639 extern template class collate<char>; 2640 extern template class collate_byname<char>; 2641 2642 extern template 2643 const codecvt<char, char, mbstate_t>& 2644 use_facet<codecvt<char, char, mbstate_t> >(const locale&); 2645 2646 extern template 2647 const collate<char>& 2648 use_facet<collate<char> >(const locale&); 2649 2650 extern template 2651 const numpunct<char>& 2652 use_facet<numpunct<char> >(const locale&); 2653 2654 extern template 2655 const num_put<char>& 2656 use_facet<num_put<char> >(const locale&); 2657 2658 extern template 2659 const num_get<char>& 2660 use_facet<num_get<char> >(const locale&); 2661 2662 extern template 2663 const moneypunct<char, true>& 2664 use_facet<moneypunct<char, true> >(const locale&); 2665 2666 extern template 2667 const moneypunct<char, false>& 2668 use_facet<moneypunct<char, false> >(const locale&); 2669 2670 extern template 2671 const money_put<char>& 2672 use_facet<money_put<char> >(const locale&); 2673 2674 extern template 2675 const money_get<char>& 2676 use_facet<money_get<char> >(const locale&); 2677 2678 extern template 2679 const __timepunct<char>& 2680 use_facet<__timepunct<char> >(const locale&); 2681 2682 extern template 2683 const time_put<char>& 2684 use_facet<time_put<char> >(const locale&); 2685 2686 extern template 2687 const time_get<char>& 2688 use_facet<time_get<char> >(const locale&); 2689 2690 extern template 2691 const messages<char>& 2692 use_facet<messages<char> >(const locale&); 2693 2694 extern template 2695 bool 2696 has_facet<ctype<char> >(const locale&); 2697 2698 extern template 2699 bool 2700 has_facet<codecvt<char, char, mbstate_t> >(const locale&); 2701 2702 extern template 2703 bool 2704 has_facet<collate<char> >(const locale&); 2705 2706 extern template 2707 bool 2708 has_facet<numpunct<char> >(const locale&); 2709 2710 extern template 2711 bool 2712 has_facet<num_put<char> >(const locale&); 2713 2714 extern template 2715 bool 2716 has_facet<num_get<char> >(const locale&); 2717 2718 extern template 2719 bool 2720 has_facet<moneypunct<char> >(const locale&); 2721 2722 extern template 2723 bool 2724 has_facet<money_put<char> >(const locale&); 2725 2726 extern template 2727 bool 2728 has_facet<money_get<char> >(const locale&); 2729 2730 extern template 2731 bool 2732 has_facet<__timepunct<char> >(const locale&); 2733 2734 extern template 2735 bool 2736 has_facet<time_put<char> >(const locale&); 2737 2738 extern template 2739 bool 2740 has_facet<time_get<char> >(const locale&); 2741 2742 extern template 2743 bool 2744 has_facet<messages<char> >(const locale&); 2745 2746 #ifdef _GLIBCXX_USE_WCHAR_T 2747 extern template class moneypunct<wchar_t, false>; 2748 extern template class moneypunct<wchar_t, true>; 2749 extern template class moneypunct_byname<wchar_t, false>; 2750 extern template class moneypunct_byname<wchar_t, true>; 2751 extern template class _GLIBCXX_LDBL_NAMESPACE money_get<wchar_t>; 2752 extern template class _GLIBCXX_LDBL_NAMESPACE money_put<wchar_t>; 2753 extern template class numpunct<wchar_t>; 2754 extern template class numpunct_byname<wchar_t>; 2755 extern template class _GLIBCXX_LDBL_NAMESPACE num_get<wchar_t>; 2756 extern template class _GLIBCXX_LDBL_NAMESPACE num_put<wchar_t>; 2757 extern template class __timepunct<wchar_t>; 2758 extern template class time_put<wchar_t>; 2759 extern template class time_put_byname<wchar_t>; 2760 extern template class time_get<wchar_t>; 2761 extern template class time_get_byname<wchar_t>; 2762 extern template class messages<wchar_t>; 2763 extern template class messages_byname<wchar_t>; 2764 extern template class ctype_byname<wchar_t>; 2765 extern template class codecvt_byname<wchar_t, char, mbstate_t>; 2766 extern template class collate<wchar_t>; 2767 extern template class collate_byname<wchar_t>; 2768 2769 extern template 2770 const codecvt<wchar_t, char, mbstate_t>& 2771 use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const&); 2772 2773 extern template 2774 const collate<wchar_t>& 2775 use_facet<collate<wchar_t> >(const locale&); 2776 2777 extern template 2778 const numpunct<wchar_t>& 2779 use_facet<numpunct<wchar_t> >(const locale&); 2780 2781 extern template 2782 const num_put<wchar_t>& 2783 use_facet<num_put<wchar_t> >(const locale&); 2784 2785 extern template 2786 const num_get<wchar_t>& 2787 use_facet<num_get<wchar_t> >(const locale&); 2788 2789 extern template 2790 const moneypunct<wchar_t, true>& 2791 use_facet<moneypunct<wchar_t, true> >(const locale&); 2792 2793 extern template 2794 const moneypunct<wchar_t, false>& 2795 use_facet<moneypunct<wchar_t, false> >(const locale&); 2796 2797 extern template 2798 const money_put<wchar_t>& 2799 use_facet<money_put<wchar_t> >(const locale&); 2800 2801 extern template 2802 const money_get<wchar_t>& 2803 use_facet<money_get<wchar_t> >(const locale&); 2804 2805 extern template 2806 const __timepunct<wchar_t>& 2807 use_facet<__timepunct<wchar_t> >(const locale&); 2808 2809 extern template 2810 const time_put<wchar_t>& 2811 use_facet<time_put<wchar_t> >(const locale&); 2812 2813 extern template 2814 const time_get<wchar_t>& 2815 use_facet<time_get<wchar_t> >(const locale&); 2816 2817 extern template 2818 const messages<wchar_t>& 2819 use_facet<messages<wchar_t> >(const locale&); 2820 2821 extern template 2822 bool 2823 has_facet<ctype<wchar_t> >(const locale&); 2824 2825 extern template 2826 bool 2827 has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&); 2828 2829 extern template 2830 bool 2831 has_facet<collate<wchar_t> >(const locale&); 2832 2833 extern template 2834 bool 2835 has_facet<numpunct<wchar_t> >(const locale&); 2836 2837 extern template 2838 bool 2839 has_facet<num_put<wchar_t> >(const locale&); 2840 2841 extern template 2842 bool 2843 has_facet<num_get<wchar_t> >(const locale&); 2844 2845 extern template 2846 bool 2847 has_facet<moneypunct<wchar_t> >(const locale&); 2848 2849 extern template 2850 bool 2851 has_facet<money_put<wchar_t> >(const locale&); 2852 2853 extern template 2854 bool 2855 has_facet<money_get<wchar_t> >(const locale&); 2856 2857 extern template 2858 bool 2859 has_facet<__timepunct<wchar_t> >(const locale&); 2860 2861 extern template 2862 bool 2863 has_facet<time_put<wchar_t> >(const locale&); 2864 2865 extern template 2866 bool 2867 has_facet<time_get<wchar_t> >(const locale&); 2868 2869 extern template 2870 bool 2871 has_facet<messages<wchar_t> >(const locale&); 2872 #endif 2873 #endif 2874 2875 _GLIBCXX_END_NAMESPACE 2876 2877 #endif 2878