locale_facets.tcc

00001 // Locale support -*- C++ -*- 00002 00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 2, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // You should have received a copy of the GNU General Public License along 00018 // with this library; see the file COPYING. If not, write to the Free 00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00020 // USA. 00021 00022 // As a special exception, you may use this file as part of a free software 00023 // library without restriction. Specifically, if other files instantiate 00024 // templates or use macros or inline functions from this file, or you compile 00025 // this file and link it with other files to produce an executable, this 00026 // file does not by itself cause the resulting executable to be covered by 00027 // the GNU General Public License. This exception does not however 00028 // invalidate any other reasons why the executable file might be covered by 00029 // the GNU General Public License. 00030 00031 // Warning: this file is not meant for user inclusion. Use <locale>. 00032 00033 #ifndef _LOCALE_FACETS_TCC 00034 #define _LOCALE_FACETS_TCC 1 00035 00036 #pragma GCC system_header 00037 00038 #include <limits> // For numeric_limits 00039 #include <typeinfo> // For bad_cast. 00040 #include <bits/streambuf_iterator.h> 00041 00042 namespace std 00043 { 00044 template<typename _Facet> 00045 locale 00046 locale::combine(const locale& __other) const 00047 { 00048 _Impl* __tmp = new _Impl(*_M_impl, 1); 00049 try 00050 { 00051 __tmp->_M_replace_facet(__other._M_impl, &_Facet::id); 00052 } 00053 catch(...) 00054 { 00055 __tmp->_M_remove_reference(); 00056 __throw_exception_again; 00057 } 00058 return locale(__tmp); 00059 } 00060 00061 template<typename _CharT, typename _Traits, typename _Alloc> 00062 bool 00063 locale::operator()(const basic_string<_CharT, _Traits, _Alloc>& __s1, 00064 const basic_string<_CharT, _Traits, _Alloc>& __s2) const 00065 { 00066 typedef std::collate<_CharT> __collate_type; 00067 const __collate_type& __collate = use_facet<__collate_type>(*this); 00068 return (__collate.compare(__s1.data(), __s1.data() + __s1.length(), 00069 __s2.data(), __s2.data() + __s2.length()) < 0); 00070 } 00071 00072 /** 00073 * @brief Test for the presence of a facet. 00074 * 00075 * has_facet tests the locale argument for the presence of the facet type 00076 * provided as the template parameter. Facets derived from the facet 00077 * parameter will also return true. 00078 * 00079 * @param Facet The facet type to test the presence of. 00080 * @param locale The locale to test. 00081 * @return true if locale contains a facet of type Facet, else false. 00082 */ 00083 template<typename _Facet> 00084 inline bool 00085 has_facet(const locale& __loc) throw() 00086 { 00087 const size_t __i = _Facet::id._M_id(); 00088 const locale::facet** __facets = __loc._M_impl->_M_facets; 00089 return (__i < __loc._M_impl->_M_facets_size && __facets[__i]); 00090 } 00091 00092 /** 00093 * @brief Return a facet. 00094 * 00095 * use_facet looks for and returns a reference to a facet of type Facet 00096 * where Facet is the template parameter. If has_facet(locale) is true, 00097 * there is a suitable facet to return. It throws std::bad_cast if the 00098 * locale doesn't contain a facet of type Facet. 00099 * 00100 * @param Facet The facet type to access. 00101 * @param locale The locale to use. 00102 * @return Reference to facet of type Facet. 00103 * @throw std::bad_cast if locale doesn't contain a facet of type Facet. 00104 */ 00105 template<typename _Facet> 00106 inline const _Facet& 00107 use_facet(const locale& __loc) 00108 { 00109 const size_t __i = _Facet::id._M_id(); 00110 const locale::facet** __facets = __loc._M_impl->_M_facets; 00111 if (!(__i < __loc._M_impl->_M_facets_size && __facets[__i])) 00112 __throw_bad_cast(); 00113 return static_cast<const _Facet&>(*__facets[__i]); 00114 } 00115 00116 // Routine to access a cache for the facet. If the cache didn't 00117 // exist before, it gets constructed on the fly. 00118 template<typename _Facet> 00119 struct __use_cache 00120 { 00121 const _Facet* 00122 operator() (const locale& __loc) const; 00123 }; 00124 00125 // Specializations. 00126 template<typename _CharT> 00127 struct __use_cache<__numpunct_cache<_CharT> > 00128 { 00129 const __numpunct_cache<_CharT>* 00130 operator() (const locale& __loc) const 00131 { 00132 const size_t __i = numpunct<_CharT>::id._M_id(); 00133 const locale::facet** __caches = __loc._M_impl->_M_caches; 00134 if (!__caches[__i]) 00135 { 00136 __numpunct_cache<_CharT>* __tmp = NULL; 00137 try 00138 { 00139 __tmp = new __numpunct_cache<_CharT>; 00140 __tmp->_M_cache(__loc); 00141 } 00142 catch(...) 00143 { 00144 delete __tmp; 00145 __throw_exception_again; 00146 } 00147 __loc._M_impl->_M_install_cache(__tmp, __i); 00148 } 00149 return static_cast<const __numpunct_cache<_CharT>*>(__caches[__i]); 00150 } 00151 }; 00152 00153 template<typename _CharT, bool _Intl> 00154 struct __use_cache<__moneypunct_cache<_CharT, _Intl> > 00155 { 00156 const __moneypunct_cache<_CharT, _Intl>* 00157 operator() (const locale& __loc) const 00158 { 00159 const size_t __i = moneypunct<_CharT, _Intl>::id._M_id(); 00160 const locale::facet** __caches = __loc._M_impl->_M_caches; 00161 if (!__caches[__i]) 00162 { 00163 __moneypunct_cache<_CharT, _Intl>* __tmp = NULL; 00164 try 00165 { 00166 __tmp = new __moneypunct_cache<_CharT, _Intl>; 00167 __tmp->_M_cache(__loc); 00168 } 00169 catch(...) 00170 { 00171 delete __tmp; 00172 __throw_exception_again; 00173 } 00174 __loc._M_impl->_M_install_cache(__tmp, __i); 00175 } 00176 return static_cast< 00177 const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]); 00178 } 00179 }; 00180 00181 template<typename _CharT> 00182 void 00183 __numpunct_cache<_CharT>::_M_cache(const locale& __loc) 00184 { 00185 _M_allocated = true; 00186 00187 const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc); 00188 00189 _M_grouping_size = __np.grouping().size(); 00190 char* __grouping = new char[_M_grouping_size]; 00191 __np.grouping().copy(__grouping, _M_grouping_size); 00192 _M_grouping = __grouping; 00193 _M_use_grouping = _M_grouping_size && __np.grouping()[0] != 0; 00194 00195 _M_truename_size = __np.truename().size(); 00196 _CharT* __truename = new _CharT[_M_truename_size]; 00197 __np.truename().copy(__truename, _M_truename_size); 00198 _M_truename = __truename; 00199 00200 _M_falsename_size = __np.falsename().size(); 00201 _CharT* __falsename = new _CharT[_M_falsename_size]; 00202 __np.falsename().copy(__falsename, _M_falsename_size); 00203 _M_falsename = __falsename; 00204 00205 _M_decimal_point = __np.decimal_point(); 00206 _M_thousands_sep = __np.thousands_sep(); 00207 00208 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc); 00209 __ct.widen(__num_base::_S_atoms_out, 00210 __num_base::_S_atoms_out + __num_base::_S_oend, _M_atoms_out); 00211 __ct.widen(__num_base::_S_atoms_in, 00212 __num_base::_S_atoms_in + __num_base::_S_iend, _M_atoms_in); 00213 } 00214 00215 template<typename _CharT, bool _Intl> 00216 void 00217 __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc) 00218 { 00219 _M_allocated = true; 00220 00221 const moneypunct<_CharT, _Intl>& __mp = 00222 use_facet<moneypunct<_CharT, _Intl> >(__loc); 00223 00224 _M_grouping_size = __mp.grouping().size(); 00225 char* __grouping = new char[_M_grouping_size]; 00226 __mp.grouping().copy(__grouping, _M_grouping_size); 00227 _M_grouping = __grouping; 00228 _M_use_grouping = _M_grouping_size && __mp.grouping()[0] != 0; 00229 00230 _M_decimal_point = __mp.decimal_point(); 00231 _M_thousands_sep = __mp.thousands_sep(); 00232 _M_frac_digits = __mp.frac_digits(); 00233 00234 _M_curr_symbol_size = __mp.curr_symbol().size(); 00235 _CharT* __curr_symbol = new _CharT[_M_curr_symbol_size]; 00236 __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size); 00237 _M_curr_symbol = __curr_symbol; 00238 00239 _M_positive_sign_size = __mp.positive_sign().size(); 00240 _CharT* __positive_sign = new _CharT[_M_positive_sign_size]; 00241 __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size); 00242 _M_positive_sign = __positive_sign; 00243 00244 _M_negative_sign_size = __mp.negative_sign().size(); 00245 _CharT* __negative_sign = new _CharT[_M_negative_sign_size]; 00246 __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size); 00247 _M_negative_sign = __negative_sign; 00248 00249 _M_pos_format = __mp.pos_format(); 00250 _M_neg_format = __mp.neg_format(); 00251 00252 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc); 00253 __ct.widen(money_base::_S_atoms, 00254 money_base::_S_atoms + money_base::_S_end, _M_atoms); 00255 } 00256 00257 00258 // Used by both numeric and monetary facets. 00259 // Check to make sure that the __grouping_tmp string constructed in 00260 // money_get or num_get matches the canonical grouping for a given 00261 // locale. 00262 // __grouping_tmp is parsed L to R 00263 // 1,222,444 == __grouping_tmp of "\1\3\3" 00264 // __grouping is parsed R to L 00265 // 1,222,444 == __grouping of "\3" == "\3\3\3" 00266 static bool 00267 __verify_grouping(const char* __grouping, size_t __grouping_size, 00268 const string& __grouping_tmp); 00269 00270 template<typename _CharT, typename _InIter> 00271 _InIter 00272 num_get<_CharT, _InIter>:: 00273 _M_extract_float(_InIter __beg, _InIter __end, ios_base& __io, 00274 ios_base::iostate& __err, string& __xtrc) const 00275 { 00276 typedef char_traits<_CharT> __traits_type; 00277 typedef typename numpunct<_CharT>::__cache_type __cache_type; 00278 __use_cache<__cache_type> __uc; 00279 const locale& __loc = __io._M_getloc(); 00280 const __cache_type* __lc = __uc(__loc); 00281 const _CharT* __lit = __lc->_M_atoms_in; 00282 00283 // True if a mantissa is found. 00284 bool __found_mantissa = false; 00285 00286 // First check for sign. 00287 if (__beg != __end) 00288 { 00289 const char_type __c = *__beg; 00290 const bool __plus = __c == __lit[__num_base::_S_iplus]; 00291 if ((__plus || __c == __lit[__num_base::_S_iminus]) 00292 && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) 00293 && !(__c == __lc->_M_decimal_point)) 00294 { 00295 __xtrc += __plus ? '+' : '-'; 00296 ++__beg; 00297 } 00298 } 00299 00300 // Next, look for leading zeros. 00301 while (__beg != __end) 00302 { 00303 const char_type __c = *__beg; 00304 if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep 00305 || __c == __lc->_M_decimal_point) 00306 break; 00307 else if (__c == __lit[__num_base::_S_izero]) 00308 { 00309 if (!__found_mantissa) 00310 { 00311 __xtrc += '0'; 00312 __found_mantissa = true; 00313 } 00314 ++__beg; 00315 } 00316 else 00317 break; 00318 } 00319 00320 // Only need acceptable digits for floating point numbers. 00321 bool __found_dec = false; 00322 bool __found_sci = false; 00323 string __found_grouping; 00324 if (__lc->_M_use_grouping) 00325 __found_grouping.reserve(32); 00326 int __sep_pos = 0; 00327 const char_type* __lit_zero = __lit + __num_base::_S_izero; 00328 while (__beg != __end) 00329 { 00330 // According to 22.2.2.1.2, p8-9, first look for thousands_sep 00331 // and decimal_point. 00332 const char_type __c = *__beg; 00333 if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) 00334 { 00335 if (!__found_dec && !__found_sci) 00336 { 00337 // NB: Thousands separator at the beginning of a string 00338 // is a no-no, as is two consecutive thousands separators. 00339 if (__sep_pos) 00340 { 00341 __found_grouping += static_cast<char>(__sep_pos); 00342 __sep_pos = 0; 00343 ++__beg; 00344 } 00345 else 00346 { 00347 __err |= ios_base::failbit; 00348 break; 00349 } 00350 } 00351 else 00352 break; 00353 } 00354 else if (__c == __lc->_M_decimal_point) 00355 { 00356 if (!__found_dec && !__found_sci) 00357 { 00358 // If no grouping chars are seen, no grouping check 00359 // is applied. Therefore __found_grouping is adjusted 00360 // only if decimal_point comes after some thousands_sep. 00361 if (__found_grouping.size()) 00362 __found_grouping += static_cast<char>(__sep_pos); 00363 __xtrc += '.'; 00364 __found_dec = true; 00365 ++__beg; 00366 } 00367 else 00368 break; 00369 } 00370 else 00371 { 00372 const char_type* __q = __traits_type::find(__lit_zero, 10, __c); 00373 if (__q) 00374 { 00375 __xtrc += __num_base::_S_atoms_in[__q - __lit]; 00376 __found_mantissa = true; 00377 ++__sep_pos; 00378 ++__beg; 00379 } 00380 else if ((__c == __lit[__num_base::_S_ie] 00381 || __c == __lit[__num_base::_S_iE]) 00382 && __found_mantissa && !__found_sci) 00383 { 00384 // Scientific notation. 00385 if (__found_grouping.size() && !__found_dec) 00386 __found_grouping += static_cast<char>(__sep_pos); 00387 __xtrc += 'e'; 00388 __found_sci = true; 00389 00390 // Remove optional plus or minus sign, if they exist. 00391 if (++__beg != __end) 00392 { 00393 const bool __plus = *__beg == __lit[__num_base::_S_iplus]; 00394 if ((__plus || *__beg == __lit[__num_base::_S_iminus]) 00395 && !(__lc->_M_use_grouping 00396 && *__beg == __lc->_M_thousands_sep) 00397 && !(*__beg == __lc->_M_decimal_point)) 00398 { 00399 __xtrc += __plus ? '+' : '-'; 00400 ++__beg; 00401 } 00402 } 00403 } 00404 else 00405 // Not a valid input item. 00406 break; 00407 } 00408 } 00409 00410 // Digit grouping is checked. If grouping and found_grouping don't 00411 // match, then get very very upset, and set failbit. 00412 if (__found_grouping.size()) 00413 { 00414 // Add the ending grouping if a decimal or 'e'/'E' wasn't found. 00415 if (!__found_dec && !__found_sci) 00416 __found_grouping += static_cast<char>(__sep_pos); 00417 00418 if (!std::__verify_grouping(__lc->_M_grouping, 00419 __lc->_M_grouping_size, 00420 __found_grouping)) 00421 __err |= ios_base::failbit; 00422 } 00423 00424 // Finish up. 00425 if (__beg == __end) 00426 __err |= ios_base::eofbit; 00427 return __beg; 00428 } 00429 00430 template<typename _CharT, typename _InIter> 00431 template<typename _ValueT> 00432 _InIter 00433 num_get<_CharT, _InIter>:: 00434 _M_extract_int(_InIter __beg, _InIter __end, ios_base& __io, 00435 ios_base::iostate& __err, _ValueT& __v) const 00436 { 00437 typedef char_traits<_CharT> __traits_type; 00438 typedef typename numpunct<_CharT>::__cache_type __cache_type; 00439 __use_cache<__cache_type> __uc; 00440 const locale& __loc = __io._M_getloc(); 00441 const __cache_type* __lc = __uc(__loc); 00442 const _CharT* __lit = __lc->_M_atoms_in; 00443 00444 // NB: Iff __basefield == 0, __base can change based on contents. 00445 const ios_base::fmtflags __basefield = __io.flags() 00446 & ios_base::basefield; 00447 const bool __oct = __basefield == ios_base::oct; 00448 int __base = __oct ? 8 : (__basefield == ios_base::hex ? 16 : 10); 00449 00450 // True if numeric digits are found. 00451 bool __found_num = false; 00452 00453 // First check for sign. 00454 bool __negative = false; 00455 if (__beg != __end) 00456 { 00457 const char_type __c = *__beg; 00458 if (numeric_limits<_ValueT>::is_signed) 00459 __negative = __c == __lit[__num_base::_S_iminus]; 00460 if ((__negative || __c == __lit[__num_base::_S_iplus]) 00461 && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) 00462 && !(__c == __lc->_M_decimal_point)) 00463 ++__beg; 00464 } 00465 00466 // Next, look for leading zeros and check required digits 00467 // for base formats. 00468 while (__beg != __end) 00469 { 00470 const char_type __c = *__beg; 00471 if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep 00472 || __c == __lc->_M_decimal_point) 00473 break; 00474 else if (__c == __lit[__num_base::_S_izero] 00475 && (!__found_num || __base == 10)) 00476 { 00477 __found_num = true; 00478 ++__beg; 00479 } 00480 else if (__found_num) 00481 { 00482 if (__c == __lit[__num_base::_S_ix] 00483 || __c == __lit[__num_base::_S_iX]) 00484 { 00485 if (__basefield == 0) 00486 __base = 16; 00487 if (__base == 16) 00488 { 00489 __found_num = false; 00490 ++__beg; 00491 } 00492 } 00493 else if (__basefield == 0) 00494 __base = 8; 00495 break; 00496 } 00497 else 00498 break; 00499 } 00500 00501 // At this point, base is determined. If not hex, only allow 00502 // base digits as valid input. 00503 const size_t __len = (__base == 16 ? __num_base::_S_iend 00504 - __num_base::_S_izero : __base); 00505 00506 // Extract. 00507 string __found_grouping; 00508 if (__lc->_M_use_grouping) 00509 __found_grouping.reserve(32); 00510 int __sep_pos = 0; 00511 bool __overflow = false; 00512 _ValueT __result = 0; 00513 const char_type* __lit_zero = __lit + __num_base::_S_izero; 00514 if (__negative) 00515 { 00516 const _ValueT __min = numeric_limits<_ValueT>::min() / __base; 00517 for (; __beg != __end; ++__beg) 00518 { 00519 // According to 22.2.2.1.2, p8-9, first look for thousands_sep 00520 // and decimal_point. 00521 const char_type __c = *__beg; 00522 if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) 00523 { 00524 // NB: Thousands separator at the beginning of a string 00525 // is a no-no, as is two consecutive thousands separators. 00526 if (__sep_pos) 00527 { 00528 __found_grouping += static_cast<char>(__sep_pos); 00529 __sep_pos = 0; 00530 } 00531 else 00532 { 00533 __err |= ios_base::failbit; 00534 break; 00535 } 00536 } 00537 else if (__c == __lc->_M_decimal_point) 00538 break; 00539 else 00540 { 00541 const char_type* __q = __traits_type::find(__lit_zero, 00542 __len, __c); 00543 if (__q) 00544 { 00545 int __digit = __q - __lit_zero; 00546 if (__digit > 15) 00547 __digit -= 6; 00548 if (__result < __min) 00549 __overflow = true; 00550 else 00551 { 00552 const _ValueT __new_result = (__result * __base 00553 - __digit); 00554 __overflow |= __new_result > __result; 00555 __result = __new_result; 00556 ++__sep_pos; 00557 __found_num = true; 00558 } 00559 } 00560 else 00561 // Not a valid input item. 00562 break; 00563 } 00564 } 00565 } 00566 else 00567 { 00568 const _ValueT __max = numeric_limits<_ValueT>::max() / __base; 00569 for (; __beg != __end; ++__beg) 00570 { 00571 const char_type __c = *__beg; 00572 if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep) 00573 { 00574 if (__sep_pos) 00575 { 00576 __found_grouping += static_cast<char>(__sep_pos); 00577 __sep_pos = 0; 00578 } 00579 else 00580 { 00581 __err |= ios_base::failbit; 00582 break; 00583 } 00584 } 00585 else if (__c == __lc->_M_decimal_point) 00586 break; 00587 else 00588 { 00589 const char_type* __q = __traits_type::find(__lit_zero, 00590 __len, __c); 00591 if (__q) 00592 { 00593 int __digit = __q - __lit_zero; 00594 if (__digit > 15) 00595 __digit -= 6; 00596 if (__result > __max) 00597 __overflow = true; 00598 else 00599 { 00600 const _ValueT __new_result = (__result * __base 00601 + __digit); 00602 __overflow |= __new_result < __result; 00603 __result = __new_result; 00604 ++__sep_pos; 00605 __found_num = true; 00606 } 00607 } 00608 else 00609 break; 00610 } 00611 } 00612 } 00613 00614 // Digit grouping is checked. If grouping and found_grouping don't 00615 // match, then get very very upset, and set failbit. 00616 if (__found_grouping.size()) 00617 { 00618 // Add the ending grouping. 00619 __found_grouping += static_cast<char>(__sep_pos); 00620 00621 if (!std::__verify_grouping(__lc->_M_grouping, 00622 __lc->_M_grouping_size, 00623 __found_grouping)) 00624 __err |= ios_base::failbit; 00625 } 00626 00627 if (!(__err & ios_base::failbit) && !__overflow 00628 && __found_num) 00629 __v = __result; 00630 else 00631 __err |= ios_base::failbit; 00632 00633 if (__beg == __end) 00634 __err |= ios_base::eofbit; 00635 return __beg; 00636 } 00637 00638 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00639 // 17. Bad bool parsing 00640 template<typename _CharT, typename _InIter> 00641 _InIter 00642 num_get<_CharT, _InIter>:: 00643 do_get(iter_type __beg, iter_type __end, ios_base& __io, 00644 ios_base::iostate& __err, bool& __v) const 00645 { 00646 if (!(__io.flags() & ios_base::boolalpha)) 00647 { 00648 // Parse bool values as long. 00649 // NB: We can't just call do_get(long) here, as it might 00650 // refer to a derived class. 00651 long __l = -1; 00652 __beg = _M_extract_int(__beg, __end, __io, __err, __l); 00653 if (__l == 0 || __l == 1) 00654 __v = __l; 00655 else 00656 __err |= ios_base::failbit; 00657 } 00658 else 00659 { 00660 // Parse bool values as alphanumeric. 00661 typedef typename numpunct<_CharT>::__cache_type __cache_type; 00662 __use_cache<__cache_type> __uc; 00663 const locale& __loc = __io._M_getloc(); 00664 const __cache_type* __lc = __uc(__loc); 00665 00666 bool __testf = true; 00667 bool __testt = true; 00668 size_t __n; 00669 for (__n = 0; __beg != __end; ++__n, ++__beg) 00670 { 00671 if (__testf) 00672 if (__n < __lc->_M_falsename_size) 00673 __testf = *__beg == __lc->_M_falsename[__n]; 00674 else 00675 break; 00676 00677 if (__testt) 00678 if (__n < __lc->_M_truename_size) 00679 __testt = *__beg == __lc->_M_truename[__n]; 00680 else 00681 break; 00682 00683 if (!__testf && !__testt) 00684 break; 00685 } 00686 if (__testf && __n == __lc->_M_falsename_size) 00687 __v = 0; 00688 else if (__testt && __n == __lc->_M_truename_size) 00689 __v = 1; 00690 else 00691 __err |= ios_base::failbit; 00692 00693 if (__beg == __end) 00694 __err |= ios_base::eofbit; 00695 } 00696 return __beg; 00697 } 00698 00699 template<typename _CharT, typename _InIter> 00700 _InIter 00701 num_get<_CharT, _InIter>:: 00702 do_get(iter_type __beg, iter_type __end, ios_base& __io, 00703 ios_base::iostate& __err, long& __v) const 00704 { return _M_extract_int(__beg, __end, __io, __err, __v); } 00705 00706 template<typename _CharT, typename _InIter> 00707 _InIter 00708 num_get<_CharT, _InIter>:: 00709 do_get(iter_type __beg, iter_type __end, ios_base& __io, 00710 ios_base::iostate& __err, unsigned short& __v) const 00711 { return _M_extract_int(__beg, __end, __io, __err, __v); } 00712 00713 template<typename _CharT, typename _InIter> 00714 _InIter 00715 num_get<_CharT, _InIter>:: 00716 do_get(iter_type __beg, iter_type __end, ios_base& __io, 00717 ios_base::iostate& __err, unsigned int& __v) const 00718 { return _M_extract_int(__beg, __end, __io, __err, __v); } 00719 00720 template<typename _CharT, typename _InIter> 00721 _InIter 00722 num_get<_CharT, _InIter>:: 00723 do_get(iter_type __beg, iter_type __end, ios_base& __io, 00724 ios_base::iostate& __err, unsigned long& __v) const 00725 { return _M_extract_int(__beg, __end, __io, __err, __v); } 00726 00727 #ifdef _GLIBCXX_USE_LONG_LONG 00728 template<typename _CharT, typename _InIter> 00729 _InIter 00730 num_get<_CharT, _InIter>:: 00731 do_get(iter_type __beg, iter_type __end, ios_base& __io, 00732 ios_base::iostate& __err, long long& __v) const 00733 { return _M_extract_int(__beg, __end, __io, __err, __v); } 00734 00735 template<typename _CharT, typename _InIter> 00736 _InIter 00737 num_get<_CharT, _InIter>:: 00738 do_get(iter_type __beg, iter_type __end, ios_base& __io, 00739 ios_base::iostate& __err, unsigned long long& __v) const 00740 { return _M_extract_int(__beg, __end, __io, __err, __v); } 00741 #endif 00742 00743 template<typename _CharT, typename _InIter> 00744 _InIter 00745 num_get<_CharT, _InIter>:: 00746 do_get(iter_type __beg, iter_type __end, ios_base& __io, 00747 ios_base::iostate& __err, float& __v) const 00748 { 00749 string __xtrc; 00750 __xtrc.reserve(32); 00751 __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); 00752 std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); 00753 return __beg; 00754 } 00755 00756 template<typename _CharT, typename _InIter> 00757 _InIter 00758 num_get<_CharT, _InIter>:: 00759 do_get(iter_type __beg, iter_type __end, ios_base& __io, 00760 ios_base::iostate& __err, double& __v) const 00761 { 00762 string __xtrc; 00763 __xtrc.reserve(32); 00764 __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); 00765 std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); 00766 return __beg; 00767 } 00768 00769 template<typename _CharT, typename _InIter> 00770 _InIter 00771 num_get<_CharT, _InIter>:: 00772 do_get(iter_type __beg, iter_type __end, ios_base& __io, 00773 ios_base::iostate& __err, long double& __v) const 00774 { 00775 string __xtrc; 00776 __xtrc.reserve(32); 00777 __beg = _M_extract_float(__beg, __end, __io, __err, __xtrc); 00778 std::__convert_to_v(__xtrc.c_str(), __v, __err, _S_get_c_locale()); 00779 return __beg; 00780 } 00781 00782 template<typename _CharT, typename _InIter> 00783 _InIter 00784 num_get<_CharT, _InIter>:: 00785 do_get(iter_type __beg, iter_type __end, ios_base& __io, 00786 ios_base::iostate& __err, void*& __v) const 00787 { 00788 // Prepare for hex formatted input. 00789 typedef ios_base::fmtflags fmtflags; 00790 const fmtflags __fmt = __io.flags(); 00791 __io.flags(__fmt & ~ios_base::basefield | ios_base::hex); 00792 00793 unsigned long __ul; 00794 __beg = _M_extract_int(__beg, __end, __io, __err, __ul); 00795 00796 // Reset from hex formatted input. 00797 __io.flags(__fmt); 00798 00799 if (!(__err & ios_base::failbit)) 00800 __v = reinterpret_cast<void*>(__ul); 00801 else 00802 __err |= ios_base::failbit; 00803 return __beg; 00804 } 00805 00806 // For use by integer and floating-point types after they have been 00807 // converted into a char_type string. 00808 template<typename _CharT, typename _OutIter> 00809 void 00810 num_put<_CharT, _OutIter>:: 00811 _M_pad(_CharT __fill, streamsize __w, ios_base& __io, 00812 _CharT* __new, const _CharT* __cs, int& __len) const 00813 { 00814 // [22.2.2.2.2] Stage 3. 00815 // If necessary, pad. 00816 __pad<_CharT, char_traits<_CharT> >::_S_pad(__io, __fill, __new, __cs, 00817 __w, __len, true); 00818 __len = static_cast<int>(__w); 00819 } 00820 00821 // Forwarding functions to peel signed from unsigned integer types. 00822 template<typename _CharT> 00823 inline int 00824 __int_to_char(_CharT* __bufend, long __v, const _CharT* __lit, 00825 ios_base::fmtflags __flags) 00826 { 00827 unsigned long __ul = static_cast<unsigned long>(__v); 00828 bool __neg = false; 00829 if (__v < 0) 00830 { 00831 __ul = -__ul; 00832 __neg = true; 00833 } 00834 return __int_to_char(__bufend, __ul, __lit, __flags, __neg); 00835 } 00836 00837 template<typename _CharT> 00838 inline int 00839 __int_to_char(_CharT* __bufend, unsigned long __v, const _CharT* __lit, 00840 ios_base::fmtflags __flags) 00841 { 00842 // About showpos, see Table 60 and C99 7.19.6.1, p6 (+). 00843 return __int_to_char(__bufend, __v, __lit, 00844 __flags & ~ios_base::showpos, false); 00845 } 00846 00847 #ifdef _GLIBCXX_USE_LONG_LONG 00848 template<typename _CharT> 00849 inline int 00850 __int_to_char(_CharT* __bufend, long long __v, const _CharT* __lit, 00851 ios_base::fmtflags __flags) 00852 { 00853 unsigned long long __ull = static_cast<unsigned long long>(__v); 00854 bool __neg = false; 00855 if (__v < 0) 00856 { 00857 __ull = -__ull; 00858 __neg = true; 00859 } 00860 return __int_to_char(__bufend, __ull, __lit, __flags, __neg); 00861 } 00862 00863 template<typename _CharT> 00864 inline int 00865 __int_to_char(_CharT* __bufend, unsigned long long __v, 00866 const _CharT* __lit, ios_base::fmtflags __flags) 00867 { return __int_to_char(__bufend, __v, __lit, 00868 __flags & ~ios_base::showpos, false); } 00869 #endif 00870 00871 template<typename _CharT, typename _ValueT> 00872 int 00873 __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit, 00874 ios_base::fmtflags __flags, bool __neg) 00875 { 00876 // Don't write base if already 0. 00877 const bool __showbase = (__flags & ios_base::showbase) && __v; 00878 const ios_base::fmtflags __basefield = __flags & ios_base::basefield; 00879 _CharT* __buf = __bufend - 1; 00880 00881 if (__builtin_expect(__basefield != ios_base::oct && 00882 __basefield != ios_base::hex, true)) 00883 { 00884 // Decimal. 00885 do 00886 { 00887 *__buf-- = __lit[(__v % 10) + __num_base::_S_odigits]; 00888 __v /= 10; 00889 } 00890 while (__v != 0); 00891 if (__neg) 00892 *__buf-- = __lit[__num_base::_S_ominus]; 00893 else if (__flags & ios_base::showpos) 00894 *__buf-- = __lit[__num_base::_S_oplus]; 00895 } 00896 else if (__basefield == ios_base::oct) 00897 { 00898 // Octal. 00899 do 00900 { 00901 *__buf-- = __lit[(__v & 0x7) + __num_base::_S_odigits]; 00902 __v >>= 3; 00903 } 00904 while (__v != 0); 00905 if (__showbase) 00906 *__buf-- = __lit[__num_base::_S_odigits]; 00907 } 00908 else 00909 { 00910 // Hex. 00911 const bool __uppercase = __flags & ios_base::uppercase; 00912 const int __case_offset = __uppercase ? __num_base::_S_oudigits 00913 : __num_base::_S_odigits; 00914 do 00915 { 00916 *__buf-- = __lit[(__v & 0xf) + __case_offset]; 00917 __v >>= 4; 00918 } 00919 while (__v != 0); 00920 if (__showbase) 00921 { 00922 // 'x' or 'X' 00923 *__buf-- = __lit[__num_base::_S_ox + __uppercase]; 00924 // '0' 00925 *__buf-- = __lit[__num_base::_S_odigits]; 00926 } 00927 } 00928 return __bufend - __buf - 1; 00929 } 00930 00931 template<typename _CharT, typename _OutIter> 00932 void 00933 num_put<_CharT, _OutIter>:: 00934 _M_group_int(const char* __grouping, size_t __grouping_size, _CharT __sep, 00935 ios_base& __io, _CharT* __new, _CharT* __cs, int& __len) const 00936 { 00937 // By itself __add_grouping cannot deal correctly with __cs when 00938 // ios::showbase is set and ios_base::oct || ios_base::hex. 00939 // Therefore we take care "by hand" of the initial 0, 0x or 0X. 00940 // However, remember that the latter do not occur if the number 00941 // printed is '0' (__len == 1). 00942 streamsize __off = 0; 00943 const ios_base::fmtflags __basefield = __io.flags() 00944 & ios_base::basefield; 00945 if ((__io.flags() & ios_base::showbase) && __len > 1) 00946 if (__basefield == ios_base::oct) 00947 { 00948 __off = 1; 00949 __new[0] = __cs[0]; 00950 } 00951 else if (__basefield == ios_base::hex) 00952 { 00953 __off = 2; 00954 __new[0] = __cs[0]; 00955 __new[1] = __cs[1]; 00956 } 00957 _CharT* __p = std::__add_grouping(__new + __off, __sep, __grouping, 00958 __grouping_size, __cs + __off, 00959 __cs + __len); 00960 __len = __p - __new; 00961 } 00962 00963 template<typename _CharT, typename _OutIter> 00964 template<typename _ValueT> 00965 _OutIter 00966 num_put<_CharT, _OutIter>:: 00967 _M_insert_int(_OutIter __s, ios_base& __io, _CharT __fill, 00968 _ValueT __v) const 00969 { 00970 typedef typename numpunct<_CharT>::__cache_type __cache_type; 00971 __use_cache<__cache_type> __uc; 00972 const locale& __loc = __io._M_getloc(); 00973 const __cache_type* __lc = __uc(__loc); 00974 const _CharT* __lit = __lc->_M_atoms_out; 00975 00976 // Long enough to hold hex, dec, and octal representations. 00977 const int __ilen = 4 * sizeof(_ValueT); 00978 _CharT* __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 00979 * __ilen)); 00980 00981 // [22.2.2.2.2] Stage 1, numeric conversion to character. 00982 // Result is returned right-justified in the buffer. 00983 int __len; 00984 __len = __int_to_char(__cs + __ilen, __v, __lit, __io.flags()); 00985 __cs += __ilen - __len; 00986 00987 // Add grouping, if necessary. 00988 if (__lc->_M_use_grouping) 00989 { 00990 // Grouping can add (almost) as many separators as the 00991 // number of digits, but no more. 00992 _CharT* __cs2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 00993 * __len * 2)); 00994 _M_group_int(__lc->_M_grouping, __lc->_M_grouping_size, 00995 __lc->_M_thousands_sep, __io, __cs2, __cs, __len); 00996 __cs = __cs2; 00997 } 00998 00999 // Pad. 01000 const streamsize __w = __io.width(); 01001 if (__w > static_cast<streamsize>(__len)) 01002 { 01003 _CharT* __cs3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 01004 * __w)); 01005 _M_pad(__fill, __w, __io, __cs3, __cs, __len); 01006 __cs = __cs3; 01007 } 01008 __io.width(0); 01009 01010 // [22.2.2.2.2] Stage 4. 01011 // Write resulting, fully-formatted string to output iterator. 01012 return std::__write(__s, __cs, __len); 01013 } 01014 01015 template<typename _CharT, typename _OutIter> 01016 void 01017 num_put<_CharT, _OutIter>:: 01018 _M_group_float(const char* __grouping, size_t __grouping_size, 01019 _CharT __sep, const _CharT* __p, _CharT* __new, 01020 _CharT* __cs, int& __len) const 01021 { 01022 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01023 // 282. What types does numpunct grouping refer to? 01024 // Add grouping, if necessary. 01025 const int __declen = __p ? __p - __cs : __len; 01026 _CharT* __p2 = std::__add_grouping(__new, __sep, __grouping, 01027 __grouping_size, 01028 __cs, __cs + __declen); 01029 01030 // Tack on decimal part. 01031 int __newlen = __p2 - __new; 01032 if (__p) 01033 { 01034 char_traits<_CharT>::copy(__p2, __p, __len - __declen); 01035 __newlen += __len - __declen; 01036 } 01037 __len = __newlen; 01038 } 01039 01040 // The following code uses snprintf (or sprintf(), when 01041 // _GLIBCXX_USE_C99 is not defined) to convert floating point values 01042 // for insertion into a stream. An optimization would be to replace 01043 // them with code that works directly on a wide buffer and then use 01044 // __pad to do the padding. It would be good to replace them anyway 01045 // to gain back the efficiency that C++ provides by knowing up front 01046 // the type of the values to insert. Also, sprintf is dangerous 01047 // since may lead to accidental buffer overruns. This 01048 // implementation follows the C++ standard fairly directly as 01049 // outlined in 22.2.2.2 [lib.locale.num.put] 01050 template<typename _CharT, typename _OutIter> 01051 template<typename _ValueT> 01052 _OutIter 01053 num_put<_CharT, _OutIter>:: 01054 _M_insert_float(_OutIter __s, ios_base& __io, _CharT __fill, char __mod, 01055 _ValueT __v) const 01056 { 01057 typedef typename numpunct<_CharT>::__cache_type __cache_type; 01058 __use_cache<__cache_type> __uc; 01059 const locale& __loc = __io._M_getloc(); 01060 const __cache_type* __lc = __uc(__loc); 01061 01062 // Use default precision if out of range. 01063 streamsize __prec = __io.precision(); 01064 if (__prec < static_cast<streamsize>(0)) 01065 __prec = static_cast<streamsize>(6); 01066 01067 const int __max_digits = numeric_limits<_ValueT>::digits10; 01068 01069 // [22.2.2.2.2] Stage 1, numeric conversion to character. 01070 int __len; 01071 // Long enough for the max format spec. 01072 char __fbuf[16]; 01073 01074 #ifdef _GLIBCXX_USE_C99 01075 // First try a buffer perhaps big enough (most probably sufficient 01076 // for non-ios_base::fixed outputs) 01077 int __cs_size = __max_digits * 3; 01078 char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 01079 01080 __num_base::_S_format_float(__io, __fbuf, __mod); 01081 __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v, 01082 _S_get_c_locale(), __prec); 01083 01084 // If the buffer was not large enough, try again with the correct size. 01085 if (__len >= __cs_size) 01086 { 01087 __cs_size = __len + 1; 01088 __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 01089 __len = std::__convert_from_v(__cs, __cs_size, __fbuf, __v, 01090 _S_get_c_locale(), __prec); 01091 } 01092 #else 01093 // Consider the possibility of long ios_base::fixed outputs 01094 const bool __fixed = __io.flags() & ios_base::fixed; 01095 const int __max_exp = numeric_limits<_ValueT>::max_exponent10; 01096 01097 // The size of the output string is computed as follows. 01098 // ios_base::fixed outputs may need up to __max_exp + 1 chars 01099 // for the integer part + __prec chars for the fractional part 01100 // + 3 chars for sign, decimal point, '\0'. On the other hand, 01101 // for non-fixed outputs __max_digits * 2 + __prec chars are 01102 // largely sufficient. 01103 const int __cs_size = __fixed ? __max_exp + __prec + 4 01104 : __max_digits * 2 + __prec; 01105 char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 01106 01107 __num_base::_S_format_float(__io, __fbuf, __mod); 01108 __len = std::__convert_from_v(__cs, 0, __fbuf, __v, 01109 _S_get_c_locale(), __prec); 01110 #endif 01111 01112 // [22.2.2.2.2] Stage 2, convert to char_type, using correct 01113 // numpunct.decimal_point() values for '.' and adding grouping. 01114 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 01115 01116 _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 01117 * __len)); 01118 __ctype.widen(__cs, __cs + __len, __ws); 01119 01120 // Replace decimal point. 01121 const _CharT __cdec = __ctype.widen('.'); 01122 const _CharT __dec = __lc->_M_decimal_point; 01123 const _CharT* __p = char_traits<_CharT>::find(__ws, __len, __cdec); 01124 if (__p) 01125 __ws[__p - __ws] = __dec; 01126 01127 // Add grouping, if necessary. 01128 if (__lc->_M_use_grouping) 01129 { 01130 // Grouping can add (almost) as many separators as the 01131 // number of digits, but no more. 01132 _CharT* __ws2 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 01133 * __len * 2)); 01134 _M_group_float(__lc->_M_grouping, __lc->_M_grouping_size, 01135 __lc->_M_thousands_sep, __p, __ws2, __ws, __len); 01136 __ws = __ws2; 01137 } 01138 01139 // Pad. 01140 const streamsize __w = __io.width(); 01141 if (__w > static_cast<streamsize>(__len)) 01142 { 01143 _CharT* __ws3 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 01144 * __w)); 01145 _M_pad(__fill, __w, __io, __ws3, __ws, __len); 01146 __ws = __ws3; 01147 } 01148 __io.width(0); 01149 01150 // [22.2.2.2.2] Stage 4. 01151 // Write resulting, fully-formatted string to output iterator. 01152 return std::__write(__s, __ws, __len); 01153 } 01154 01155 template<typename _CharT, typename _OutIter> 01156 _OutIter 01157 num_put<_CharT, _OutIter>:: 01158 do_put(iter_type __s, ios_base& __io, char_type __fill, bool __v) const 01159 { 01160 const ios_base::fmtflags __flags = __io.flags(); 01161 if ((__flags & ios_base::boolalpha) == 0) 01162 { 01163 const long __l = __v; 01164 __s = _M_insert_int(__s, __io, __fill, __l); 01165 } 01166 else 01167 { 01168 typedef typename numpunct<_CharT>::__cache_type __cache_type; 01169 __use_cache<__cache_type> __uc; 01170 const locale& __loc = __io._M_getloc(); 01171 const __cache_type* __lc = __uc(__loc); 01172 01173 const _CharT* __name = __v ? __lc->_M_truename 01174 : __lc->_M_falsename; 01175 int __len = __v ? __lc->_M_truename_size 01176 : __lc->_M_falsename_size; 01177 01178 const streamsize __w = __io.width(); 01179 if (__w > static_cast<streamsize>(__len)) 01180 { 01181 _CharT* __cs 01182 = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 01183 * __w)); 01184 _M_pad(__fill, __w, __io, __cs, __name, __len); 01185 __name = __cs; 01186 } 01187 __io.width(0); 01188 __s = std::__write(__s, __name, __len); 01189 } 01190 return __s; 01191 } 01192 01193 template<typename _CharT, typename _OutIter> 01194 _OutIter 01195 num_put<_CharT, _OutIter>:: 01196 do_put(iter_type __s, ios_base& __io, char_type __fill, long __v) const 01197 { return _M_insert_int(__s, __io, __fill, __v); } 01198 01199 template<typename _CharT, typename _OutIter> 01200 _OutIter 01201 num_put<_CharT, _OutIter>:: 01202 do_put(iter_type __s, ios_base& __io, char_type __fill, 01203 unsigned long __v) const 01204 { return _M_insert_int(__s, __io, __fill, __v); } 01205 01206 #ifdef _GLIBCXX_USE_LONG_LONG 01207 template<typename _CharT, typename _OutIter> 01208 _OutIter 01209 num_put<_CharT, _OutIter>:: 01210 do_put(iter_type __s, ios_base& __b, char_type __fill, long long __v) const 01211 { return _M_insert_int(__s, __b, __fill, __v); } 01212 01213 template<typename _CharT, typename _OutIter> 01214 _OutIter 01215 num_put<_CharT, _OutIter>:: 01216 do_put(iter_type __s, ios_base& __io, char_type __fill, 01217 unsigned long long __v) const 01218 { return _M_insert_int(__s, __io, __fill, __v); } 01219 #endif 01220 01221 template<typename _CharT, typename _OutIter> 01222 _OutIter 01223 num_put<_CharT, _OutIter>:: 01224 do_put(iter_type __s, ios_base& __io, char_type __fill, double __v) const 01225 { return _M_insert_float(__s, __io, __fill, char(), __v); } 01226 01227 template<typename _CharT, typename _OutIter> 01228 _OutIter 01229 num_put<_CharT, _OutIter>:: 01230 do_put(iter_type __s, ios_base& __io, char_type __fill, 01231 long double __v) const 01232 { return _M_insert_float(__s, __io, __fill, 'L', __v); } 01233 01234 template<typename _CharT, typename _OutIter> 01235 _OutIter 01236 num_put<_CharT, _OutIter>:: 01237 do_put(iter_type __s, ios_base& __io, char_type __fill, 01238 const void* __v) const 01239 { 01240 const ios_base::fmtflags __flags = __io.flags(); 01241 const ios_base::fmtflags __fmt = ~(ios_base::basefield 01242 | ios_base::uppercase 01243 | ios_base::internal); 01244 __io.flags(__flags & __fmt | (ios_base::hex | ios_base::showbase)); 01245 01246 __s = _M_insert_int(__s, __io, __fill, 01247 reinterpret_cast<unsigned long>(__v)); 01248 __io.flags(__flags); 01249 return __s; 01250 } 01251 01252 template<typename _CharT, typename _InIter> 01253 template<bool _Intl> 01254 _InIter 01255 money_get<_CharT, _InIter>:: 01256 _M_extract(iter_type __beg, iter_type __end, ios_base& __io, 01257 ios_base::iostate& __err, string& __units) const 01258 { 01259 typedef char_traits<_CharT> __traits_type; 01260 typedef typename string_type::size_type size_type; 01261 typedef money_base::part part; 01262 typedef moneypunct<_CharT, _Intl> __moneypunct_type; 01263 typedef typename __moneypunct_type::__cache_type __cache_type; 01264 01265 const locale& __loc = __io._M_getloc(); 01266 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 01267 01268 __use_cache<__cache_type> __uc; 01269 const __cache_type* __lc = __uc(__loc); 01270 const char_type* __lit = __lc->_M_atoms; 01271 01272 // Deduced sign. 01273 bool __negative = false; 01274 // Sign size. 01275 size_type __sign_size = 0; 01276 // True if sign is mandatory. 01277 const bool __mandatory_sign = (__lc->_M_positive_sign_size 01278 && __lc->_M_negative_sign_size); 01279 // String of grouping info from thousands_sep plucked from __units. 01280 string __grouping_tmp; 01281 if (__lc->_M_use_grouping) 01282 __grouping_tmp.reserve(32); 01283 // Last position before the decimal point. 01284 int __last_pos = 0; 01285 // Separator positions, then, possibly, fractional digits. 01286 int __n = 0; 01287 // If input iterator is in a valid state. 01288 bool __testvalid = true; 01289 // Flag marking when a decimal point is found. 01290 bool __testdecfound = false; 01291 01292 // The tentative returned string is stored here. 01293 string __res; 01294 __res.reserve(32); 01295 01296 const char_type* __lit_zero = __lit + money_base::_S_zero; 01297 const money_base::pattern __p = __lc->_M_neg_format; 01298 for (int __i = 0; __i < 4 && __testvalid; ++__i) 01299 { 01300 const part __which = static_cast<part>(__p.field[__i]); 01301 switch (__which) 01302 { 01303 case money_base::symbol: 01304 // According to 22.2.6.1.2, p2, symbol is required 01305 // if (__io.flags() & ios_base::showbase), otherwise 01306 // is optional and consumed only if other characters 01307 // are needed to complete the format. 01308 if (__io.flags() & ios_base::showbase || __sign_size > 1 01309 || __i == 0 01310 || (__i == 1 && (__mandatory_sign 01311 || (static_cast<part>(__p.field[0]) 01312 == money_base::sign) 01313 || (static_cast<part>(__p.field[2]) 01314 == money_base::space))) 01315 || (__i == 2 && ((static_cast<part>(__p.field[3]) 01316 == money_base::value) 01317 || __mandatory_sign 01318 && (static_cast<part>(__p.field[3]) 01319 == money_base::sign)))) 01320 { 01321 const size_type __len = __lc->_M_curr_symbol_size; 01322 size_type __j = 0; 01323 for (; __beg != __end && __j < __len 01324 && *__beg == __lc->_M_curr_symbol[__j]; 01325 ++__beg, ++__j); 01326 if (__j != __len 01327 && (__j || __io.flags() & ios_base::showbase)) 01328 __testvalid = false; 01329 } 01330 break; 01331 case money_base::sign: 01332 // Sign might not exist, or be more than one character long. 01333 if (__lc->_M_positive_sign_size && __beg != __end 01334 && *__beg == __lc->_M_positive_sign[0]) 01335 { 01336 __sign_size = __lc->_M_positive_sign_size; 01337 ++__beg; 01338 } 01339 else if (__lc->_M_negative_sign_size && __beg != __end 01340 && *__beg == __lc->_M_negative_sign[0]) 01341 { 01342 __negative = true; 01343 __sign_size = __lc->_M_negative_sign_size; 01344 ++__beg; 01345 } 01346 else if (__lc->_M_positive_sign_size 01347 && !__lc->_M_negative_sign_size) 01348 // "... if no sign is detected, the result is given the sign 01349 // that corresponds to the source of the empty string" 01350 __negative = true; 01351 else if (__mandatory_sign) 01352 __testvalid = false; 01353 break; 01354 case money_base::value: 01355 // Extract digits, remove and stash away the 01356 // grouping of found thousands separators. 01357 for (; __beg != __end; ++__beg) 01358 { 01359 const char_type* __q = __traits_type::find(__lit_zero, 01360 10, *__beg); 01361 if (__q != 0) 01362 { 01363 __res += money_base::_S_atoms[__q - __lit]; 01364 ++__n; 01365 } 01366 else if (*__beg == __lc->_M_decimal_point 01367 && !__testdecfound) 01368 { 01369 __last_pos = __n; 01370 __n = 0; 01371 __testdecfound = true; 01372 } 01373 else if (__lc->_M_use_grouping 01374 && *__beg == __lc->_M_thousands_sep 01375 && !__testdecfound) 01376 { 01377 if (__n) 01378 { 01379 // Mark position for later analysis. 01380 __grouping_tmp += static_cast<char>(__n); 01381 __n = 0; 01382 } 01383 else 01384 { 01385 __testvalid = false; 01386 break; 01387 } 01388 } 01389 else 01390 break; 01391 } 01392 if (__res.empty()) 01393 __testvalid = false; 01394 break; 01395 case money_base::space: 01396 // At least one space is required. 01397 if (__beg != __end && __ctype.is(ctype_base::space, *__beg)) 01398 ++__beg; 01399 else 01400 __testvalid = false; 01401 case money_base::none: 01402 // Only if not at the end of the pattern. 01403 if (__i != 3) 01404 for (; __beg != __end 01405 && __ctype.is(ctype_base::space, *__beg); ++__beg); 01406 break; 01407 } 01408 } 01409 01410 // Need to get the rest of the sign characters, if they exist. 01411 if (__sign_size > 1 && __testvalid) 01412 { 01413 const char_type* __sign = __negative ? __lc->_M_negative_sign 01414 : __lc->_M_positive_sign; 01415 size_type __i = 1; 01416 for (; __beg != __end && __i < __sign_size 01417 && *__beg == __sign[__i]; ++__beg, ++__i); 01418 01419 if (__i != __sign_size) 01420 __testvalid = false; 01421 } 01422 01423 if (__testvalid) 01424 { 01425 // Strip leading zeros. 01426 if (__res.size() > 1) 01427 { 01428 const size_type __first = __res.find_first_not_of('0'); 01429 const bool __only_zeros = __first == string::npos; 01430 if (__first) 01431 __res.erase(0, __only_zeros ? __res.size() - 1 : __first); 01432 } 01433 01434 // 22.2.6.1.2, p4 01435 if (__negative && __res[0] != '0') 01436 __res.insert(__res.begin(), '-'); 01437 01438 // Test for grouping fidelity. 01439 if (__grouping_tmp.size()) 01440 { 01441 // Add the ending grouping. 01442 __grouping_tmp += static_cast<char>(__testdecfound ? __last_pos 01443 : __n); 01444 if (!std::__verify_grouping(__lc->_M_grouping, 01445 __lc->_M_grouping_size, 01446 __grouping_tmp)) 01447 __testvalid = false; 01448 } 01449 01450 // Iff not enough digits were supplied after the decimal-point. 01451 if (__testdecfound && __lc->_M_frac_digits > 0 01452 && __n != __lc->_M_frac_digits) 01453 __testvalid = false; 01454 } 01455 01456 // Iff no more characters are available. 01457 if (__beg == __end) 01458 __err |= ios_base::eofbit; 01459 01460 // Iff valid sequence is not recognized. 01461 if (!__testvalid) 01462 __err |= ios_base::failbit; 01463 else 01464 __units.swap(__res); 01465 01466 return __beg; 01467 } 01468 01469 template<typename _CharT, typename _InIter> 01470 _InIter 01471 money_get<_CharT, _InIter>:: 01472 do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 01473 ios_base::iostate& __err, long double& __units) const 01474 { 01475 string __str; 01476 if (__intl) 01477 __beg = _M_extract<true>(__beg, __end, __io, __err, __str); 01478 else 01479 __beg = _M_extract<false>(__beg, __end, __io, __err, __str); 01480 std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); 01481 return __beg; 01482 } 01483 01484 template<typename _CharT, typename _InIter> 01485 _InIter 01486 money_get<_CharT, _InIter>:: 01487 do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 01488 ios_base::iostate& __err, string_type& __units) const 01489 { 01490 typedef typename string::size_type size_type; 01491 01492 const locale& __loc = __io._M_getloc(); 01493 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 01494 01495 string __str; 01496 const iter_type __ret = __intl ? _M_extract<true>(__beg, __end, __io, 01497 __err, __str) 01498 : _M_extract<false>(__beg, __end, __io, 01499 __err, __str); 01500 const size_type __len = __str.size(); 01501 if (__len) 01502 { 01503 _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 01504 * __len)); 01505 __ctype.widen(__str.data(), __str.data() + __len, __ws); 01506 __units.assign(__ws, __len); 01507 } 01508 01509 return __ret; 01510 } 01511 01512 template<typename _CharT, typename _OutIter> 01513 template<bool _Intl> 01514 _OutIter 01515 money_put<_CharT, _OutIter>:: 01516 _M_insert(iter_type __s, ios_base& __io, char_type __fill, 01517 const string_type& __digits) const 01518 { 01519 typedef typename string_type::size_type size_type; 01520 typedef money_base::part part; 01521 typedef moneypunct<_CharT, _Intl> __moneypunct_type; 01522 typedef typename __moneypunct_type::__cache_type __cache_type; 01523 01524 const locale& __loc = __io._M_getloc(); 01525 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 01526 01527 __use_cache<__cache_type> __uc; 01528 const __cache_type* __lc = __uc(__loc); 01529 const char_type* __lit = __lc->_M_atoms; 01530 01531 // Determine if negative or positive formats are to be used, and 01532 // discard leading negative_sign if it is present. 01533 const char_type* __beg = __digits.data(); 01534 01535 money_base::pattern __p; 01536 const char_type* __sign; 01537 size_type __sign_size; 01538 if (*__beg != __lit[money_base::_S_minus]) 01539 { 01540 __p = __lc->_M_pos_format; 01541 __sign = __lc->_M_positive_sign; 01542 __sign_size = __lc->_M_positive_sign_size; 01543 } 01544 else 01545 { 01546 __p = __lc->_M_neg_format; 01547 __sign = __lc->_M_negative_sign; 01548 __sign_size = __lc->_M_negative_sign_size; 01549 if (__digits.size()) 01550 ++__beg; 01551 } 01552 01553 // Look for valid numbers in the ctype facet within input digits. 01554 size_type __len = __ctype.scan_not(ctype_base::digit, __beg, 01555 __beg + __digits.size()) - __beg; 01556 if (__len) 01557 { 01558 // Assume valid input, and attempt to format. 01559 // Break down input numbers into base components, as follows: 01560 // final_value = grouped units + (decimal point) + (digits) 01561 string_type __value; 01562 __value.reserve(2 * __len); 01563 01564 // Add thousands separators to non-decimal digits, per 01565 // grouping rules. 01566 int __paddec = __len - __lc->_M_frac_digits; 01567 if (__paddec > 0) 01568 { 01569 if (__lc->_M_frac_digits < 0) 01570 __paddec = __len; 01571 if (__lc->_M_grouping_size) 01572 { 01573 _CharT* __ws = 01574 static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 01575 * 2 * __len)); 01576 _CharT* __ws_end = 01577 std::__add_grouping(__ws, __lc->_M_thousands_sep, 01578 __lc->_M_grouping, 01579 __lc->_M_grouping_size, 01580 __beg, __beg + __paddec); 01581 __value.assign(__ws, __ws_end - __ws); 01582 } 01583 else 01584 __value.assign(__beg, __paddec); 01585 } 01586 01587 // Deal with decimal point, decimal digits. 01588 if (__lc->_M_frac_digits > 0) 01589 { 01590 __value += __lc->_M_decimal_point; 01591 if (__paddec >= 0) 01592 __value.append(__beg + __paddec, __lc->_M_frac_digits); 01593 else 01594 { 01595 // Have to pad zeros in the decimal position. 01596 __value.append(-__paddec, __lit[money_base::_S_zero]); 01597 __value.append(__beg, __len); 01598 } 01599 } 01600 01601 // Calculate length of resulting string. 01602 const ios_base::fmtflags __f = __io.flags() 01603 & ios_base::adjustfield; 01604 __len = __value.size() + __sign_size; 01605 __len += ((__io.flags() & ios_base::showbase) 01606 ? __lc->_M_curr_symbol_size : 0); 01607 01608 string_type __res; 01609 __res.reserve(2 * __len); 01610 01611 const size_type __width = static_cast<size_type>(__io.width()); 01612 const bool __testipad = (__f == ios_base::internal 01613 && __len < __width); 01614 // Fit formatted digits into the required pattern. 01615 for (int __i = 0; __i < 4; ++__i) 01616 { 01617 const part __which = static_cast<part>(__p.field[__i]); 01618 switch (__which) 01619 { 01620 case money_base::symbol: 01621 if (__io.flags() & ios_base::showbase) 01622 __res.append(__lc->_M_curr_symbol, 01623 __lc->_M_curr_symbol_size); 01624 break; 01625 case money_base::sign: 01626 // Sign might not exist, or be more than one 01627 // charater long. In that case, add in the rest 01628 // below. 01629 if (__sign_size) 01630 __res += __sign[0]; 01631 break; 01632 case money_base::value: 01633 __res += __value; 01634 break; 01635 case money_base::space: 01636 // At least one space is required, but if internal 01637 // formatting is required, an arbitrary number of 01638 // fill spaces will be necessary. 01639 if (__testipad) 01640 __res.append(__width - __len, __fill); 01641 else 01642 __res += __fill; 01643 break; 01644 case money_base::none: 01645 if (__testipad) 01646 __res.append(__width - __len, __fill); 01647 break; 01648 } 01649 } 01650 01651 // Special case of multi-part sign parts. 01652 if (__sign_size > 1) 01653 __res.append(__sign + 1, __sign_size - 1); 01654 01655 // Pad, if still necessary. 01656 __len = __res.size(); 01657 if (__width > __len) 01658 { 01659 if (__f == ios_base::left) 01660 // After. 01661 __res.append(__width - __len, __fill); 01662 else 01663 // Before. 01664 __res.insert(0, __width - __len, __fill); 01665 __len = __width; 01666 } 01667 01668 // Write resulting, fully-formatted string to output iterator. 01669 __s = std::__write(__s, __res.data(), __len); 01670 } 01671 __io.width(0); 01672 return __s; 01673 } 01674 01675 template<typename _CharT, typename _OutIter> 01676 _OutIter 01677 money_put<_CharT, _OutIter>:: 01678 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 01679 long double __units) const 01680 { 01681 const locale __loc = __io.getloc(); 01682 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 01683 #ifdef _GLIBCXX_USE_C99 01684 // First try a buffer perhaps big enough. 01685 int __cs_size = 64; 01686 char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 01687 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01688 // 328. Bad sprintf format modifier in money_put<>::do_put() 01689 int __len = std::__convert_from_v(__cs, __cs_size, "%.*Lf", __units, 01690 _S_get_c_locale(), 0); 01691 // If the buffer was not large enough, try again with the correct size. 01692 if (__len >= __cs_size) 01693 { 01694 __cs_size = __len + 1; 01695 __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 01696 __len = std::__convert_from_v(__cs, __cs_size, "%.*Lf", __units, 01697 _S_get_c_locale(), 0); 01698 } 01699 #else 01700 // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. 01701 const int __cs_size = numeric_limits<long double>::max_exponent10 + 3; 01702 char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 01703 int __len = std::__convert_from_v(__cs, 0, "%.*Lf", __units, 01704 _S_get_c_locale(), 0); 01705 #endif 01706 _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 01707 * __cs_size)); 01708 __ctype.widen(__cs, __cs + __len, __ws); 01709 const string_type __digits(__ws, __len); 01710 return __intl ? _M_insert<true>(__s, __io, __fill, __digits) 01711 : _M_insert<false>(__s, __io, __fill, __digits); 01712 } 01713 01714 template<typename _CharT, typename _OutIter> 01715 _OutIter 01716 money_put<_CharT, _OutIter>:: 01717 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 01718 const string_type& __digits) const 01719 { return __intl ? _M_insert<true>(__s, __io, __fill, __digits) 01720 : _M_insert<false>(__s, __io, __fill, __digits); } 01721 01722 01723 // NB: Not especially useful. Without an ios_base object or some 01724 // kind of locale reference, we are left clawing at the air where 01725 // the side of the mountain used to be... 01726 template<typename _CharT, typename _InIter> 01727 time_base::dateorder 01728 time_get<_CharT, _InIter>::do_date_order() const 01729 { return time_base::no_order; } 01730 01731 // Expand a strftime format string and parse it. E.g., do_get_date() may 01732 // pass %m/%d/%Y => extracted characters. 01733 template<typename _CharT, typename _InIter> 01734 _InIter 01735 time_get<_CharT, _InIter>:: 01736 _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, 01737 ios_base::iostate& __err, tm* __tm, 01738 const _CharT* __format) const 01739 { 01740 const locale& __loc = __io._M_getloc(); 01741 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 01742 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 01743 const size_t __len = char_traits<_CharT>::length(__format); 01744 01745 for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i) 01746 { 01747 if (__ctype.narrow(__format[__i], 0) == '%') 01748 { 01749 // Verify valid formatting code, attempt to extract. 01750 char __c = __ctype.narrow(__format[++__i], 0); 01751 int __mem = 0; 01752 if (__c == 'E' || __c == 'O') 01753 __c = __ctype.narrow(__format[++__i], 0); 01754 switch (__c) 01755 { 01756 const char* __cs; 01757 _CharT __wcs[10]; 01758 case 'a': 01759 // Abbreviated weekday name [tm_wday] 01760 const char_type* __days1[7]; 01761 __tp._M_days_abbreviated(__days1); 01762 __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 01763 7, __io, __err); 01764 break; 01765 case 'A': 01766 // Weekday name [tm_wday]. 01767 const char_type* __days2[7]; 01768 __tp._M_days(__days2); 01769 __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 01770 7, __io, __err); 01771 break; 01772 case 'h': 01773 case 'b': 01774 // Abbreviated month name [tm_mon] 01775 const char_type* __months1[12]; 01776 __tp._M_months_abbreviated(__months1); 01777 __beg = _M_extract_name(__beg, __end, __tm->tm_mon, 01778 __months1, 12, __io, __err); 01779 break; 01780 case 'B': 01781 // Month name [tm_mon]. 01782 const char_type* __months2[12]; 01783 __tp._M_months(__months2); 01784 __beg = _M_extract_name(__beg, __end, __tm->tm_mon, 01785 __months2, 12, __io, __err); 01786 break; 01787 case 'c': 01788 // Default time and date representation. 01789 const char_type* __dt[2]; 01790 __tp._M_date_time_formats(__dt); 01791 __beg = _M_extract_via_format(__beg, __end, __io, __err, 01792 __tm, __dt[0]); 01793 break; 01794 case 'd': 01795 // Day [01, 31]. [tm_mday] 01796 __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, 01797 __io, __err); 01798 break; 01799 case 'e': 01800 // Day [1, 31], with single digits preceded by 01801 // space. [tm_mday] 01802 if (__ctype.is(ctype_base::space, *__beg)) 01803 __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9, 01804 1, __io, __err); 01805 else 01806 __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31, 01807 2, __io, __err); 01808 break; 01809 case 'D': 01810 // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] 01811 __cs = "%m/%d/%y"; 01812 __ctype.widen(__cs, __cs + 9, __wcs); 01813 __beg = _M_extract_via_format(__beg, __end, __io, __err, 01814 __tm, __wcs); 01815 break; 01816 case 'H': 01817 // Hour [00, 23]. [tm_hour] 01818 __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2, 01819 __io, __err); 01820 break; 01821 case 'I': 01822 // Hour [01, 12]. [tm_hour] 01823 __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2, 01824 __io, __err); 01825 break; 01826 case 'm': 01827 // Month [01, 12]. [tm_mon] 01828 __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, 01829 __io, __err); 01830 if (!__err) 01831 __tm->tm_mon = __mem - 1; 01832 break; 01833 case 'M': 01834 // Minute [00, 59]. [tm_min] 01835 __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2, 01836 __io, __err); 01837 break; 01838 case 'n': 01839 if (__ctype.narrow(*__beg, 0) == '\n') 01840 ++__beg; 01841 else 01842 __err |= ios_base::failbit; 01843 break; 01844 case 'R': 01845 // Equivalent to (%H:%M). 01846 __cs = "%H:%M"; 01847 __ctype.widen(__cs, __cs + 6, __wcs); 01848 __beg = _M_extract_via_format(__beg, __end, __io, __err, 01849 __tm, __wcs); 01850 break; 01851 case 'S': 01852 // Seconds. [tm_sec] 01853 // [00, 60] in C99 (one leap-second), [00, 61] in C89. 01854 #ifdef _GLIBCXX_USE_C99 01855 __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2, 01856 #else 01857 __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2, 01858 #endif 01859 __io, __err); 01860 break; 01861 case 't': 01862 if (__ctype.narrow(*__beg, 0) == '\t') 01863 ++__beg; 01864 else 01865 __err |= ios_base::failbit; 01866 break; 01867 case 'T': 01868 // Equivalent to (%H:%M:%S). 01869 __cs = "%H:%M:%S"; 01870 __ctype.widen(__cs, __cs + 9, __wcs); 01871 __beg = _M_extract_via_format(__beg, __end, __io, __err, 01872 __tm, __wcs); 01873 break; 01874 case 'x': 01875 // Locale's date. 01876 const char_type* __dates[2]; 01877 __tp._M_date_formats(__dates); 01878 __beg = _M_extract_via_format(__beg, __end, __io, __err, 01879 __tm, __dates[0]); 01880 break; 01881 case 'X': 01882 // Locale's time. 01883 const char_type* __times[2]; 01884 __tp._M_time_formats(__times); 01885 __beg = _M_extract_via_format(__beg, __end, __io, __err, 01886 __tm, __times[0]); 01887 break; 01888 case 'y': 01889 case 'C': // C99 01890 // Two digit year. [tm_year] 01891 __beg = _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2, 01892 __io, __err); 01893 break; 01894 case 'Y': 01895 // Year [1900). [tm_year] 01896 __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4, 01897 __io, __err); 01898 if (!__err) 01899 __tm->tm_year = __mem - 1900; 01900 break; 01901 case 'Z': 01902 // Timezone info. 01903 if (__ctype.is(ctype_base::upper, *__beg)) 01904 { 01905 int __tmp; 01906 __beg = _M_extract_name(__beg, __end, __tmp, 01907 __timepunct_cache<_CharT>::_S_timezones, 01908 14, __io, __err); 01909 01910 // GMT requires special effort. 01911 if (__beg != __end && !__err && __tmp == 0 01912 && (*__beg == __ctype.widen('-') 01913 || *__beg == __ctype.widen('+'))) 01914 { 01915 __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2, 01916 __io, __err); 01917 __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2, 01918 __io, __err); 01919 } 01920 } 01921 else 01922 __err |= ios_base::failbit; 01923 break; 01924 default: 01925 // Not recognized. 01926 __err |= ios_base::failbit; 01927 } 01928 } 01929 else 01930 { 01931 // Verify format and input match, extract and discard. 01932 if (__format[__i] == *__beg) 01933 ++__beg; 01934 else 01935 __err |= ios_base::failbit; 01936 } 01937 } 01938 return __beg; 01939 } 01940 01941 template<typename _CharT, typename _InIter> 01942 _InIter 01943 time_get<_CharT, _InIter>:: 01944 _M_extract_num(iter_type __beg, iter_type __end, int& __member, 01945 int __min, int __max, size_t __len, 01946 ios_base& __io, ios_base::iostate& __err) const 01947 { 01948 const locale& __loc = __io._M_getloc(); 01949 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 01950 01951 // As-is works for __len = 1, 2, 4, the values actually used. 01952 int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1); 01953 01954 ++__min; 01955 size_t __i = 0; 01956 int __value = 0; 01957 for (; __beg != __end && __i < __len; ++__beg, ++__i) 01958 { 01959 const char __c = __ctype.narrow(*__beg, '*'); 01960 if (__c >= '0' && __c <= '9') 01961 { 01962 __value = __value * 10 + (__c - '0'); 01963 const int __valuec = __value * __mult; 01964 if (__valuec > __max || __valuec + __mult < __min) 01965 break; 01966 __mult /= 10; 01967 } 01968 else 01969 break; 01970 } 01971 if (__i == __len) 01972 __member = __value; 01973 else 01974 __err |= ios_base::failbit; 01975 return __beg; 01976 } 01977 01978 // Assumptions: 01979 // All elements in __names are unique. 01980 template<typename _CharT, typename _InIter> 01981 _InIter 01982 time_get<_CharT, _InIter>:: 01983 _M_extract_name(iter_type __beg, iter_type __end, int& __member, 01984 const _CharT** __names, size_t __indexlen, 01985 ios_base& __io, ios_base::iostate& __err) const 01986 { 01987 typedef char_traits<_CharT> __traits_type; 01988 const locale& __loc = __io._M_getloc(); 01989 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 01990 01991 int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) 01992 * __indexlen)); 01993 size_t __nmatches = 0; 01994 size_t __pos = 0; 01995 bool __testvalid = true; 01996 const char_type* __name; 01997 01998 // Look for initial matches. 01999 // NB: Some of the locale data is in the form of all lowercase 02000 // names, and some is in the form of initially-capitalized 02001 // names. Look for both. 02002 if (__beg != __end) 02003 { 02004 const char_type __c = *__beg; 02005 for (size_t __i1 = 0; __i1 < __indexlen; ++__i1) 02006 if (__c == __names[__i1][0] 02007 || __c == __ctype.toupper(__names[__i1][0])) 02008 __matches[__nmatches++] = __i1; 02009 } 02010 02011 while (__nmatches > 1) 02012 { 02013 // Find smallest matching string. 02014 size_t __minlen = __traits_type::length(__names[__matches[0]]); 02015 for (size_t __i2 = 1; __i2 < __nmatches; ++__i2) 02016 __minlen = std::min(__minlen, 02017 __traits_type::length(__names[__matches[__i2]])); 02018 ++__pos; 02019 ++__beg; 02020 if (__pos < __minlen && __beg != __end) 02021 for (size_t __i3 = 0; __i3 < __nmatches;) 02022 { 02023 __name = __names[__matches[__i3]]; 02024 if (__name[__pos] != *__beg) 02025 __matches[__i3] = __matches[--__nmatches]; 02026 else 02027 ++__i3; 02028 } 02029 else 02030 break; 02031 } 02032 02033 if (__nmatches == 1) 02034 { 02035 // Make sure found name is completely extracted. 02036 ++__pos; 02037 ++__beg; 02038 __name = __names[__matches[0]]; 02039 const size_t __len = __traits_type::length(__name); 02040 while (__pos < __len && __beg != __end && __name[__pos] == *__beg) 02041 ++__beg, ++__pos; 02042 02043 if (__len == __pos) 02044 __member = __matches[0]; 02045 else 02046 __testvalid = false; 02047 } 02048 else 02049 __testvalid = false; 02050 if (!__testvalid) 02051 __err |= ios_base::failbit; 02052 return __beg; 02053 } 02054 02055 template<typename _CharT, typename _InIter> 02056 _InIter 02057 time_get<_CharT, _InIter>:: 02058 do_get_time(iter_type __beg, iter_type __end, ios_base& __io, 02059 ios_base::iostate& __err, tm* __tm) const 02060 { 02061 const locale& __loc = __io._M_getloc(); 02062 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 02063 const char_type* __times[2]; 02064 __tp._M_time_formats(__times); 02065 __beg = _M_extract_via_format(__beg, __end, __io, __err, 02066 __tm, __times[0]); 02067 if (__beg == __end) 02068 __err |= ios_base::eofbit; 02069 return __beg; 02070 } 02071 02072 template<typename _CharT, typename _InIter> 02073 _InIter 02074 time_get<_CharT, _InIter>:: 02075 do_get_date(iter_type __beg, iter_type __end, ios_base& __io, 02076 ios_base::iostate& __err, tm* __tm) const 02077 { 02078 const locale& __loc = __io._M_getloc(); 02079 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 02080 const char_type* __dates[2]; 02081 __tp._M_date_formats(__dates); 02082 __beg = _M_extract_via_format(__beg, __end, __io, __err, 02083 __tm, __dates[0]); 02084 if (__beg == __end) 02085 __err |= ios_base::eofbit; 02086 return __beg; 02087 } 02088 02089 template<typename _CharT, typename _InIter> 02090 _InIter 02091 time_get<_CharT, _InIter>:: 02092 do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, 02093 ios_base::iostate& __err, tm* __tm) const 02094 { 02095 typedef char_traits<_CharT> __traits_type; 02096 const locale& __loc = __io._M_getloc(); 02097 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 02098 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 02099 const char_type* __days[7]; 02100 __tp._M_days_abbreviated(__days); 02101 int __tmpwday; 02102 __beg = _M_extract_name(__beg, __end, __tmpwday, __days, 7, __io, __err); 02103 02104 // Check to see if non-abbreviated name exists, and extract. 02105 // NB: Assumes both _M_days and _M_days_abbreviated organized in 02106 // exact same order, first to last, such that the resulting 02107 // __days array with the same index points to a day, and that 02108 // day's abbreviated form. 02109 // NB: Also assumes that an abbreviated name is a subset of the name. 02110 if (!__err) 02111 { 02112 size_t __pos = __traits_type::length(__days[__tmpwday]); 02113 __tp._M_days(__days); 02114 const char_type* __name = __days[__tmpwday]; 02115 if (__name[__pos] == *__beg) 02116 { 02117 // Extract the rest of it. 02118 const size_t __len = __traits_type::length(__name); 02119 while (__pos < __len && __beg != __end 02120 && __name[__pos] == *__beg) 02121 ++__beg, ++__pos; 02122 if (__len != __pos) 02123 __err |= ios_base::failbit; 02124 } 02125 if (!__err) 02126 __tm->tm_wday = __tmpwday; 02127 } 02128 if (__beg == __end) 02129 __err |= ios_base::eofbit; 02130 return __beg; 02131 } 02132 02133 template<typename _CharT, typename _InIter> 02134 _InIter 02135 time_get<_CharT, _InIter>:: 02136 do_get_monthname(iter_type __beg, iter_type __end, 02137 ios_base& __io, ios_base::iostate& __err, tm* __tm) const 02138 { 02139 typedef char_traits<_CharT> __traits_type; 02140 const locale& __loc = __io._M_getloc(); 02141 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 02142 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 02143 const char_type* __months[12]; 02144 __tp._M_months_abbreviated(__months); 02145 int __tmpmon; 02146 __beg = _M_extract_name(__beg, __end, __tmpmon, __months, 12, 02147 __io, __err); 02148 02149 // Check to see if non-abbreviated name exists, and extract. 02150 // NB: Assumes both _M_months and _M_months_abbreviated organized in 02151 // exact same order, first to last, such that the resulting 02152 // __months array with the same index points to a month, and that 02153 // month's abbreviated form. 02154 // NB: Also assumes that an abbreviated name is a subset of the name. 02155 if (!__err) 02156 { 02157 size_t __pos = __traits_type::length(__months[__tmpmon]); 02158 __tp._M_months(__months); 02159 const char_type* __name = __months[__tmpmon]; 02160 if (__name[__pos] == *__beg) 02161 { 02162 // Extract the rest of it. 02163 const size_t __len = __traits_type::length(__name); 02164 while (__pos < __len && __beg != __end 02165 && __name[__pos] == *__beg) 02166 ++__beg, ++__pos; 02167 if (__len != __pos) 02168 __err |= ios_base::failbit; 02169 } 02170 if (!__err) 02171 __tm->tm_mon = __tmpmon; 02172 } 02173 02174 if (__beg == __end) 02175 __err |= ios_base::eofbit; 02176 return __beg; 02177 } 02178 02179 template<typename _CharT, typename _InIter> 02180 _InIter 02181 time_get<_CharT, _InIter>:: 02182 do_get_year(iter_type __beg, iter_type __end, ios_base& __io, 02183 ios_base::iostate& __err, tm* __tm) const 02184 { 02185 const locale& __loc = __io._M_getloc(); 02186 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 02187 02188 size_t __i = 0; 02189 int __value = 0; 02190 for (; __beg != __end && __i < 4; ++__beg, ++__i) 02191 { 02192 const char __c = __ctype.narrow(*__beg, '*'); 02193 if (__c >= '0' && __c <= '9') 02194 __value = __value * 10 + (__c - '0'); 02195 else 02196 break; 02197 } 02198 if (__i == 2 || __i == 4) 02199 __tm->tm_year = __i == 2 ? __value : __value - 1900; 02200 else 02201 __err |= ios_base::failbit; 02202 if (__beg == __end) 02203 __err |= ios_base::eofbit; 02204 return __beg; 02205 } 02206 02207 template<typename _CharT, typename _OutIter> 02208 _OutIter 02209 time_put<_CharT, _OutIter>:: 02210 put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, 02211 const _CharT* __beg, const _CharT* __end) const 02212 { 02213 const locale& __loc = __io._M_getloc(); 02214 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); 02215 for (; __beg != __end; ++__beg) 02216 if (__ctype.narrow(*__beg, 0) != '%') 02217 { 02218 *__s = *__beg; 02219 ++__s; 02220 } 02221 else if (++__beg != __end) 02222 { 02223 char __format; 02224 char __mod = 0; 02225 const char __c = __ctype.narrow(*__beg, 0); 02226 if (__c != 'E' && __c != 'O') 02227 __format = __c; 02228 else if (++__beg != __end) 02229 { 02230 __mod = __c; 02231 __format = __ctype.narrow(*__beg, 0); 02232 } 02233 else 02234 break; 02235 __s = this->do_put(__s, __io, __fill, __tm, __format, __mod); 02236 } 02237 else 02238 break; 02239 return __s; 02240 } 02241 02242 template<typename _CharT, typename _OutIter> 02243 _OutIter 02244 time_put<_CharT, _OutIter>:: 02245 do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, 02246 char __format, char __mod) const 02247 { 02248 const locale& __loc = __io._M_getloc(); 02249 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); 02250 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); 02251 02252 // NB: This size is arbitrary. Should this be a data member, 02253 // initialized at construction? 02254 const size_t __maxlen = 128; 02255 char_type* __res = 02256 static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __maxlen)); 02257 02258 // NB: In IEE 1003.1-200x, and perhaps other locale models, it 02259 // is possible that the format character will be longer than one 02260 // character. Possibilities include 'E' or 'O' followed by a 02261 // format character: if __mod is not the default argument, assume 02262 // it's a valid modifier. 02263 char_type __fmt[4]; 02264 __fmt[0] = __ctype.widen('%'); 02265 if (!__mod) 02266 { 02267 __fmt[1] = __format; 02268 __fmt[2] = char_type(); 02269 } 02270 else 02271 { 02272 __fmt[1] = __mod; 02273 __fmt[2] = __format; 02274 __fmt[3] = char_type(); 02275 } 02276 02277 __tp._M_put(__res, __maxlen, __fmt, __tm); 02278 02279 // Write resulting, fully-formatted string to output iterator. 02280 return std::__write(__s, __res, char_traits<char_type>::length(__res)); 02281 } 02282 02283 // Generic version does nothing. 02284 template<typename _CharT> 02285 int 02286 collate<_CharT>::_M_compare(const _CharT*, const _CharT*) const 02287 { return 0; } 02288 02289 // Generic version does nothing. 02290 template<typename _CharT> 02291 size_t 02292 collate<_CharT>::_M_transform(_CharT*, const _CharT*, size_t) const 02293 { return 0; } 02294 02295 template<typename _CharT> 02296 int 02297 collate<_CharT>:: 02298 do_compare(const _CharT* __lo1, const _CharT* __hi1, 02299 const _CharT* __lo2, const _CharT* __hi2) const 02300 { 02301 // strcoll assumes zero-terminated strings so we make a copy 02302 // and then put a zero at the end. 02303 const string_type __one(__lo1, __hi1); 02304 const string_type __two(__lo2, __hi2); 02305 02306 const _CharT* __p = __one.c_str(); 02307 const _CharT* __pend = __one.data() + __one.length(); 02308 const _CharT* __q = __two.c_str(); 02309 const _CharT* __qend = __two.data() + __two.length(); 02310 02311 // strcoll stops when it sees a nul character so we break 02312 // the strings into zero-terminated substrings and pass those 02313 // to strcoll. 02314 for (;;) 02315 { 02316 const int __res = _M_compare(__p, __q); 02317 if (__res) 02318 return __res; 02319 02320 __p += char_traits<_CharT>::length(__p); 02321 __q += char_traits<_CharT>::length(__q); 02322 if (__p == __pend && __q == __qend) 02323 return 0; 02324 else if (__p == __pend) 02325 return -1; 02326 else if (__q == __qend) 02327 return 1; 02328 02329 __p++; 02330 __q++; 02331 } 02332 } 02333 02334 template<typename _CharT> 02335 typename collate<_CharT>::string_type 02336 collate<_CharT>:: 02337 do_transform(const _CharT* __lo, const _CharT* __hi) const 02338 { 02339 // strxfrm assumes zero-terminated strings so we make a copy 02340 string_type __str(__lo, __hi); 02341 02342 const _CharT* __p = __str.c_str(); 02343 const _CharT* __pend = __str.data() + __str.length(); 02344 02345 size_t __len = (__hi - __lo) * 2; 02346 02347 string_type __ret; 02348 02349 // strxfrm stops when it sees a nul character so we break 02350 // the string into zero-terminated substrings and pass those 02351 // to strxfrm. 02352 for (;;) 02353 { 02354 // First try a buffer perhaps big enough. 02355 _CharT* __c = 02356 static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __len)); 02357 size_t __res = _M_transform(__c, __p, __len); 02358 // If the buffer was not large enough, try again with the 02359 // correct size. 02360 if (__res >= __len) 02361 { 02362 __len = __res + 1; 02363 __c = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) 02364 * __len)); 02365 __res = _M_transform(__c, __p, __len); 02366 } 02367 02368 __ret.append(__c, __res); 02369 __p += char_traits<_CharT>::length(__p); 02370 if (__p == __pend) 02371 return __ret; 02372 02373 __p++; 02374 __ret.push_back(_CharT()); 02375 } 02376 } 02377 02378 template<typename _CharT> 02379 long 02380 collate<_CharT>:: 02381 do_hash(const _CharT* __lo, const _CharT* __hi) const 02382 { 02383 unsigned long __val = 0; 02384 for (; __lo < __hi; ++__lo) 02385 __val = *__lo + ((__val << 7) | 02386 (__val >> (numeric_limits<unsigned long>::digits - 7))); 02387 return static_cast<long>(__val); 02388 } 02389 02390 // Construct correctly padded string, as per 22.2.2.2.2 02391 // Assumes 02392 // __newlen > __oldlen 02393 // __news is allocated for __newlen size 02394 // Used by both num_put and ostream inserters: if __num, 02395 // internal-adjusted objects are padded according to the rules below 02396 // concerning 0[xX] and +-, otherwise, exactly as right-adjusted 02397 // ones are. 02398 02399 // NB: Of the two parameters, _CharT can be deduced from the 02400 // function arguments. The other (_Traits) has to be explicitly specified. 02401 template<typename _CharT, typename _Traits> 02402 void 02403 __pad<_CharT, _Traits>::_S_pad(ios_base& __io, _CharT __fill, 02404 _CharT* __news, const _CharT* __olds, 02405 const streamsize __newlen, 02406 const streamsize __oldlen, const bool __num) 02407 { 02408 const size_t __plen = static_cast<size_t>(__newlen - __oldlen); 02409 const ios_base::fmtflags __adjust = __io.flags() & ios_base::adjustfield; 02410 02411 // Padding last. 02412 if (__adjust == ios_base::left) 02413 { 02414 _Traits::copy(__news, const_cast<_CharT*>(__olds), __oldlen); 02415 _Traits::assign(__news + __oldlen, __plen, __fill); 02416 return; 02417 } 02418 02419 size_t __mod = 0; 02420 if (__adjust == ios_base::internal && __num) 02421 { 02422 // Pad after the sign, if there is one. 02423 // Pad after 0[xX], if there is one. 02424 // Who came up with these rules, anyway? Jeeze. 02425 const locale& __loc = __io._M_getloc(); 02426 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 02427 02428 const bool __testsign = (__ctype.widen('-') == __olds[0] 02429 || __ctype.widen('+') == __olds[0]); 02430 const bool __testhex = (__ctype.widen('0') == __olds[0] 02431 && __oldlen > 1 02432 && (__ctype.widen('x') == __olds[1] 02433 || __ctype.widen('X') == __olds[1])); 02434 if (__testhex) 02435 { 02436 __news[0] = __olds[0]; 02437 __news[1] = __olds[1]; 02438 __mod = 2; 02439 __news += 2; 02440 } 02441 else if (__testsign) 02442 { 02443 __news[0] = __olds[0]; 02444 __mod = 1; 02445 ++__news; 02446 } 02447 // else Padding first. 02448 } 02449 _Traits::assign(__news, __plen, __fill); 02450 _Traits::copy(__news + __plen, const_cast<_CharT*>(__olds + __mod), 02451 __oldlen - __mod); 02452 } 02453 02454 bool 02455 __verify_grouping(const char* __grouping, size_t __grouping_size, 02456 const string& __grouping_tmp) 02457 { 02458 const size_t __n = __grouping_tmp.size() - 1; 02459 const size_t __min = std::min(__n, size_t(__grouping_size - 1)); 02460 size_t __i = __n; 02461 bool __test = true; 02462 02463 // Parsed number groupings have to match the 02464 // numpunct::grouping string exactly, starting at the 02465 // right-most point of the parsed sequence of elements ... 02466 for (size_t __j = 0; __j < __min && __test; --__i, ++__j) 02467 __test = __grouping_tmp[__i] == __grouping[__j]; 02468 for (; __i && __test; --__i) 02469 __test = __grouping_tmp[__i] == __grouping[__min]; 02470 // ... but the last parsed grouping can be <= numpunct 02471 // grouping. 02472 __test &= __grouping_tmp[0] <= __grouping[__min]; 02473 return __test; 02474 } 02475 02476 template<typename _CharT> 02477 _CharT* 02478 __add_grouping(_CharT* __s, _CharT __sep, 02479 const char* __gbeg, size_t __gsize, 02480 const _CharT* __first, const _CharT* __last) 02481 { 02482 if (__last - __first > *__gbeg) 02483 { 02484 const bool __bump = __gsize != 1; 02485 __s = std::__add_grouping(__s, __sep, __gbeg + __bump, 02486 __gsize - __bump, __first, 02487 __last - *__gbeg); 02488 __first = __last - *__gbeg; 02489 *__s++ = __sep; 02490 } 02491 do 02492 *__s++ = *__first++; 02493 while (__first != __last); 02494 return __s; 02495 } 02496 02497 // Inhibit implicit instantiations for required instantiations, 02498 // which are defined via explicit instantiations elsewhere. 02499 // NB: This syntax is a GNU extension. 02500 #if _GLIBCXX_EXTERN_TEMPLATE 02501 extern template class moneypunct<char, false>; 02502 extern template class moneypunct<char, true>; 02503 extern template class moneypunct_byname<char, false>; 02504 extern template class moneypunct_byname<char, true>; 02505 extern template class money_get<char>; 02506 extern template class money_put<char>; 02507 extern template class numpunct<char>; 02508 extern template class numpunct_byname<char>; 02509 extern template class num_get<char>; 02510 extern template class num_put<char>; 02511 extern template class __timepunct<char>; 02512 extern template class time_put<char>; 02513 extern template class time_put_byname<char>; 02514 extern template class time_get<char>; 02515 extern template class time_get_byname<char>; 02516 extern template class messages<char>; 02517 extern template class messages_byname<char>; 02518 extern template class ctype_byname<char>; 02519 extern template class codecvt_byname<char, char, mbstate_t>; 02520 extern template class collate<char>; 02521 extern template class collate_byname<char>; 02522 02523 extern template 02524 const codecvt<char, char, mbstate_t>& 02525 use_facet<codecvt<char, char, mbstate_t> >(const locale&); 02526 02527 extern template 02528 const collate<char>& 02529 use_facet<collate<char> >(const locale&); 02530 02531 extern template 02532 const numpunct<char>& 02533 use_facet<numpunct<char> >(const locale&); 02534 02535 extern template 02536 const num_put<char>& 02537 use_facet<num_put<char> >(const locale&); 02538 02539 extern template 02540 const num_get<char>& 02541 use_facet<num_get<char> >(const locale&); 02542 02543 extern template 02544 const moneypunct<char, true>& 02545 use_facet<moneypunct<char, true> >(const locale&); 02546 02547 extern template 02548 const moneypunct<char, false>& 02549 use_facet<moneypunct<char, false> >(const locale&); 02550 02551 extern template 02552 const money_put<char>& 02553 use_facet<money_put<char> >(const locale&); 02554 02555 extern template 02556 const money_get<char>& 02557 use_facet<money_get<char> >(const locale&); 02558 02559 extern template 02560 const __timepunct<char>& 02561 use_facet<__timepunct<char> >(const locale&); 02562 02563 extern template 02564 const time_put<char>& 02565 use_facet<time_put<char> >(const locale&); 02566 02567 extern template 02568 const time_get<char>& 02569 use_facet<time_get<char> >(const locale&); 02570 02571 extern template 02572 const messages<char>& 02573 use_facet<messages<char> >(const locale&); 02574 02575 extern template 02576 bool 02577 has_facet<ctype<char> >(const locale&); 02578 02579 extern template 02580 bool 02581 has_facet<codecvt<char, char, mbstate_t> >(const locale&); 02582 02583 extern template 02584 bool 02585 has_facet<collate<char> >(const locale&); 02586 02587 extern template 02588 bool 02589 has_facet<numpunct<char> >(const locale&); 02590 02591 extern template 02592 bool 02593 has_facet<num_put<char> >(const locale&); 02594 02595 extern template 02596 bool 02597 has_facet<num_get<char> >(const locale&); 02598 02599 extern template 02600 bool 02601 has_facet<moneypunct<char> >(const locale&); 02602 02603 extern template 02604 bool 02605 has_facet<money_put<char> >(const locale&); 02606 02607 extern template 02608 bool 02609 has_facet<money_get<char> >(const locale&); 02610 02611 extern template 02612 bool 02613 has_facet<__timepunct<char> >(const locale&); 02614 02615 extern template 02616 bool 02617 has_facet<time_put<char> >(const locale&); 02618 02619 extern template 02620 bool 02621 has_facet<time_get<char> >(const locale&); 02622 02623 extern template 02624 bool 02625 has_facet<messages<char> >(const locale&); 02626 02627 #ifdef _GLIBCXX_USE_WCHAR_T 02628 extern template class moneypunct<wchar_t, false>; 02629 extern template class moneypunct<wchar_t, true>; 02630 extern template class moneypunct_byname<wchar_t, false>; 02631 extern template class moneypunct_byname<wchar_t, true>; 02632 extern template class money_get<wchar_t>; 02633 extern template class money_put<wchar_t>; 02634 extern template class numpunct<wchar_t>; 02635 extern template class numpunct_byname<wchar_t>; 02636 extern template class num_get<wchar_t>; 02637 extern template class num_put<wchar_t>; 02638 extern template class __timepunct<wchar_t>; 02639 extern template class time_put<wchar_t>; 02640 extern template class time_put_byname<wchar_t>; 02641 extern template class time_get<wchar_t>; 02642 extern template class time_get_byname<wchar_t>; 02643 extern template class messages<wchar_t>; 02644 extern template class messages_byname<wchar_t>; 02645 extern template class ctype_byname<wchar_t>; 02646 extern template class codecvt_byname<wchar_t, char, mbstate_t>; 02647 extern template class collate<wchar_t>; 02648 extern template class collate_byname<wchar_t>; 02649 02650 extern template 02651 const codecvt<wchar_t, char, mbstate_t>& 02652 use_facet<codecvt<wchar_t, char, mbstate_t> >(locale const&); 02653 02654 extern template 02655 const collate<wchar_t>& 02656 use_facet<collate<wchar_t> >(const locale&); 02657 02658 extern template 02659 const numpunct<wchar_t>& 02660 use_facet<numpunct<wchar_t> >(const locale&); 02661 02662 extern template 02663 const num_put<wchar_t>& 02664 use_facet<num_put<wchar_t> >(const locale&); 02665 02666 extern template 02667 const num_get<wchar_t>& 02668 use_facet<num_get<wchar_t> >(const locale&); 02669 02670 extern template 02671 const moneypunct<wchar_t, true>& 02672 use_facet<moneypunct<wchar_t, true> >(const locale&); 02673 02674 extern template 02675 const moneypunct<wchar_t, false>& 02676 use_facet<moneypunct<wchar_t, false> >(const locale&); 02677 02678 extern template 02679 const money_put<wchar_t>& 02680 use_facet<money_put<wchar_t> >(const locale&); 02681 02682 extern template 02683 const money_get<wchar_t>& 02684 use_facet<money_get<wchar_t> >(const locale&); 02685 02686 extern template 02687 const __timepunct<wchar_t>& 02688 use_facet<__timepunct<wchar_t> >(const locale&); 02689 02690 extern template 02691 const time_put<wchar_t>& 02692 use_facet<time_put<wchar_t> >(const locale&); 02693 02694 extern template 02695 const time_get<wchar_t>& 02696 use_facet<time_get<wchar_t> >(const locale&); 02697 02698 extern template 02699 const messages<wchar_t>& 02700 use_facet<messages<wchar_t> >(const locale&); 02701 02702 extern template 02703 bool 02704 has_facet<ctype<wchar_t> >(const locale&); 02705 02706 extern template 02707 bool 02708 has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&); 02709 02710 extern template 02711 bool 02712 has_facet<collate<wchar_t> >(const locale&); 02713 02714 extern template 02715 bool 02716 has_facet<numpunct<wchar_t> >(const locale&); 02717 02718 extern template 02719 bool 02720 has_facet<num_put<wchar_t> >(const locale&); 02721 02722 extern template 02723 bool 02724 has_facet<num_get<wchar_t> >(const locale&); 02725 02726 extern template 02727 bool 02728 has_facet<moneypunct<wchar_t> >(const locale&); 02729 02730 extern template 02731 bool 02732 has_facet<money_put<wchar_t> >(const locale&); 02733 02734 extern template 02735 bool 02736 has_facet<money_get<wchar_t> >(const locale&); 02737 02738 extern template 02739 bool 02740 has_facet<__timepunct<wchar_t> >(const locale&); 02741 02742 extern template 02743 bool 02744 has_facet<time_put<wchar_t> >(const locale&); 02745 02746 extern template 02747 bool 02748 has_facet<time_get<wchar_t> >(const locale&); 02749 02750 extern template 02751 bool 02752 has_facet<messages<wchar_t> >(const locale&); 02753 #endif 02754 #endif 02755 } // namespace std 02756 02757 #endif

Generated on Sun Sep 12 15:49:58 2004 for libstdc++ source by doxygen 1.3.8