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