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

Generated on Wed Aug 4 21:43:13 2004 for libstdc++-v3 Source by doxygen 1.3.8