libstdc++
|
00001 // Locale support -*- C++ -*- 00002 00003 // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file bits/locale_facets_nonio.tcc 00026 * This is an internal header file, included by other library headers. 00027 * Do not attempt to use it directly. @headername{locale} 00028 */ 00029 00030 #ifndef _LOCALE_FACETS_NONIO_TCC 00031 #define _LOCALE_FACETS_NONIO_TCC 1 00032 00033 #pragma GCC system_header 00034 00035 namespace std _GLIBCXX_VISIBILITY(default) 00036 { 00037 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00038 00039 template<typename _CharT, bool _Intl> 00040 struct __use_cache<__moneypunct_cache<_CharT, _Intl> > 00041 { 00042 const __moneypunct_cache<_CharT, _Intl>* 00043 operator() (const locale& __loc) const 00044 { 00045 const size_t __i = moneypunct<_CharT, _Intl>::id._M_id(); 00046 const locale::facet** __caches = __loc._M_impl->_M_caches; 00047 if (!__caches[__i]) 00048 { 00049 __moneypunct_cache<_CharT, _Intl>* __tmp = 0; 00050 __try 00051 { 00052 __tmp = new __moneypunct_cache<_CharT, _Intl>; 00053 __tmp->_M_cache(__loc); 00054 } 00055 __catch(...) 00056 { 00057 delete __tmp; 00058 __throw_exception_again; 00059 } 00060 __loc._M_impl->_M_install_cache(__tmp, __i); 00061 } 00062 return static_cast< 00063 const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]); 00064 } 00065 }; 00066 00067 template<typename _CharT, bool _Intl> 00068 void 00069 __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc) 00070 { 00071 _M_allocated = true; 00072 00073 const moneypunct<_CharT, _Intl>& __mp = 00074 use_facet<moneypunct<_CharT, _Intl> >(__loc); 00075 00076 _M_decimal_point = __mp.decimal_point(); 00077 _M_thousands_sep = __mp.thousands_sep(); 00078 _M_frac_digits = __mp.frac_digits(); 00079 00080 char* __grouping = 0; 00081 _CharT* __curr_symbol = 0; 00082 _CharT* __positive_sign = 0; 00083 _CharT* __negative_sign = 0; 00084 __try 00085 { 00086 _M_grouping_size = __mp.grouping().size(); 00087 __grouping = new char[_M_grouping_size]; 00088 __mp.grouping().copy(__grouping, _M_grouping_size); 00089 _M_grouping = __grouping; 00090 _M_use_grouping = (_M_grouping_size 00091 && static_cast<signed char>(_M_grouping[0]) > 0 00092 && (_M_grouping[0] 00093 != __gnu_cxx::__numeric_traits<char>::__max)); 00094 00095 _M_curr_symbol_size = __mp.curr_symbol().size(); 00096 __curr_symbol = new _CharT[_M_curr_symbol_size]; 00097 __mp.curr_symbol().copy(__curr_symbol, _M_curr_symbol_size); 00098 _M_curr_symbol = __curr_symbol; 00099 00100 _M_positive_sign_size = __mp.positive_sign().size(); 00101 __positive_sign = new _CharT[_M_positive_sign_size]; 00102 __mp.positive_sign().copy(__positive_sign, _M_positive_sign_size); 00103 _M_positive_sign = __positive_sign; 00104 00105 _M_negative_sign_size = __mp.negative_sign().size(); 00106 __negative_sign = new _CharT[_M_negative_sign_size]; 00107 __mp.negative_sign().copy(__negative_sign, _M_negative_sign_size); 00108 _M_negative_sign = __negative_sign; 00109 00110 _M_pos_format = __mp.pos_format(); 00111 _M_neg_format = __mp.neg_format(); 00112 00113 const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc); 00114 __ct.widen(money_base::_S_atoms, 00115 money_base::_S_atoms + money_base::_S_end, _M_atoms); 00116 } 00117 __catch(...) 00118 { 00119 delete [] __grouping; 00120 delete [] __curr_symbol; 00121 delete [] __positive_sign; 00122 delete [] __negative_sign; 00123 __throw_exception_again; 00124 } 00125 } 00126 00127 _GLIBCXX_BEGIN_NAMESPACE_LDBL 00128 00129 template<typename _CharT, typename _InIter> 00130 template<bool _Intl> 00131 _InIter 00132 money_get<_CharT, _InIter>:: 00133 _M_extract(iter_type __beg, iter_type __end, ios_base& __io, 00134 ios_base::iostate& __err, string& __units) const 00135 { 00136 typedef char_traits<_CharT> __traits_type; 00137 typedef typename string_type::size_type size_type; 00138 typedef money_base::part part; 00139 typedef __moneypunct_cache<_CharT, _Intl> __cache_type; 00140 00141 const locale& __loc = __io._M_getloc(); 00142 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 00143 00144 __use_cache<__cache_type> __uc; 00145 const __cache_type* __lc = __uc(__loc); 00146 const char_type* __lit = __lc->_M_atoms; 00147 00148 // Deduced sign. 00149 bool __negative = false; 00150 // Sign size. 00151 size_type __sign_size = 0; 00152 // True if sign is mandatory. 00153 const bool __mandatory_sign = (__lc->_M_positive_sign_size 00154 && __lc->_M_negative_sign_size); 00155 // String of grouping info from thousands_sep plucked from __units. 00156 string __grouping_tmp; 00157 if (__lc->_M_use_grouping) 00158 __grouping_tmp.reserve(32); 00159 // Last position before the decimal point. 00160 int __last_pos = 0; 00161 // Separator positions, then, possibly, fractional digits. 00162 int __n = 0; 00163 // If input iterator is in a valid state. 00164 bool __testvalid = true; 00165 // Flag marking when a decimal point is found. 00166 bool __testdecfound = false; 00167 00168 // The tentative returned string is stored here. 00169 string __res; 00170 __res.reserve(32); 00171 00172 const char_type* __lit_zero = __lit + money_base::_S_zero; 00173 const money_base::pattern __p = __lc->_M_neg_format; 00174 for (int __i = 0; __i < 4 && __testvalid; ++__i) 00175 { 00176 const part __which = static_cast<part>(__p.field[__i]); 00177 switch (__which) 00178 { 00179 case money_base::symbol: 00180 // According to 22.2.6.1.2, p2, symbol is required 00181 // if (__io.flags() & ios_base::showbase), otherwise 00182 // is optional and consumed only if other characters 00183 // are needed to complete the format. 00184 if (__io.flags() & ios_base::showbase || __sign_size > 1 00185 || __i == 0 00186 || (__i == 1 && (__mandatory_sign 00187 || (static_cast<part>(__p.field[0]) 00188 == money_base::sign) 00189 || (static_cast<part>(__p.field[2]) 00190 == money_base::space))) 00191 || (__i == 2 && ((static_cast<part>(__p.field[3]) 00192 == money_base::value) 00193 || (__mandatory_sign 00194 && (static_cast<part>(__p.field[3]) 00195 == money_base::sign))))) 00196 { 00197 const size_type __len = __lc->_M_curr_symbol_size; 00198 size_type __j = 0; 00199 for (; __beg != __end && __j < __len 00200 && *__beg == __lc->_M_curr_symbol[__j]; 00201 ++__beg, ++__j); 00202 if (__j != __len 00203 && (__j || __io.flags() & ios_base::showbase)) 00204 __testvalid = false; 00205 } 00206 break; 00207 case money_base::sign: 00208 // Sign might not exist, or be more than one character long. 00209 if (__lc->_M_positive_sign_size && __beg != __end 00210 && *__beg == __lc->_M_positive_sign[0]) 00211 { 00212 __sign_size = __lc->_M_positive_sign_size; 00213 ++__beg; 00214 } 00215 else if (__lc->_M_negative_sign_size && __beg != __end 00216 && *__beg == __lc->_M_negative_sign[0]) 00217 { 00218 __negative = true; 00219 __sign_size = __lc->_M_negative_sign_size; 00220 ++__beg; 00221 } 00222 else if (__lc->_M_positive_sign_size 00223 && !__lc->_M_negative_sign_size) 00224 // "... if no sign is detected, the result is given the sign 00225 // that corresponds to the source of the empty string" 00226 __negative = true; 00227 else if (__mandatory_sign) 00228 __testvalid = false; 00229 break; 00230 case money_base::value: 00231 // Extract digits, remove and stash away the 00232 // grouping of found thousands separators. 00233 for (; __beg != __end; ++__beg) 00234 { 00235 const char_type __c = *__beg; 00236 const char_type* __q = __traits_type::find(__lit_zero, 00237 10, __c); 00238 if (__q != 0) 00239 { 00240 __res += money_base::_S_atoms[__q - __lit]; 00241 ++__n; 00242 } 00243 else if (__c == __lc->_M_decimal_point 00244 && !__testdecfound) 00245 { 00246 if (__lc->_M_frac_digits <= 0) 00247 break; 00248 00249 __last_pos = __n; 00250 __n = 0; 00251 __testdecfound = true; 00252 } 00253 else if (__lc->_M_use_grouping 00254 && __c == __lc->_M_thousands_sep 00255 && !__testdecfound) 00256 { 00257 if (__n) 00258 { 00259 // Mark position for later analysis. 00260 __grouping_tmp += static_cast<char>(__n); 00261 __n = 0; 00262 } 00263 else 00264 { 00265 __testvalid = false; 00266 break; 00267 } 00268 } 00269 else 00270 break; 00271 } 00272 if (__res.empty()) 00273 __testvalid = false; 00274 break; 00275 case money_base::space: 00276 // At least one space is required. 00277 if (__beg != __end && __ctype.is(ctype_base::space, *__beg)) 00278 ++__beg; 00279 else 00280 __testvalid = false; 00281 case money_base::none: 00282 // Only if not at the end of the pattern. 00283 if (__i != 3) 00284 for (; __beg != __end 00285 && __ctype.is(ctype_base::space, *__beg); ++__beg); 00286 break; 00287 } 00288 } 00289 00290 // Need to get the rest of the sign characters, if they exist. 00291 if (__sign_size > 1 && __testvalid) 00292 { 00293 const char_type* __sign = __negative ? __lc->_M_negative_sign 00294 : __lc->_M_positive_sign; 00295 size_type __i = 1; 00296 for (; __beg != __end && __i < __sign_size 00297 && *__beg == __sign[__i]; ++__beg, ++__i); 00298 00299 if (__i != __sign_size) 00300 __testvalid = false; 00301 } 00302 00303 if (__testvalid) 00304 { 00305 // Strip leading zeros. 00306 if (__res.size() > 1) 00307 { 00308 const size_type __first = __res.find_first_not_of('0'); 00309 const bool __only_zeros = __first == string::npos; 00310 if (__first) 00311 __res.erase(0, __only_zeros ? __res.size() - 1 : __first); 00312 } 00313 00314 // 22.2.6.1.2, p4 00315 if (__negative && __res[0] != '0') 00316 __res.insert(__res.begin(), '-'); 00317 00318 // Test for grouping fidelity. 00319 if (__grouping_tmp.size()) 00320 { 00321 // Add the ending grouping. 00322 __grouping_tmp += static_cast<char>(__testdecfound ? __last_pos 00323 : __n); 00324 if (!std::__verify_grouping(__lc->_M_grouping, 00325 __lc->_M_grouping_size, 00326 __grouping_tmp)) 00327 __err |= ios_base::failbit; 00328 } 00329 00330 // Iff not enough digits were supplied after the decimal-point. 00331 if (__testdecfound && __n != __lc->_M_frac_digits) 00332 __testvalid = false; 00333 } 00334 00335 // Iff valid sequence is not recognized. 00336 if (!__testvalid) 00337 __err |= ios_base::failbit; 00338 else 00339 __units.swap(__res); 00340 00341 // Iff no more characters are available. 00342 if (__beg == __end) 00343 __err |= ios_base::eofbit; 00344 return __beg; 00345 } 00346 00347 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 00348 template<typename _CharT, typename _InIter> 00349 _InIter 00350 money_get<_CharT, _InIter>:: 00351 __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 00352 ios_base::iostate& __err, double& __units) const 00353 { 00354 string __str; 00355 __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str) 00356 : _M_extract<false>(__beg, __end, __io, __err, __str); 00357 std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); 00358 return __beg; 00359 } 00360 #endif 00361 00362 template<typename _CharT, typename _InIter> 00363 _InIter 00364 money_get<_CharT, _InIter>:: 00365 do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 00366 ios_base::iostate& __err, long double& __units) const 00367 { 00368 string __str; 00369 __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str) 00370 : _M_extract<false>(__beg, __end, __io, __err, __str); 00371 std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); 00372 return __beg; 00373 } 00374 00375 template<typename _CharT, typename _InIter> 00376 _InIter 00377 money_get<_CharT, _InIter>:: 00378 do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 00379 ios_base::iostate& __err, string_type& __digits) const 00380 { 00381 typedef typename string::size_type size_type; 00382 00383 const locale& __loc = __io._M_getloc(); 00384 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 00385 00386 string __str; 00387 __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str) 00388 : _M_extract<false>(__beg, __end, __io, __err, __str); 00389 const size_type __len = __str.size(); 00390 if (__len) 00391 { 00392 __digits.resize(__len); 00393 __ctype.widen(__str.data(), __str.data() + __len, &__digits[0]); 00394 } 00395 return __beg; 00396 } 00397 00398 template<typename _CharT, typename _OutIter> 00399 template<bool _Intl> 00400 _OutIter 00401 money_put<_CharT, _OutIter>:: 00402 _M_insert(iter_type __s, ios_base& __io, char_type __fill, 00403 const string_type& __digits) const 00404 { 00405 typedef typename string_type::size_type size_type; 00406 typedef money_base::part part; 00407 typedef __moneypunct_cache<_CharT, _Intl> __cache_type; 00408 00409 const locale& __loc = __io._M_getloc(); 00410 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 00411 00412 __use_cache<__cache_type> __uc; 00413 const __cache_type* __lc = __uc(__loc); 00414 const char_type* __lit = __lc->_M_atoms; 00415 00416 // Determine if negative or positive formats are to be used, and 00417 // discard leading negative_sign if it is present. 00418 const char_type* __beg = __digits.data(); 00419 00420 money_base::pattern __p; 00421 const char_type* __sign; 00422 size_type __sign_size; 00423 if (!(*__beg == __lit[money_base::_S_minus])) 00424 { 00425 __p = __lc->_M_pos_format; 00426 __sign = __lc->_M_positive_sign; 00427 __sign_size = __lc->_M_positive_sign_size; 00428 } 00429 else 00430 { 00431 __p = __lc->_M_neg_format; 00432 __sign = __lc->_M_negative_sign; 00433 __sign_size = __lc->_M_negative_sign_size; 00434 if (__digits.size()) 00435 ++__beg; 00436 } 00437 00438 // Look for valid numbers in the ctype facet within input digits. 00439 size_type __len = __ctype.scan_not(ctype_base::digit, __beg, 00440 __beg + __digits.size()) - __beg; 00441 if (__len) 00442 { 00443 // Assume valid input, and attempt to format. 00444 // Break down input numbers into base components, as follows: 00445 // final_value = grouped units + (decimal point) + (digits) 00446 string_type __value; 00447 __value.reserve(2 * __len); 00448 00449 // Add thousands separators to non-decimal digits, per 00450 // grouping rules. 00451 long __paddec = __len - __lc->_M_frac_digits; 00452 if (__paddec > 0) 00453 { 00454 if (__lc->_M_frac_digits < 0) 00455 __paddec = __len; 00456 if (__lc->_M_grouping_size) 00457 { 00458 __value.assign(2 * __paddec, char_type()); 00459 _CharT* __vend = 00460 std::__add_grouping(&__value[0], __lc->_M_thousands_sep, 00461 __lc->_M_grouping, 00462 __lc->_M_grouping_size, 00463 __beg, __beg + __paddec); 00464 __value.erase(__vend - &__value[0]); 00465 } 00466 else 00467 __value.assign(__beg, __paddec); 00468 } 00469 00470 // Deal with decimal point, decimal digits. 00471 if (__lc->_M_frac_digits > 0) 00472 { 00473 __value += __lc->_M_decimal_point; 00474 if (__paddec >= 0) 00475 __value.append(__beg + __paddec, __lc->_M_frac_digits); 00476 else 00477 { 00478 // Have to pad zeros in the decimal position. 00479 __value.append(-__paddec, __lit[money_base::_S_zero]); 00480 __value.append(__beg, __len); 00481 } 00482 } 00483 00484 // Calculate length of resulting string. 00485 const ios_base::fmtflags __f = __io.flags() 00486 & ios_base::adjustfield; 00487 __len = __value.size() + __sign_size; 00488 __len += ((__io.flags() & ios_base::showbase) 00489 ? __lc->_M_curr_symbol_size : 0); 00490 00491 string_type __res; 00492 __res.reserve(2 * __len); 00493 00494 const size_type __width = static_cast<size_type>(__io.width()); 00495 const bool __testipad = (__f == ios_base::internal 00496 && __len < __width); 00497 // Fit formatted digits into the required pattern. 00498 for (int __i = 0; __i < 4; ++__i) 00499 { 00500 const part __which = static_cast<part>(__p.field[__i]); 00501 switch (__which) 00502 { 00503 case money_base::symbol: 00504 if (__io.flags() & ios_base::showbase) 00505 __res.append(__lc->_M_curr_symbol, 00506 __lc->_M_curr_symbol_size); 00507 break; 00508 case money_base::sign: 00509 // Sign might not exist, or be more than one 00510 // character long. In that case, add in the rest 00511 // below. 00512 if (__sign_size) 00513 __res += __sign[0]; 00514 break; 00515 case money_base::value: 00516 __res += __value; 00517 break; 00518 case money_base::space: 00519 // At least one space is required, but if internal 00520 // formatting is required, an arbitrary number of 00521 // fill spaces will be necessary. 00522 if (__testipad) 00523 __res.append(__width - __len, __fill); 00524 else 00525 __res += __fill; 00526 break; 00527 case money_base::none: 00528 if (__testipad) 00529 __res.append(__width - __len, __fill); 00530 break; 00531 } 00532 } 00533 00534 // Special case of multi-part sign parts. 00535 if (__sign_size > 1) 00536 __res.append(__sign + 1, __sign_size - 1); 00537 00538 // Pad, if still necessary. 00539 __len = __res.size(); 00540 if (__width > __len) 00541 { 00542 if (__f == ios_base::left) 00543 // After. 00544 __res.append(__width - __len, __fill); 00545 else 00546 // Before. 00547 __res.insert(0, __width - __len, __fill); 00548 __len = __width; 00549 } 00550 00551 // Write resulting, fully-formatted string to output iterator. 00552 __s = std::__write(__s, __res.data(), __len); 00553 } 00554 __io.width(0); 00555 return __s; 00556 } 00557 00558 #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 00559 template<typename _CharT, typename _OutIter> 00560 _OutIter 00561 money_put<_CharT, _OutIter>:: 00562 __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 00563 double __units) const 00564 { return this->do_put(__s, __intl, __io, __fill, (long double) __units); } 00565 #endif 00566 00567 template<typename _CharT, typename _OutIter> 00568 _OutIter 00569 money_put<_CharT, _OutIter>:: 00570 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 00571 long double __units) const 00572 { 00573 const locale __loc = __io.getloc(); 00574 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 00575 #ifdef _GLIBCXX_USE_C99 00576 // First try a buffer perhaps big enough. 00577 int __cs_size = 64; 00578 char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 00579 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00580 // 328. Bad sprintf format modifier in money_put<>::do_put() 00581 int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, 00582 "%.*Lf", 0, __units); 00583 // If the buffer was not large enough, try again with the correct size. 00584 if (__len >= __cs_size) 00585 { 00586 __cs_size = __len + 1; 00587 __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 00588 __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, 00589 "%.*Lf", 0, __units); 00590 } 00591 #else 00592 // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. 00593 const int __cs_size = 00594 __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 3; 00595 char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 00596 int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf", 00597 0, __units); 00598 #endif 00599 string_type __digits(__len, char_type()); 00600 __ctype.widen(__cs, __cs + __len, &__digits[0]); 00601 return __intl ? _M_insert<true>(__s, __io, __fill, __digits) 00602 : _M_insert<false>(__s, __io, __fill, __digits); 00603 } 00604 00605 template<typename _CharT, typename _OutIter> 00606 _OutIter 00607 money_put<_CharT, _OutIter>:: 00608 do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 00609 const string_type& __digits) const 00610 { return __intl ? _M_insert<true>(__s, __io, __fill, __digits) 00611 : _M_insert<false>(__s, __io, __fill, __digits); } 00612 00613 _GLIBCXX_END_NAMESPACE_LDBL 00614 00615 // NB: Not especially useful. Without an ios_base object or some 00616 // kind of locale reference, we are left clawing at the air where 00617 // the side of the mountain used to be... 00618 template<typename _CharT, typename _InIter> 00619 time_base::dateorder 00620 time_get<_CharT, _InIter>::do_date_order() const 00621 { return time_base::no_order; } 00622 00623 // Expand a strftime format string and parse it. E.g., do_get_date() may 00624 // pass %m/%d/%Y => extracted characters. 00625 template<typename _CharT, typename _InIter> 00626 _InIter 00627 time_get<_CharT, _InIter>:: 00628 _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, 00629 ios_base::iostate& __err, tm* __tm, 00630 const _CharT* __format) const 00631 { 00632 const locale& __loc = __io._M_getloc(); 00633 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 00634 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 00635 const size_t __len = char_traits<_CharT>::length(__format); 00636 00637 ios_base::iostate __tmperr = ios_base::goodbit; 00638 size_t __i = 0; 00639 for (; __beg != __end && __i < __len && !__tmperr; ++__i) 00640 { 00641 if (__ctype.narrow(__format[__i], 0) == '%') 00642 { 00643 // Verify valid formatting code, attempt to extract. 00644 char __c = __ctype.narrow(__format[++__i], 0); 00645 int __mem = 0; 00646 if (__c == 'E' || __c == 'O') 00647 __c = __ctype.narrow(__format[++__i], 0); 00648 switch (__c) 00649 { 00650 const char* __cs; 00651 _CharT __wcs[10]; 00652 case 'a': 00653 // Abbreviated weekday name [tm_wday] 00654 const char_type* __days1[7]; 00655 __tp._M_days_abbreviated(__days1); 00656 __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 00657 7, __io, __tmperr); 00658 break; 00659 case 'A': 00660 // Weekday name [tm_wday]. 00661 const char_type* __days2[7]; 00662 __tp._M_days(__days2); 00663 __beg = _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 00664 7, __io, __tmperr); 00665 break; 00666 case 'h': 00667 case 'b': 00668 // Abbreviated month name [tm_mon] 00669 const char_type* __months1[12]; 00670 __tp._M_months_abbreviated(__months1); 00671 __beg = _M_extract_name(__beg, __end, __tm->tm_mon, 00672 __months1, 12, __io, __tmperr); 00673 break; 00674 case 'B': 00675 // Month name [tm_mon]. 00676 const char_type* __months2[12]; 00677 __tp._M_months(__months2); 00678 __beg = _M_extract_name(__beg, __end, __tm->tm_mon, 00679 __months2, 12, __io, __tmperr); 00680 break; 00681 case 'c': 00682 // Default time and date representation. 00683 const char_type* __dt[2]; 00684 __tp._M_date_time_formats(__dt); 00685 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 00686 __tm, __dt[0]); 00687 break; 00688 case 'd': 00689 // Day [01, 31]. [tm_mday] 00690 __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, 00691 __io, __tmperr); 00692 break; 00693 case 'e': 00694 // Day [1, 31], with single digits preceded by 00695 // space. [tm_mday] 00696 if (__ctype.is(ctype_base::space, *__beg)) 00697 __beg = _M_extract_num(++__beg, __end, __tm->tm_mday, 1, 9, 00698 1, __io, __tmperr); 00699 else 00700 __beg = _M_extract_num(__beg, __end, __tm->tm_mday, 10, 31, 00701 2, __io, __tmperr); 00702 break; 00703 case 'D': 00704 // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] 00705 __cs = "%m/%d/%y"; 00706 __ctype.widen(__cs, __cs + 9, __wcs); 00707 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 00708 __tm, __wcs); 00709 break; 00710 case 'H': 00711 // Hour [00, 23]. [tm_hour] 00712 __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2, 00713 __io, __tmperr); 00714 break; 00715 case 'I': 00716 // Hour [01, 12]. [tm_hour] 00717 __beg = _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2, 00718 __io, __tmperr); 00719 break; 00720 case 'm': 00721 // Month [01, 12]. [tm_mon] 00722 __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, 00723 __io, __tmperr); 00724 if (!__tmperr) 00725 __tm->tm_mon = __mem - 1; 00726 break; 00727 case 'M': 00728 // Minute [00, 59]. [tm_min] 00729 __beg = _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2, 00730 __io, __tmperr); 00731 break; 00732 case 'n': 00733 if (__ctype.narrow(*__beg, 0) == '\n') 00734 ++__beg; 00735 else 00736 __tmperr |= ios_base::failbit; 00737 break; 00738 case 'R': 00739 // Equivalent to (%H:%M). 00740 __cs = "%H:%M"; 00741 __ctype.widen(__cs, __cs + 6, __wcs); 00742 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 00743 __tm, __wcs); 00744 break; 00745 case 'S': 00746 // Seconds. [tm_sec] 00747 // [00, 60] in C99 (one leap-second), [00, 61] in C89. 00748 #ifdef _GLIBCXX_USE_C99 00749 __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 60, 2, 00750 #else 00751 __beg = _M_extract_num(__beg, __end, __tm->tm_sec, 0, 61, 2, 00752 #endif 00753 __io, __tmperr); 00754 break; 00755 case 't': 00756 if (__ctype.narrow(*__beg, 0) == '\t') 00757 ++__beg; 00758 else 00759 __tmperr |= ios_base::failbit; 00760 break; 00761 case 'T': 00762 // Equivalent to (%H:%M:%S). 00763 __cs = "%H:%M:%S"; 00764 __ctype.widen(__cs, __cs + 9, __wcs); 00765 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 00766 __tm, __wcs); 00767 break; 00768 case 'x': 00769 // Locale's date. 00770 const char_type* __dates[2]; 00771 __tp._M_date_formats(__dates); 00772 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 00773 __tm, __dates[0]); 00774 break; 00775 case 'X': 00776 // Locale's time. 00777 const char_type* __times[2]; 00778 __tp._M_time_formats(__times); 00779 __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 00780 __tm, __times[0]); 00781 break; 00782 case 'y': 00783 case 'C': // C99 00784 // Two digit year. 00785 case 'Y': 00786 // Year [1900). 00787 // NB: We parse either two digits, implicitly years since 00788 // 1900, or 4 digits, full year. In both cases we can 00789 // reconstruct [tm_year]. See also libstdc++/26701. 00790 __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4, 00791 __io, __tmperr); 00792 if (!__tmperr) 00793 __tm->tm_year = __mem < 0 ? __mem + 100 : __mem - 1900; 00794 break; 00795 case 'Z': 00796 // Timezone info. 00797 if (__ctype.is(ctype_base::upper, *__beg)) 00798 { 00799 int __tmp; 00800 __beg = _M_extract_name(__beg, __end, __tmp, 00801 __timepunct_cache<_CharT>::_S_timezones, 00802 14, __io, __tmperr); 00803 00804 // GMT requires special effort. 00805 if (__beg != __end && !__tmperr && __tmp == 0 00806 && (*__beg == __ctype.widen('-') 00807 || *__beg == __ctype.widen('+'))) 00808 { 00809 __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2, 00810 __io, __tmperr); 00811 __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2, 00812 __io, __tmperr); 00813 } 00814 } 00815 else 00816 __tmperr |= ios_base::failbit; 00817 break; 00818 default: 00819 // Not recognized. 00820 __tmperr |= ios_base::failbit; 00821 } 00822 } 00823 else 00824 { 00825 // Verify format and input match, extract and discard. 00826 if (__format[__i] == *__beg) 00827 ++__beg; 00828 else 00829 __tmperr |= ios_base::failbit; 00830 } 00831 } 00832 00833 if (__tmperr || __i != __len) 00834 __err |= ios_base::failbit; 00835 00836 return __beg; 00837 } 00838 00839 template<typename _CharT, typename _InIter> 00840 _InIter 00841 time_get<_CharT, _InIter>:: 00842 _M_extract_num(iter_type __beg, iter_type __end, int& __member, 00843 int __min, int __max, size_t __len, 00844 ios_base& __io, ios_base::iostate& __err) const 00845 { 00846 const locale& __loc = __io._M_getloc(); 00847 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 00848 00849 // As-is works for __len = 1, 2, 4, the values actually used. 00850 int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1); 00851 00852 ++__min; 00853 size_t __i = 0; 00854 int __value = 0; 00855 for (; __beg != __end && __i < __len; ++__beg, ++__i) 00856 { 00857 const char __c = __ctype.narrow(*__beg, '*'); 00858 if (__c >= '0' && __c <= '9') 00859 { 00860 __value = __value * 10 + (__c - '0'); 00861 const int __valuec = __value * __mult; 00862 if (__valuec > __max || __valuec + __mult < __min) 00863 break; 00864 __mult /= 10; 00865 } 00866 else 00867 break; 00868 } 00869 if (__i == __len) 00870 __member = __value; 00871 // Special encoding for do_get_year, 'y', and 'Y' above. 00872 else if (__len == 4 && __i == 2) 00873 __member = __value - 100; 00874 else 00875 __err |= ios_base::failbit; 00876 00877 return __beg; 00878 } 00879 00880 // Assumptions: 00881 // All elements in __names are unique. 00882 template<typename _CharT, typename _InIter> 00883 _InIter 00884 time_get<_CharT, _InIter>:: 00885 _M_extract_name(iter_type __beg, iter_type __end, int& __member, 00886 const _CharT** __names, size_t __indexlen, 00887 ios_base& __io, ios_base::iostate& __err) const 00888 { 00889 typedef char_traits<_CharT> __traits_type; 00890 const locale& __loc = __io._M_getloc(); 00891 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 00892 00893 int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) 00894 * __indexlen)); 00895 size_t __nmatches = 0; 00896 size_t __pos = 0; 00897 bool __testvalid = true; 00898 const char_type* __name; 00899 00900 // Look for initial matches. 00901 // NB: Some of the locale data is in the form of all lowercase 00902 // names, and some is in the form of initially-capitalized 00903 // names. Look for both. 00904 if (__beg != __end) 00905 { 00906 const char_type __c = *__beg; 00907 for (size_t __i1 = 0; __i1 < __indexlen; ++__i1) 00908 if (__c == __names[__i1][0] 00909 || __c == __ctype.toupper(__names[__i1][0])) 00910 __matches[__nmatches++] = __i1; 00911 } 00912 00913 while (__nmatches > 1) 00914 { 00915 // Find smallest matching string. 00916 size_t __minlen = __traits_type::length(__names[__matches[0]]); 00917 for (size_t __i2 = 1; __i2 < __nmatches; ++__i2) 00918 __minlen = std::min(__minlen, 00919 __traits_type::length(__names[__matches[__i2]])); 00920 ++__beg, ++__pos; 00921 if (__pos < __minlen && __beg != __end) 00922 for (size_t __i3 = 0; __i3 < __nmatches;) 00923 { 00924 __name = __names[__matches[__i3]]; 00925 if (!(__name[__pos] == *__beg)) 00926 __matches[__i3] = __matches[--__nmatches]; 00927 else 00928 ++__i3; 00929 } 00930 else 00931 break; 00932 } 00933 00934 if (__nmatches == 1) 00935 { 00936 // Make sure found name is completely extracted. 00937 ++__beg, ++__pos; 00938 __name = __names[__matches[0]]; 00939 const size_t __len = __traits_type::length(__name); 00940 while (__pos < __len && __beg != __end && __name[__pos] == *__beg) 00941 ++__beg, ++__pos; 00942 00943 if (__len == __pos) 00944 __member = __matches[0]; 00945 else 00946 __testvalid = false; 00947 } 00948 else 00949 __testvalid = false; 00950 if (!__testvalid) 00951 __err |= ios_base::failbit; 00952 00953 return __beg; 00954 } 00955 00956 template<typename _CharT, typename _InIter> 00957 _InIter 00958 time_get<_CharT, _InIter>:: 00959 _M_extract_wday_or_month(iter_type __beg, iter_type __end, int& __member, 00960 const _CharT** __names, size_t __indexlen, 00961 ios_base& __io, ios_base::iostate& __err) const 00962 { 00963 typedef char_traits<_CharT> __traits_type; 00964 const locale& __loc = __io._M_getloc(); 00965 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 00966 00967 int* __matches = static_cast<int*>(__builtin_alloca(2 * sizeof(int) 00968 * __indexlen)); 00969 size_t __nmatches = 0; 00970 size_t* __matches_lengths = 0; 00971 size_t __pos = 0; 00972 00973 if (__beg != __end) 00974 { 00975 const char_type __c = *__beg; 00976 for (size_t __i = 0; __i < 2 * __indexlen; ++__i) 00977 if (__c == __names[__i][0] 00978 || __c == __ctype.toupper(__names[__i][0])) 00979 __matches[__nmatches++] = __i; 00980 } 00981 00982 if (__nmatches) 00983 { 00984 ++__beg, ++__pos; 00985 00986 __matches_lengths 00987 = static_cast<size_t*>(__builtin_alloca(sizeof(size_t) 00988 * __nmatches)); 00989 for (size_t __i = 0; __i < __nmatches; ++__i) 00990 __matches_lengths[__i] 00991 = __traits_type::length(__names[__matches[__i]]); 00992 } 00993 00994 for (; __beg != __end; ++__beg, ++__pos) 00995 { 00996 size_t __nskipped = 0; 00997 const char_type __c = *__beg; 00998 for (size_t __i = 0; __i < __nmatches;) 00999 { 01000 const char_type* __name = __names[__matches[__i]]; 01001 if (__pos >= __matches_lengths[__i]) 01002 ++__nskipped, ++__i; 01003 else if (!(__name[__pos] == __c)) 01004 { 01005 --__nmatches; 01006 __matches[__i] = __matches[__nmatches]; 01007 __matches_lengths[__i] = __matches_lengths[__nmatches]; 01008 } 01009 else 01010 ++__i; 01011 } 01012 if (__nskipped == __nmatches) 01013 break; 01014 } 01015 01016 if ((__nmatches == 1 && __matches_lengths[0] == __pos) 01017 || (__nmatches == 2 && (__matches_lengths[0] == __pos 01018 || __matches_lengths[1] == __pos))) 01019 __member = (__matches[0] >= __indexlen 01020 ? __matches[0] - __indexlen : __matches[0]); 01021 else 01022 __err |= ios_base::failbit; 01023 01024 return __beg; 01025 } 01026 01027 template<typename _CharT, typename _InIter> 01028 _InIter 01029 time_get<_CharT, _InIter>:: 01030 do_get_time(iter_type __beg, iter_type __end, ios_base& __io, 01031 ios_base::iostate& __err, tm* __tm) const 01032 { 01033 const locale& __loc = __io._M_getloc(); 01034 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 01035 const char_type* __times[2]; 01036 __tp._M_time_formats(__times); 01037 __beg = _M_extract_via_format(__beg, __end, __io, __err, 01038 __tm, __times[0]); 01039 if (__beg == __end) 01040 __err |= ios_base::eofbit; 01041 return __beg; 01042 } 01043 01044 template<typename _CharT, typename _InIter> 01045 _InIter 01046 time_get<_CharT, _InIter>:: 01047 do_get_date(iter_type __beg, iter_type __end, ios_base& __io, 01048 ios_base::iostate& __err, tm* __tm) const 01049 { 01050 const locale& __loc = __io._M_getloc(); 01051 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 01052 const char_type* __dates[2]; 01053 __tp._M_date_formats(__dates); 01054 __beg = _M_extract_via_format(__beg, __end, __io, __err, 01055 __tm, __dates[0]); 01056 if (__beg == __end) 01057 __err |= ios_base::eofbit; 01058 return __beg; 01059 } 01060 01061 template<typename _CharT, typename _InIter> 01062 _InIter 01063 time_get<_CharT, _InIter>:: 01064 do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, 01065 ios_base::iostate& __err, tm* __tm) const 01066 { 01067 typedef char_traits<_CharT> __traits_type; 01068 const locale& __loc = __io._M_getloc(); 01069 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 01070 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 01071 const char_type* __days[14]; 01072 __tp._M_days_abbreviated(__days); 01073 __tp._M_days(__days + 7); 01074 int __tmpwday; 01075 ios_base::iostate __tmperr = ios_base::goodbit; 01076 01077 __beg = _M_extract_wday_or_month(__beg, __end, __tmpwday, __days, 7, 01078 __io, __tmperr); 01079 if (!__tmperr) 01080 __tm->tm_wday = __tmpwday; 01081 else 01082 __err |= ios_base::failbit; 01083 01084 if (__beg == __end) 01085 __err |= ios_base::eofbit; 01086 return __beg; 01087 } 01088 01089 template<typename _CharT, typename _InIter> 01090 _InIter 01091 time_get<_CharT, _InIter>:: 01092 do_get_monthname(iter_type __beg, iter_type __end, 01093 ios_base& __io, ios_base::iostate& __err, tm* __tm) const 01094 { 01095 typedef char_traits<_CharT> __traits_type; 01096 const locale& __loc = __io._M_getloc(); 01097 const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 01098 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 01099 const char_type* __months[24]; 01100 __tp._M_months_abbreviated(__months); 01101 __tp._M_months(__months + 12); 01102 int __tmpmon; 01103 ios_base::iostate __tmperr = ios_base::goodbit; 01104 01105 __beg = _M_extract_wday_or_month(__beg, __end, __tmpmon, __months, 12, 01106 __io, __tmperr); 01107 if (!__tmperr) 01108 __tm->tm_mon = __tmpmon; 01109 else 01110 __err |= ios_base::failbit; 01111 01112 if (__beg == __end) 01113 __err |= ios_base::eofbit; 01114 return __beg; 01115 } 01116 01117 template<typename _CharT, typename _InIter> 01118 _InIter 01119 time_get<_CharT, _InIter>:: 01120 do_get_year(iter_type __beg, iter_type __end, ios_base& __io, 01121 ios_base::iostate& __err, tm* __tm) const 01122 { 01123 const locale& __loc = __io._M_getloc(); 01124 const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 01125 int __tmpyear; 01126 ios_base::iostate __tmperr = ios_base::goodbit; 01127 01128 __beg = _M_extract_num(__beg, __end, __tmpyear, 0, 9999, 4, 01129 __io, __tmperr); 01130 if (!__tmperr) 01131 __tm->tm_year = __tmpyear < 0 ? __tmpyear + 100 : __tmpyear - 1900; 01132 else 01133 __err |= ios_base::failbit; 01134 01135 if (__beg == __end) 01136 __err |= ios_base::eofbit; 01137 return __beg; 01138 } 01139 01140 template<typename _CharT, typename _OutIter> 01141 _OutIter 01142 time_put<_CharT, _OutIter>:: 01143 put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, 01144 const _CharT* __beg, const _CharT* __end) const 01145 { 01146 const locale& __loc = __io._M_getloc(); 01147 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); 01148 for (; __beg != __end; ++__beg) 01149 if (__ctype.narrow(*__beg, 0) != '%') 01150 { 01151 *__s = *__beg; 01152 ++__s; 01153 } 01154 else if (++__beg != __end) 01155 { 01156 char __format; 01157 char __mod = 0; 01158 const char __c = __ctype.narrow(*__beg, 0); 01159 if (__c != 'E' && __c != 'O') 01160 __format = __c; 01161 else if (++__beg != __end) 01162 { 01163 __mod = __c; 01164 __format = __ctype.narrow(*__beg, 0); 01165 } 01166 else 01167 break; 01168 __s = this->do_put(__s, __io, __fill, __tm, __format, __mod); 01169 } 01170 else 01171 break; 01172 return __s; 01173 } 01174 01175 template<typename _CharT, typename _OutIter> 01176 _OutIter 01177 time_put<_CharT, _OutIter>:: 01178 do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, 01179 char __format, char __mod) const 01180 { 01181 const locale& __loc = __io._M_getloc(); 01182 ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); 01183 __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); 01184 01185 // NB: This size is arbitrary. Should this be a data member, 01186 // initialized at construction? 01187 const size_t __maxlen = 128; 01188 char_type __res[__maxlen]; 01189 01190 // NB: In IEE 1003.1-200x, and perhaps other locale models, it 01191 // is possible that the format character will be longer than one 01192 // character. Possibilities include 'E' or 'O' followed by a 01193 // format character: if __mod is not the default argument, assume 01194 // it's a valid modifier. 01195 char_type __fmt[4]; 01196 __fmt[0] = __ctype.widen('%'); 01197 if (!__mod) 01198 { 01199 __fmt[1] = __format; 01200 __fmt[2] = char_type(); 01201 } 01202 else 01203 { 01204 __fmt[1] = __mod; 01205 __fmt[2] = __format; 01206 __fmt[3] = char_type(); 01207 } 01208 01209 __tp._M_put(__res, __maxlen, __fmt, __tm); 01210 01211 // Write resulting, fully-formatted string to output iterator. 01212 return std::__write(__s, __res, char_traits<char_type>::length(__res)); 01213 } 01214 01215 01216 // Inhibit implicit instantiations for required instantiations, 01217 // which are defined via explicit instantiations elsewhere. 01218 #if _GLIBCXX_EXTERN_TEMPLATE 01219 extern template class moneypunct<char, false>; 01220 extern template class moneypunct<char, true>; 01221 extern template class moneypunct_byname<char, false>; 01222 extern template class moneypunct_byname<char, true>; 01223 extern template class _GLIBCXX_NAMESPACE_LDBL money_get<char>; 01224 extern template class _GLIBCXX_NAMESPACE_LDBL money_put<char>; 01225 extern template class __timepunct<char>; 01226 extern template class time_put<char>; 01227 extern template class time_put_byname<char>; 01228 extern template class time_get<char>; 01229 extern template class time_get_byname<char>; 01230 extern template class messages<char>; 01231 extern template class messages_byname<char>; 01232 01233 extern template 01234 const moneypunct<char, true>& 01235 use_facet<moneypunct<char, true> >(const locale&); 01236 01237 extern template 01238 const moneypunct<char, false>& 01239 use_facet<moneypunct<char, false> >(const locale&); 01240 01241 extern template 01242 const money_put<char>& 01243 use_facet<money_put<char> >(const locale&); 01244 01245 extern template 01246 const money_get<char>& 01247 use_facet<money_get<char> >(const locale&); 01248 01249 extern template 01250 const __timepunct<char>& 01251 use_facet<__timepunct<char> >(const locale&); 01252 01253 extern template 01254 const time_put<char>& 01255 use_facet<time_put<char> >(const locale&); 01256 01257 extern template 01258 const time_get<char>& 01259 use_facet<time_get<char> >(const locale&); 01260 01261 extern template 01262 const messages<char>& 01263 use_facet<messages<char> >(const locale&); 01264 01265 extern template 01266 bool 01267 has_facet<moneypunct<char> >(const locale&); 01268 01269 extern template 01270 bool 01271 has_facet<money_put<char> >(const locale&); 01272 01273 extern template 01274 bool 01275 has_facet<money_get<char> >(const locale&); 01276 01277 extern template 01278 bool 01279 has_facet<__timepunct<char> >(const locale&); 01280 01281 extern template 01282 bool 01283 has_facet<time_put<char> >(const locale&); 01284 01285 extern template 01286 bool 01287 has_facet<time_get<char> >(const locale&); 01288 01289 extern template 01290 bool 01291 has_facet<messages<char> >(const locale&); 01292 01293 #ifdef _GLIBCXX_USE_WCHAR_T 01294 extern template class moneypunct<wchar_t, false>; 01295 extern template class moneypunct<wchar_t, true>; 01296 extern template class moneypunct_byname<wchar_t, false>; 01297 extern template class moneypunct_byname<wchar_t, true>; 01298 extern template class _GLIBCXX_NAMESPACE_LDBL money_get<wchar_t>; 01299 extern template class _GLIBCXX_NAMESPACE_LDBL money_put<wchar_t>; 01300 extern template class __timepunct<wchar_t>; 01301 extern template class time_put<wchar_t>; 01302 extern template class time_put_byname<wchar_t>; 01303 extern template class time_get<wchar_t>; 01304 extern template class time_get_byname<wchar_t>; 01305 extern template class messages<wchar_t>; 01306 extern template class messages_byname<wchar_t>; 01307 01308 extern template 01309 const moneypunct<wchar_t, true>& 01310 use_facet<moneypunct<wchar_t, true> >(const locale&); 01311 01312 extern template 01313 const moneypunct<wchar_t, false>& 01314 use_facet<moneypunct<wchar_t, false> >(const locale&); 01315 01316 extern template 01317 const money_put<wchar_t>& 01318 use_facet<money_put<wchar_t> >(const locale&); 01319 01320 extern template 01321 const money_get<wchar_t>& 01322 use_facet<money_get<wchar_t> >(const locale&); 01323 01324 extern template 01325 const __timepunct<wchar_t>& 01326 use_facet<__timepunct<wchar_t> >(const locale&); 01327 01328 extern template 01329 const time_put<wchar_t>& 01330 use_facet<time_put<wchar_t> >(const locale&); 01331 01332 extern template 01333 const time_get<wchar_t>& 01334 use_facet<time_get<wchar_t> >(const locale&); 01335 01336 extern template 01337 const messages<wchar_t>& 01338 use_facet<messages<wchar_t> >(const locale&); 01339 01340 extern template 01341 bool 01342 has_facet<moneypunct<wchar_t> >(const locale&); 01343 01344 extern template 01345 bool 01346 has_facet<money_put<wchar_t> >(const locale&); 01347 01348 extern template 01349 bool 01350 has_facet<money_get<wchar_t> >(const locale&); 01351 01352 extern template 01353 bool 01354 has_facet<__timepunct<wchar_t> >(const locale&); 01355 01356 extern template 01357 bool 01358 has_facet<time_put<wchar_t> >(const locale&); 01359 01360 extern template 01361 bool 01362 has_facet<time_get<wchar_t> >(const locale&); 01363 01364 extern template 01365 bool 01366 has_facet<messages<wchar_t> >(const locale&); 01367 #endif 01368 #endif 01369 01370 _GLIBCXX_END_NAMESPACE_VERSION 01371 } // namespace std 01372 01373 #endif