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

Generated on Wed Aug 4 22:34:26 2004 for libstdc++-v3 Source by doxygen 1.3.8