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