1*38fd1498Szrj // Locale support -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 2007-2018 Free Software Foundation, Inc. 4*38fd1498Szrj // 5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj // software; you can redistribute it and/or modify it under the 7*38fd1498Szrj // terms of the GNU General Public License as published by the 8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj // any later version. 10*38fd1498Szrj 11*38fd1498Szrj // This library is distributed in the hope that it will be useful, 12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj // GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj // You should have received a copy of the GNU General Public License and 21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj // <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj /** @file bits/locale_facets_nonio.tcc 26*38fd1498Szrj * This is an internal header file, included by other library headers. 27*38fd1498Szrj * Do not attempt to use it directly. @headername{locale} 28*38fd1498Szrj */ 29*38fd1498Szrj 30*38fd1498Szrj #ifndef _LOCALE_FACETS_NONIO_TCC 31*38fd1498Szrj #define _LOCALE_FACETS_NONIO_TCC 1 32*38fd1498Szrj 33*38fd1498Szrj #pragma GCC system_header 34*38fd1498Szrj 35*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 36*38fd1498Szrj { 37*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 38*38fd1498Szrj 39*38fd1498Szrj template<typename _CharT, bool _Intl> 40*38fd1498Szrj struct __use_cache<__moneypunct_cache<_CharT, _Intl> > 41*38fd1498Szrj { 42*38fd1498Szrj const __moneypunct_cache<_CharT, _Intl>* operator ()std::__use_cache43*38fd1498Szrj operator() (const locale& __loc) const 44*38fd1498Szrj { 45*38fd1498Szrj const size_t __i = moneypunct<_CharT, _Intl>::id._M_id(); 46*38fd1498Szrj const locale::facet** __caches = __loc._M_impl->_M_caches; 47*38fd1498Szrj if (!__caches[__i]) 48*38fd1498Szrj { 49*38fd1498Szrj __moneypunct_cache<_CharT, _Intl>* __tmp = 0; 50*38fd1498Szrj __try 51*38fd1498Szrj { 52*38fd1498Szrj __tmp = new __moneypunct_cache<_CharT, _Intl>; 53*38fd1498Szrj __tmp->_M_cache(__loc); 54*38fd1498Szrj } 55*38fd1498Szrj __catch(...) 56*38fd1498Szrj { 57*38fd1498Szrj delete __tmp; 58*38fd1498Szrj __throw_exception_again; 59*38fd1498Szrj } 60*38fd1498Szrj __loc._M_impl->_M_install_cache(__tmp, __i); 61*38fd1498Szrj } 62*38fd1498Szrj return static_cast< 63*38fd1498Szrj const __moneypunct_cache<_CharT, _Intl>*>(__caches[__i]); 64*38fd1498Szrj } 65*38fd1498Szrj }; 66*38fd1498Szrj 67*38fd1498Szrj template<typename _CharT, bool _Intl> 68*38fd1498Szrj void _M_cache(const locale & __loc)69*38fd1498Szrj __moneypunct_cache<_CharT, _Intl>::_M_cache(const locale& __loc) 70*38fd1498Szrj { 71*38fd1498Szrj const moneypunct<_CharT, _Intl>& __mp = 72*38fd1498Szrj use_facet<moneypunct<_CharT, _Intl> >(__loc); 73*38fd1498Szrj 74*38fd1498Szrj _M_decimal_point = __mp.decimal_point(); 75*38fd1498Szrj _M_thousands_sep = __mp.thousands_sep(); 76*38fd1498Szrj _M_frac_digits = __mp.frac_digits(); 77*38fd1498Szrj 78*38fd1498Szrj char* __grouping = 0; 79*38fd1498Szrj _CharT* __curr_symbol = 0; 80*38fd1498Szrj _CharT* __positive_sign = 0; 81*38fd1498Szrj _CharT* __negative_sign = 0; 82*38fd1498Szrj __try 83*38fd1498Szrj { 84*38fd1498Szrj const string& __g = __mp.grouping(); 85*38fd1498Szrj _M_grouping_size = __g.size(); 86*38fd1498Szrj __grouping = new char[_M_grouping_size]; 87*38fd1498Szrj __g.copy(__grouping, _M_grouping_size); 88*38fd1498Szrj _M_use_grouping = (_M_grouping_size 89*38fd1498Szrj && static_cast<signed char>(__grouping[0]) > 0 90*38fd1498Szrj && (__grouping[0] 91*38fd1498Szrj != __gnu_cxx::__numeric_traits<char>::__max)); 92*38fd1498Szrj 93*38fd1498Szrj const basic_string<_CharT>& __cs = __mp.curr_symbol(); 94*38fd1498Szrj _M_curr_symbol_size = __cs.size(); 95*38fd1498Szrj __curr_symbol = new _CharT[_M_curr_symbol_size]; 96*38fd1498Szrj __cs.copy(__curr_symbol, _M_curr_symbol_size); 97*38fd1498Szrj 98*38fd1498Szrj const basic_string<_CharT>& __ps = __mp.positive_sign(); 99*38fd1498Szrj _M_positive_sign_size = __ps.size(); 100*38fd1498Szrj __positive_sign = new _CharT[_M_positive_sign_size]; 101*38fd1498Szrj __ps.copy(__positive_sign, _M_positive_sign_size); 102*38fd1498Szrj 103*38fd1498Szrj const basic_string<_CharT>& __ns = __mp.negative_sign(); 104*38fd1498Szrj _M_negative_sign_size = __ns.size(); 105*38fd1498Szrj __negative_sign = new _CharT[_M_negative_sign_size]; 106*38fd1498Szrj __ns.copy(__negative_sign, _M_negative_sign_size); 107*38fd1498Szrj 108*38fd1498Szrj _M_pos_format = __mp.pos_format(); 109*38fd1498Szrj _M_neg_format = __mp.neg_format(); 110*38fd1498Szrj 111*38fd1498Szrj const ctype<_CharT>& __ct = use_facet<ctype<_CharT> >(__loc); 112*38fd1498Szrj __ct.widen(money_base::_S_atoms, 113*38fd1498Szrj money_base::_S_atoms + money_base::_S_end, _M_atoms); 114*38fd1498Szrj 115*38fd1498Szrj _M_grouping = __grouping; 116*38fd1498Szrj _M_curr_symbol = __curr_symbol; 117*38fd1498Szrj _M_positive_sign = __positive_sign; 118*38fd1498Szrj _M_negative_sign = __negative_sign; 119*38fd1498Szrj _M_allocated = true; 120*38fd1498Szrj } 121*38fd1498Szrj __catch(...) 122*38fd1498Szrj { 123*38fd1498Szrj delete [] __grouping; 124*38fd1498Szrj delete [] __curr_symbol; 125*38fd1498Szrj delete [] __positive_sign; 126*38fd1498Szrj delete [] __negative_sign; 127*38fd1498Szrj __throw_exception_again; 128*38fd1498Szrj } 129*38fd1498Szrj } 130*38fd1498Szrj 131*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 132*38fd1498Szrj 133*38fd1498Szrj template<typename _CharT, typename _InIter> 134*38fd1498Szrj template<bool _Intl> 135*38fd1498Szrj _InIter 136*38fd1498Szrj money_get<_CharT, _InIter>:: _M_extract(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,string & __units) const137*38fd1498Szrj _M_extract(iter_type __beg, iter_type __end, ios_base& __io, 138*38fd1498Szrj ios_base::iostate& __err, string& __units) const 139*38fd1498Szrj { 140*38fd1498Szrj typedef char_traits<_CharT> __traits_type; 141*38fd1498Szrj typedef typename string_type::size_type size_type; 142*38fd1498Szrj typedef money_base::part part; 143*38fd1498Szrj typedef __moneypunct_cache<_CharT, _Intl> __cache_type; 144*38fd1498Szrj 145*38fd1498Szrj const locale& __loc = __io._M_getloc(); 146*38fd1498Szrj const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 147*38fd1498Szrj 148*38fd1498Szrj __use_cache<__cache_type> __uc; 149*38fd1498Szrj const __cache_type* __lc = __uc(__loc); 150*38fd1498Szrj const char_type* __lit = __lc->_M_atoms; 151*38fd1498Szrj 152*38fd1498Szrj // Deduced sign. 153*38fd1498Szrj bool __negative = false; 154*38fd1498Szrj // Sign size. 155*38fd1498Szrj size_type __sign_size = 0; 156*38fd1498Szrj // True if sign is mandatory. 157*38fd1498Szrj const bool __mandatory_sign = (__lc->_M_positive_sign_size 158*38fd1498Szrj && __lc->_M_negative_sign_size); 159*38fd1498Szrj // String of grouping info from thousands_sep plucked from __units. 160*38fd1498Szrj string __grouping_tmp; 161*38fd1498Szrj if (__lc->_M_use_grouping) 162*38fd1498Szrj __grouping_tmp.reserve(32); 163*38fd1498Szrj // Last position before the decimal point. 164*38fd1498Szrj int __last_pos = 0; 165*38fd1498Szrj // Separator positions, then, possibly, fractional digits. 166*38fd1498Szrj int __n = 0; 167*38fd1498Szrj // If input iterator is in a valid state. 168*38fd1498Szrj bool __testvalid = true; 169*38fd1498Szrj // Flag marking when a decimal point is found. 170*38fd1498Szrj bool __testdecfound = false; 171*38fd1498Szrj 172*38fd1498Szrj // The tentative returned string is stored here. 173*38fd1498Szrj string __res; 174*38fd1498Szrj __res.reserve(32); 175*38fd1498Szrj 176*38fd1498Szrj const char_type* __lit_zero = __lit + money_base::_S_zero; 177*38fd1498Szrj const money_base::pattern __p = __lc->_M_neg_format; 178*38fd1498Szrj for (int __i = 0; __i < 4 && __testvalid; ++__i) 179*38fd1498Szrj { 180*38fd1498Szrj const part __which = static_cast<part>(__p.field[__i]); 181*38fd1498Szrj switch (__which) 182*38fd1498Szrj { 183*38fd1498Szrj case money_base::symbol: 184*38fd1498Szrj // According to 22.2.6.1.2, p2, symbol is required 185*38fd1498Szrj // if (__io.flags() & ios_base::showbase), otherwise 186*38fd1498Szrj // is optional and consumed only if other characters 187*38fd1498Szrj // are needed to complete the format. 188*38fd1498Szrj if (__io.flags() & ios_base::showbase || __sign_size > 1 189*38fd1498Szrj || __i == 0 190*38fd1498Szrj || (__i == 1 && (__mandatory_sign 191*38fd1498Szrj || (static_cast<part>(__p.field[0]) 192*38fd1498Szrj == money_base::sign) 193*38fd1498Szrj || (static_cast<part>(__p.field[2]) 194*38fd1498Szrj == money_base::space))) 195*38fd1498Szrj || (__i == 2 && ((static_cast<part>(__p.field[3]) 196*38fd1498Szrj == money_base::value) 197*38fd1498Szrj || (__mandatory_sign 198*38fd1498Szrj && (static_cast<part>(__p.field[3]) 199*38fd1498Szrj == money_base::sign))))) 200*38fd1498Szrj { 201*38fd1498Szrj const size_type __len = __lc->_M_curr_symbol_size; 202*38fd1498Szrj size_type __j = 0; 203*38fd1498Szrj for (; __beg != __end && __j < __len 204*38fd1498Szrj && *__beg == __lc->_M_curr_symbol[__j]; 205*38fd1498Szrj ++__beg, (void)++__j); 206*38fd1498Szrj if (__j != __len 207*38fd1498Szrj && (__j || __io.flags() & ios_base::showbase)) 208*38fd1498Szrj __testvalid = false; 209*38fd1498Szrj } 210*38fd1498Szrj break; 211*38fd1498Szrj case money_base::sign: 212*38fd1498Szrj // Sign might not exist, or be more than one character long. 213*38fd1498Szrj if (__lc->_M_positive_sign_size && __beg != __end 214*38fd1498Szrj && *__beg == __lc->_M_positive_sign[0]) 215*38fd1498Szrj { 216*38fd1498Szrj __sign_size = __lc->_M_positive_sign_size; 217*38fd1498Szrj ++__beg; 218*38fd1498Szrj } 219*38fd1498Szrj else if (__lc->_M_negative_sign_size && __beg != __end 220*38fd1498Szrj && *__beg == __lc->_M_negative_sign[0]) 221*38fd1498Szrj { 222*38fd1498Szrj __negative = true; 223*38fd1498Szrj __sign_size = __lc->_M_negative_sign_size; 224*38fd1498Szrj ++__beg; 225*38fd1498Szrj } 226*38fd1498Szrj else if (__lc->_M_positive_sign_size 227*38fd1498Szrj && !__lc->_M_negative_sign_size) 228*38fd1498Szrj // "... if no sign is detected, the result is given the sign 229*38fd1498Szrj // that corresponds to the source of the empty string" 230*38fd1498Szrj __negative = true; 231*38fd1498Szrj else if (__mandatory_sign) 232*38fd1498Szrj __testvalid = false; 233*38fd1498Szrj break; 234*38fd1498Szrj case money_base::value: 235*38fd1498Szrj // Extract digits, remove and stash away the 236*38fd1498Szrj // grouping of found thousands separators. 237*38fd1498Szrj for (; __beg != __end; ++__beg) 238*38fd1498Szrj { 239*38fd1498Szrj const char_type __c = *__beg; 240*38fd1498Szrj const char_type* __q = __traits_type::find(__lit_zero, 241*38fd1498Szrj 10, __c); 242*38fd1498Szrj if (__q != 0) 243*38fd1498Szrj { 244*38fd1498Szrj __res += money_base::_S_atoms[__q - __lit]; 245*38fd1498Szrj ++__n; 246*38fd1498Szrj } 247*38fd1498Szrj else if (__c == __lc->_M_decimal_point 248*38fd1498Szrj && !__testdecfound) 249*38fd1498Szrj { 250*38fd1498Szrj if (__lc->_M_frac_digits <= 0) 251*38fd1498Szrj break; 252*38fd1498Szrj 253*38fd1498Szrj __last_pos = __n; 254*38fd1498Szrj __n = 0; 255*38fd1498Szrj __testdecfound = true; 256*38fd1498Szrj } 257*38fd1498Szrj else if (__lc->_M_use_grouping 258*38fd1498Szrj && __c == __lc->_M_thousands_sep 259*38fd1498Szrj && !__testdecfound) 260*38fd1498Szrj { 261*38fd1498Szrj if (__n) 262*38fd1498Szrj { 263*38fd1498Szrj // Mark position for later analysis. 264*38fd1498Szrj __grouping_tmp += static_cast<char>(__n); 265*38fd1498Szrj __n = 0; 266*38fd1498Szrj } 267*38fd1498Szrj else 268*38fd1498Szrj { 269*38fd1498Szrj __testvalid = false; 270*38fd1498Szrj break; 271*38fd1498Szrj } 272*38fd1498Szrj } 273*38fd1498Szrj else 274*38fd1498Szrj break; 275*38fd1498Szrj } 276*38fd1498Szrj if (__res.empty()) 277*38fd1498Szrj __testvalid = false; 278*38fd1498Szrj break; 279*38fd1498Szrj case money_base::space: 280*38fd1498Szrj // At least one space is required. 281*38fd1498Szrj if (__beg != __end && __ctype.is(ctype_base::space, *__beg)) 282*38fd1498Szrj ++__beg; 283*38fd1498Szrj else 284*38fd1498Szrj __testvalid = false; 285*38fd1498Szrj // fallthrough 286*38fd1498Szrj case money_base::none: 287*38fd1498Szrj // Only if not at the end of the pattern. 288*38fd1498Szrj if (__i != 3) 289*38fd1498Szrj for (; __beg != __end 290*38fd1498Szrj && __ctype.is(ctype_base::space, *__beg); ++__beg); 291*38fd1498Szrj break; 292*38fd1498Szrj } 293*38fd1498Szrj } 294*38fd1498Szrj 295*38fd1498Szrj // Need to get the rest of the sign characters, if they exist. 296*38fd1498Szrj if (__sign_size > 1 && __testvalid) 297*38fd1498Szrj { 298*38fd1498Szrj const char_type* __sign = __negative ? __lc->_M_negative_sign 299*38fd1498Szrj : __lc->_M_positive_sign; 300*38fd1498Szrj size_type __i = 1; 301*38fd1498Szrj for (; __beg != __end && __i < __sign_size 302*38fd1498Szrj && *__beg == __sign[__i]; ++__beg, (void)++__i); 303*38fd1498Szrj 304*38fd1498Szrj if (__i != __sign_size) 305*38fd1498Szrj __testvalid = false; 306*38fd1498Szrj } 307*38fd1498Szrj 308*38fd1498Szrj if (__testvalid) 309*38fd1498Szrj { 310*38fd1498Szrj // Strip leading zeros. 311*38fd1498Szrj if (__res.size() > 1) 312*38fd1498Szrj { 313*38fd1498Szrj const size_type __first = __res.find_first_not_of('0'); 314*38fd1498Szrj const bool __only_zeros = __first == string::npos; 315*38fd1498Szrj if (__first) 316*38fd1498Szrj __res.erase(0, __only_zeros ? __res.size() - 1 : __first); 317*38fd1498Szrj } 318*38fd1498Szrj 319*38fd1498Szrj // 22.2.6.1.2, p4 320*38fd1498Szrj if (__negative && __res[0] != '0') 321*38fd1498Szrj __res.insert(__res.begin(), '-'); 322*38fd1498Szrj 323*38fd1498Szrj // Test for grouping fidelity. 324*38fd1498Szrj if (__grouping_tmp.size()) 325*38fd1498Szrj { 326*38fd1498Szrj // Add the ending grouping. 327*38fd1498Szrj __grouping_tmp += static_cast<char>(__testdecfound ? __last_pos 328*38fd1498Szrj : __n); 329*38fd1498Szrj if (!std::__verify_grouping(__lc->_M_grouping, 330*38fd1498Szrj __lc->_M_grouping_size, 331*38fd1498Szrj __grouping_tmp)) 332*38fd1498Szrj __err |= ios_base::failbit; 333*38fd1498Szrj } 334*38fd1498Szrj 335*38fd1498Szrj // Iff not enough digits were supplied after the decimal-point. 336*38fd1498Szrj if (__testdecfound && __n != __lc->_M_frac_digits) 337*38fd1498Szrj __testvalid = false; 338*38fd1498Szrj } 339*38fd1498Szrj 340*38fd1498Szrj // Iff valid sequence is not recognized. 341*38fd1498Szrj if (!__testvalid) 342*38fd1498Szrj __err |= ios_base::failbit; 343*38fd1498Szrj else 344*38fd1498Szrj __units.swap(__res); 345*38fd1498Szrj 346*38fd1498Szrj // Iff no more characters are available. 347*38fd1498Szrj if (__beg == __end) 348*38fd1498Szrj __err |= ios_base::eofbit; 349*38fd1498Szrj return __beg; 350*38fd1498Szrj } 351*38fd1498Szrj 352*38fd1498Szrj #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ 353*38fd1498Szrj && _GLIBCXX_USE_CXX11_ABI == 0 354*38fd1498Szrj template<typename _CharT, typename _InIter> 355*38fd1498Szrj _InIter 356*38fd1498Szrj money_get<_CharT, _InIter>:: __do_get(iter_type __beg,iter_type __end,bool __intl,ios_base & __io,ios_base::iostate & __err,double & __units) const357*38fd1498Szrj __do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 358*38fd1498Szrj ios_base::iostate& __err, double& __units) const 359*38fd1498Szrj { 360*38fd1498Szrj string __str; 361*38fd1498Szrj __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str) 362*38fd1498Szrj : _M_extract<false>(__beg, __end, __io, __err, __str); 363*38fd1498Szrj std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); 364*38fd1498Szrj return __beg; 365*38fd1498Szrj } 366*38fd1498Szrj #endif 367*38fd1498Szrj 368*38fd1498Szrj template<typename _CharT, typename _InIter> 369*38fd1498Szrj _InIter 370*38fd1498Szrj money_get<_CharT, _InIter>:: do_get(iter_type __beg,iter_type __end,bool __intl,ios_base & __io,ios_base::iostate & __err,long double & __units) const371*38fd1498Szrj do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 372*38fd1498Szrj ios_base::iostate& __err, long double& __units) const 373*38fd1498Szrj { 374*38fd1498Szrj string __str; 375*38fd1498Szrj __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str) 376*38fd1498Szrj : _M_extract<false>(__beg, __end, __io, __err, __str); 377*38fd1498Szrj std::__convert_to_v(__str.c_str(), __units, __err, _S_get_c_locale()); 378*38fd1498Szrj return __beg; 379*38fd1498Szrj } 380*38fd1498Szrj 381*38fd1498Szrj template<typename _CharT, typename _InIter> 382*38fd1498Szrj _InIter 383*38fd1498Szrj money_get<_CharT, _InIter>:: do_get(iter_type __beg,iter_type __end,bool __intl,ios_base & __io,ios_base::iostate & __err,string_type & __digits) const384*38fd1498Szrj do_get(iter_type __beg, iter_type __end, bool __intl, ios_base& __io, 385*38fd1498Szrj ios_base::iostate& __err, string_type& __digits) const 386*38fd1498Szrj { 387*38fd1498Szrj typedef typename string::size_type size_type; 388*38fd1498Szrj 389*38fd1498Szrj const locale& __loc = __io._M_getloc(); 390*38fd1498Szrj const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 391*38fd1498Szrj 392*38fd1498Szrj string __str; 393*38fd1498Szrj __beg = __intl ? _M_extract<true>(__beg, __end, __io, __err, __str) 394*38fd1498Szrj : _M_extract<false>(__beg, __end, __io, __err, __str); 395*38fd1498Szrj const size_type __len = __str.size(); 396*38fd1498Szrj if (__len) 397*38fd1498Szrj { 398*38fd1498Szrj __digits.resize(__len); 399*38fd1498Szrj __ctype.widen(__str.data(), __str.data() + __len, &__digits[0]); 400*38fd1498Szrj } 401*38fd1498Szrj return __beg; 402*38fd1498Szrj } 403*38fd1498Szrj 404*38fd1498Szrj template<typename _CharT, typename _OutIter> 405*38fd1498Szrj template<bool _Intl> 406*38fd1498Szrj _OutIter 407*38fd1498Szrj money_put<_CharT, _OutIter>:: _M_insert(iter_type __s,ios_base & __io,char_type __fill,const string_type & __digits) const408*38fd1498Szrj _M_insert(iter_type __s, ios_base& __io, char_type __fill, 409*38fd1498Szrj const string_type& __digits) const 410*38fd1498Szrj { 411*38fd1498Szrj typedef typename string_type::size_type size_type; 412*38fd1498Szrj typedef money_base::part part; 413*38fd1498Szrj typedef __moneypunct_cache<_CharT, _Intl> __cache_type; 414*38fd1498Szrj 415*38fd1498Szrj const locale& __loc = __io._M_getloc(); 416*38fd1498Szrj const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 417*38fd1498Szrj 418*38fd1498Szrj __use_cache<__cache_type> __uc; 419*38fd1498Szrj const __cache_type* __lc = __uc(__loc); 420*38fd1498Szrj const char_type* __lit = __lc->_M_atoms; 421*38fd1498Szrj 422*38fd1498Szrj // Determine if negative or positive formats are to be used, and 423*38fd1498Szrj // discard leading negative_sign if it is present. 424*38fd1498Szrj const char_type* __beg = __digits.data(); 425*38fd1498Szrj 426*38fd1498Szrj money_base::pattern __p; 427*38fd1498Szrj const char_type* __sign; 428*38fd1498Szrj size_type __sign_size; 429*38fd1498Szrj if (!(*__beg == __lit[money_base::_S_minus])) 430*38fd1498Szrj { 431*38fd1498Szrj __p = __lc->_M_pos_format; 432*38fd1498Szrj __sign = __lc->_M_positive_sign; 433*38fd1498Szrj __sign_size = __lc->_M_positive_sign_size; 434*38fd1498Szrj } 435*38fd1498Szrj else 436*38fd1498Szrj { 437*38fd1498Szrj __p = __lc->_M_neg_format; 438*38fd1498Szrj __sign = __lc->_M_negative_sign; 439*38fd1498Szrj __sign_size = __lc->_M_negative_sign_size; 440*38fd1498Szrj if (__digits.size()) 441*38fd1498Szrj ++__beg; 442*38fd1498Szrj } 443*38fd1498Szrj 444*38fd1498Szrj // Look for valid numbers in the ctype facet within input digits. 445*38fd1498Szrj size_type __len = __ctype.scan_not(ctype_base::digit, __beg, 446*38fd1498Szrj __beg + __digits.size()) - __beg; 447*38fd1498Szrj if (__len) 448*38fd1498Szrj { 449*38fd1498Szrj // Assume valid input, and attempt to format. 450*38fd1498Szrj // Break down input numbers into base components, as follows: 451*38fd1498Szrj // final_value = grouped units + (decimal point) + (digits) 452*38fd1498Szrj string_type __value; 453*38fd1498Szrj __value.reserve(2 * __len); 454*38fd1498Szrj 455*38fd1498Szrj // Add thousands separators to non-decimal digits, per 456*38fd1498Szrj // grouping rules. 457*38fd1498Szrj long __paddec = __len - __lc->_M_frac_digits; 458*38fd1498Szrj if (__paddec > 0) 459*38fd1498Szrj { 460*38fd1498Szrj if (__lc->_M_frac_digits < 0) 461*38fd1498Szrj __paddec = __len; 462*38fd1498Szrj if (__lc->_M_grouping_size) 463*38fd1498Szrj { 464*38fd1498Szrj __value.assign(2 * __paddec, char_type()); 465*38fd1498Szrj _CharT* __vend = 466*38fd1498Szrj std::__add_grouping(&__value[0], __lc->_M_thousands_sep, 467*38fd1498Szrj __lc->_M_grouping, 468*38fd1498Szrj __lc->_M_grouping_size, 469*38fd1498Szrj __beg, __beg + __paddec); 470*38fd1498Szrj __value.erase(__vend - &__value[0]); 471*38fd1498Szrj } 472*38fd1498Szrj else 473*38fd1498Szrj __value.assign(__beg, __paddec); 474*38fd1498Szrj } 475*38fd1498Szrj 476*38fd1498Szrj // Deal with decimal point, decimal digits. 477*38fd1498Szrj if (__lc->_M_frac_digits > 0) 478*38fd1498Szrj { 479*38fd1498Szrj __value += __lc->_M_decimal_point; 480*38fd1498Szrj if (__paddec >= 0) 481*38fd1498Szrj __value.append(__beg + __paddec, __lc->_M_frac_digits); 482*38fd1498Szrj else 483*38fd1498Szrj { 484*38fd1498Szrj // Have to pad zeros in the decimal position. 485*38fd1498Szrj __value.append(-__paddec, __lit[money_base::_S_zero]); 486*38fd1498Szrj __value.append(__beg, __len); 487*38fd1498Szrj } 488*38fd1498Szrj } 489*38fd1498Szrj 490*38fd1498Szrj // Calculate length of resulting string. 491*38fd1498Szrj const ios_base::fmtflags __f = __io.flags() 492*38fd1498Szrj & ios_base::adjustfield; 493*38fd1498Szrj __len = __value.size() + __sign_size; 494*38fd1498Szrj __len += ((__io.flags() & ios_base::showbase) 495*38fd1498Szrj ? __lc->_M_curr_symbol_size : 0); 496*38fd1498Szrj 497*38fd1498Szrj string_type __res; 498*38fd1498Szrj __res.reserve(2 * __len); 499*38fd1498Szrj 500*38fd1498Szrj const size_type __width = static_cast<size_type>(__io.width()); 501*38fd1498Szrj const bool __testipad = (__f == ios_base::internal 502*38fd1498Szrj && __len < __width); 503*38fd1498Szrj // Fit formatted digits into the required pattern. 504*38fd1498Szrj for (int __i = 0; __i < 4; ++__i) 505*38fd1498Szrj { 506*38fd1498Szrj const part __which = static_cast<part>(__p.field[__i]); 507*38fd1498Szrj switch (__which) 508*38fd1498Szrj { 509*38fd1498Szrj case money_base::symbol: 510*38fd1498Szrj if (__io.flags() & ios_base::showbase) 511*38fd1498Szrj __res.append(__lc->_M_curr_symbol, 512*38fd1498Szrj __lc->_M_curr_symbol_size); 513*38fd1498Szrj break; 514*38fd1498Szrj case money_base::sign: 515*38fd1498Szrj // Sign might not exist, or be more than one 516*38fd1498Szrj // character long. In that case, add in the rest 517*38fd1498Szrj // below. 518*38fd1498Szrj if (__sign_size) 519*38fd1498Szrj __res += __sign[0]; 520*38fd1498Szrj break; 521*38fd1498Szrj case money_base::value: 522*38fd1498Szrj __res += __value; 523*38fd1498Szrj break; 524*38fd1498Szrj case money_base::space: 525*38fd1498Szrj // At least one space is required, but if internal 526*38fd1498Szrj // formatting is required, an arbitrary number of 527*38fd1498Szrj // fill spaces will be necessary. 528*38fd1498Szrj if (__testipad) 529*38fd1498Szrj __res.append(__width - __len, __fill); 530*38fd1498Szrj else 531*38fd1498Szrj __res += __fill; 532*38fd1498Szrj break; 533*38fd1498Szrj case money_base::none: 534*38fd1498Szrj if (__testipad) 535*38fd1498Szrj __res.append(__width - __len, __fill); 536*38fd1498Szrj break; 537*38fd1498Szrj } 538*38fd1498Szrj } 539*38fd1498Szrj 540*38fd1498Szrj // Special case of multi-part sign parts. 541*38fd1498Szrj if (__sign_size > 1) 542*38fd1498Szrj __res.append(__sign + 1, __sign_size - 1); 543*38fd1498Szrj 544*38fd1498Szrj // Pad, if still necessary. 545*38fd1498Szrj __len = __res.size(); 546*38fd1498Szrj if (__width > __len) 547*38fd1498Szrj { 548*38fd1498Szrj if (__f == ios_base::left) 549*38fd1498Szrj // After. 550*38fd1498Szrj __res.append(__width - __len, __fill); 551*38fd1498Szrj else 552*38fd1498Szrj // Before. 553*38fd1498Szrj __res.insert(0, __width - __len, __fill); 554*38fd1498Szrj __len = __width; 555*38fd1498Szrj } 556*38fd1498Szrj 557*38fd1498Szrj // Write resulting, fully-formatted string to output iterator. 558*38fd1498Szrj __s = std::__write(__s, __res.data(), __len); 559*38fd1498Szrj } 560*38fd1498Szrj __io.width(0); 561*38fd1498Szrj return __s; 562*38fd1498Szrj } 563*38fd1498Szrj 564*38fd1498Szrj #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ \ 565*38fd1498Szrj && _GLIBCXX_USE_CXX11_ABI == 0 566*38fd1498Szrj template<typename _CharT, typename _OutIter> 567*38fd1498Szrj _OutIter 568*38fd1498Szrj money_put<_CharT, _OutIter>:: __do_put(iter_type __s,bool __intl,ios_base & __io,char_type __fill,double __units) const569*38fd1498Szrj __do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 570*38fd1498Szrj double __units) const 571*38fd1498Szrj { return this->do_put(__s, __intl, __io, __fill, (long double) __units); } 572*38fd1498Szrj #endif 573*38fd1498Szrj 574*38fd1498Szrj template<typename _CharT, typename _OutIter> 575*38fd1498Szrj _OutIter 576*38fd1498Szrj money_put<_CharT, _OutIter>:: do_put(iter_type __s,bool __intl,ios_base & __io,char_type __fill,long double __units) const577*38fd1498Szrj do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 578*38fd1498Szrj long double __units) const 579*38fd1498Szrj { 580*38fd1498Szrj const locale __loc = __io.getloc(); 581*38fd1498Szrj const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 582*38fd1498Szrj #if _GLIBCXX_USE_C99_STDIO 583*38fd1498Szrj // First try a buffer perhaps big enough. 584*38fd1498Szrj int __cs_size = 64; 585*38fd1498Szrj char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 586*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 587*38fd1498Szrj // 328. Bad sprintf format modifier in money_put<>::do_put() 588*38fd1498Szrj int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, 589*38fd1498Szrj "%.*Lf", 0, __units); 590*38fd1498Szrj // If the buffer was not large enough, try again with the correct size. 591*38fd1498Szrj if (__len >= __cs_size) 592*38fd1498Szrj { 593*38fd1498Szrj __cs_size = __len + 1; 594*38fd1498Szrj __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 595*38fd1498Szrj __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, 596*38fd1498Szrj "%.*Lf", 0, __units); 597*38fd1498Szrj } 598*38fd1498Szrj #else 599*38fd1498Szrj // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. 600*38fd1498Szrj const int __cs_size = 601*38fd1498Szrj __gnu_cxx::__numeric_traits<long double>::__max_exponent10 + 3; 602*38fd1498Szrj char* __cs = static_cast<char*>(__builtin_alloca(__cs_size)); 603*38fd1498Szrj int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf", 604*38fd1498Szrj 0, __units); 605*38fd1498Szrj #endif 606*38fd1498Szrj string_type __digits(__len, char_type()); 607*38fd1498Szrj __ctype.widen(__cs, __cs + __len, &__digits[0]); 608*38fd1498Szrj return __intl ? _M_insert<true>(__s, __io, __fill, __digits) 609*38fd1498Szrj : _M_insert<false>(__s, __io, __fill, __digits); 610*38fd1498Szrj } 611*38fd1498Szrj 612*38fd1498Szrj template<typename _CharT, typename _OutIter> 613*38fd1498Szrj _OutIter 614*38fd1498Szrj money_put<_CharT, _OutIter>:: do_put(iter_type __s,bool __intl,ios_base & __io,char_type __fill,const string_type & __digits) const615*38fd1498Szrj do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill, 616*38fd1498Szrj const string_type& __digits) const 617*38fd1498Szrj { return __intl ? _M_insert<true>(__s, __io, __fill, __digits) 618*38fd1498Szrj : _M_insert<false>(__s, __io, __fill, __digits); } 619*38fd1498Szrj 620*38fd1498Szrj _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11 621*38fd1498Szrj 622*38fd1498Szrj // NB: Not especially useful. Without an ios_base object or some 623*38fd1498Szrj // kind of locale reference, we are left clawing at the air where 624*38fd1498Szrj // the side of the mountain used to be... 625*38fd1498Szrj template<typename _CharT, typename _InIter> 626*38fd1498Szrj time_base::dateorder do_date_order() const627*38fd1498Szrj time_get<_CharT, _InIter>::do_date_order() const 628*38fd1498Szrj { return time_base::no_order; } 629*38fd1498Szrj 630*38fd1498Szrj // Expand a strftime format string and parse it. E.g., do_get_date() may 631*38fd1498Szrj // pass %m/%d/%Y => extracted characters. 632*38fd1498Szrj template<typename _CharT, typename _InIter> 633*38fd1498Szrj _InIter 634*38fd1498Szrj time_get<_CharT, _InIter>:: _M_extract_via_format(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,tm * __tm,const _CharT * __format) const635*38fd1498Szrj _M_extract_via_format(iter_type __beg, iter_type __end, ios_base& __io, 636*38fd1498Szrj ios_base::iostate& __err, tm* __tm, 637*38fd1498Szrj const _CharT* __format) const 638*38fd1498Szrj { 639*38fd1498Szrj const locale& __loc = __io._M_getloc(); 640*38fd1498Szrj const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 641*38fd1498Szrj const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 642*38fd1498Szrj const size_t __len = char_traits<_CharT>::length(__format); 643*38fd1498Szrj 644*38fd1498Szrj ios_base::iostate __tmperr = ios_base::goodbit; 645*38fd1498Szrj size_t __i = 0; 646*38fd1498Szrj for (; __beg != __end && __i < __len && !__tmperr; ++__i) 647*38fd1498Szrj { 648*38fd1498Szrj if (__ctype.narrow(__format[__i], 0) == '%') 649*38fd1498Szrj { 650*38fd1498Szrj // Verify valid formatting code, attempt to extract. 651*38fd1498Szrj char __c = __ctype.narrow(__format[++__i], 0); 652*38fd1498Szrj int __mem = 0; 653*38fd1498Szrj if (__c == 'E' || __c == 'O') 654*38fd1498Szrj __c = __ctype.narrow(__format[++__i], 0); 655*38fd1498Szrj switch (__c) 656*38fd1498Szrj { 657*38fd1498Szrj const char* __cs; 658*38fd1498Szrj _CharT __wcs[10]; 659*38fd1498Szrj case 'a': 660*38fd1498Szrj // Abbreviated weekday name [tm_wday] 661*38fd1498Szrj const char_type* __days1[7]; 662*38fd1498Szrj __tp._M_days_abbreviated(__days1); 663*38fd1498Szrj __beg = _M_extract_name(__beg, __end, __mem, __days1, 664*38fd1498Szrj 7, __io, __tmperr); 665*38fd1498Szrj if (!__tmperr) 666*38fd1498Szrj __tm->tm_wday = __mem; 667*38fd1498Szrj break; 668*38fd1498Szrj case 'A': 669*38fd1498Szrj // Weekday name [tm_wday]. 670*38fd1498Szrj const char_type* __days2[7]; 671*38fd1498Szrj __tp._M_days(__days2); 672*38fd1498Szrj __beg = _M_extract_name(__beg, __end, __mem, __days2, 673*38fd1498Szrj 7, __io, __tmperr); 674*38fd1498Szrj if (!__tmperr) 675*38fd1498Szrj __tm->tm_wday = __mem; 676*38fd1498Szrj break; 677*38fd1498Szrj case 'h': 678*38fd1498Szrj case 'b': 679*38fd1498Szrj // Abbreviated month name [tm_mon] 680*38fd1498Szrj const char_type* __months1[12]; 681*38fd1498Szrj __tp._M_months_abbreviated(__months1); 682*38fd1498Szrj __beg = _M_extract_name(__beg, __end, __mem, 683*38fd1498Szrj __months1, 12, __io, __tmperr); 684*38fd1498Szrj if (!__tmperr) 685*38fd1498Szrj __tm->tm_mon = __mem; 686*38fd1498Szrj break; 687*38fd1498Szrj case 'B': 688*38fd1498Szrj // Month name [tm_mon]. 689*38fd1498Szrj const char_type* __months2[12]; 690*38fd1498Szrj __tp._M_months(__months2); 691*38fd1498Szrj __beg = _M_extract_name(__beg, __end, __mem, 692*38fd1498Szrj __months2, 12, __io, __tmperr); 693*38fd1498Szrj if (!__tmperr) 694*38fd1498Szrj __tm->tm_mon = __mem; 695*38fd1498Szrj break; 696*38fd1498Szrj case 'c': 697*38fd1498Szrj // Default time and date representation. 698*38fd1498Szrj const char_type* __dt[2]; 699*38fd1498Szrj __tp._M_date_time_formats(__dt); 700*38fd1498Szrj __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 701*38fd1498Szrj __tm, __dt[0]); 702*38fd1498Szrj break; 703*38fd1498Szrj case 'd': 704*38fd1498Szrj // Day [01, 31]. [tm_mday] 705*38fd1498Szrj __beg = _M_extract_num(__beg, __end, __mem, 1, 31, 2, 706*38fd1498Szrj __io, __tmperr); 707*38fd1498Szrj if (!__tmperr) 708*38fd1498Szrj __tm->tm_mday = __mem; 709*38fd1498Szrj break; 710*38fd1498Szrj case 'e': 711*38fd1498Szrj // Day [1, 31], with single digits preceded by 712*38fd1498Szrj // space. [tm_mday] 713*38fd1498Szrj if (__ctype.is(ctype_base::space, *__beg)) 714*38fd1498Szrj __beg = _M_extract_num(++__beg, __end, __mem, 1, 9, 715*38fd1498Szrj 1, __io, __tmperr); 716*38fd1498Szrj else 717*38fd1498Szrj __beg = _M_extract_num(__beg, __end, __mem, 10, 31, 718*38fd1498Szrj 2, __io, __tmperr); 719*38fd1498Szrj if (!__tmperr) 720*38fd1498Szrj __tm->tm_mday = __mem; 721*38fd1498Szrj break; 722*38fd1498Szrj case 'D': 723*38fd1498Szrj // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] 724*38fd1498Szrj __cs = "%m/%d/%y"; 725*38fd1498Szrj __ctype.widen(__cs, __cs + 9, __wcs); 726*38fd1498Szrj __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 727*38fd1498Szrj __tm, __wcs); 728*38fd1498Szrj break; 729*38fd1498Szrj case 'H': 730*38fd1498Szrj // Hour [00, 23]. [tm_hour] 731*38fd1498Szrj __beg = _M_extract_num(__beg, __end, __mem, 0, 23, 2, 732*38fd1498Szrj __io, __tmperr); 733*38fd1498Szrj if (!__tmperr) 734*38fd1498Szrj __tm->tm_hour = __mem; 735*38fd1498Szrj break; 736*38fd1498Szrj case 'I': 737*38fd1498Szrj // Hour [01, 12]. [tm_hour] 738*38fd1498Szrj __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, 739*38fd1498Szrj __io, __tmperr); 740*38fd1498Szrj if (!__tmperr) 741*38fd1498Szrj __tm->tm_hour = __mem; 742*38fd1498Szrj break; 743*38fd1498Szrj case 'm': 744*38fd1498Szrj // Month [01, 12]. [tm_mon] 745*38fd1498Szrj __beg = _M_extract_num(__beg, __end, __mem, 1, 12, 2, 746*38fd1498Szrj __io, __tmperr); 747*38fd1498Szrj if (!__tmperr) 748*38fd1498Szrj __tm->tm_mon = __mem - 1; 749*38fd1498Szrj break; 750*38fd1498Szrj case 'M': 751*38fd1498Szrj // Minute [00, 59]. [tm_min] 752*38fd1498Szrj __beg = _M_extract_num(__beg, __end, __mem, 0, 59, 2, 753*38fd1498Szrj __io, __tmperr); 754*38fd1498Szrj if (!__tmperr) 755*38fd1498Szrj __tm->tm_min = __mem; 756*38fd1498Szrj break; 757*38fd1498Szrj case 'n': 758*38fd1498Szrj if (__ctype.narrow(*__beg, 0) == '\n') 759*38fd1498Szrj ++__beg; 760*38fd1498Szrj else 761*38fd1498Szrj __tmperr |= ios_base::failbit; 762*38fd1498Szrj break; 763*38fd1498Szrj case 'R': 764*38fd1498Szrj // Equivalent to (%H:%M). 765*38fd1498Szrj __cs = "%H:%M"; 766*38fd1498Szrj __ctype.widen(__cs, __cs + 6, __wcs); 767*38fd1498Szrj __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 768*38fd1498Szrj __tm, __wcs); 769*38fd1498Szrj break; 770*38fd1498Szrj case 'S': 771*38fd1498Szrj // Seconds. [tm_sec] 772*38fd1498Szrj // [00, 60] in C99 (one leap-second), [00, 61] in C89. 773*38fd1498Szrj #if _GLIBCXX_USE_C99 774*38fd1498Szrj __beg = _M_extract_num(__beg, __end, __mem, 0, 60, 2, 775*38fd1498Szrj #else 776*38fd1498Szrj __beg = _M_extract_num(__beg, __end, __mem, 0, 61, 2, 777*38fd1498Szrj #endif 778*38fd1498Szrj __io, __tmperr); 779*38fd1498Szrj if (!__tmperr) 780*38fd1498Szrj __tm->tm_sec = __mem; 781*38fd1498Szrj break; 782*38fd1498Szrj case 't': 783*38fd1498Szrj if (__ctype.narrow(*__beg, 0) == '\t') 784*38fd1498Szrj ++__beg; 785*38fd1498Szrj else 786*38fd1498Szrj __tmperr |= ios_base::failbit; 787*38fd1498Szrj break; 788*38fd1498Szrj case 'T': 789*38fd1498Szrj // Equivalent to (%H:%M:%S). 790*38fd1498Szrj __cs = "%H:%M:%S"; 791*38fd1498Szrj __ctype.widen(__cs, __cs + 9, __wcs); 792*38fd1498Szrj __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 793*38fd1498Szrj __tm, __wcs); 794*38fd1498Szrj break; 795*38fd1498Szrj case 'x': 796*38fd1498Szrj // Locale's date. 797*38fd1498Szrj const char_type* __dates[2]; 798*38fd1498Szrj __tp._M_date_formats(__dates); 799*38fd1498Szrj __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 800*38fd1498Szrj __tm, __dates[0]); 801*38fd1498Szrj break; 802*38fd1498Szrj case 'X': 803*38fd1498Szrj // Locale's time. 804*38fd1498Szrj const char_type* __times[2]; 805*38fd1498Szrj __tp._M_time_formats(__times); 806*38fd1498Szrj __beg = _M_extract_via_format(__beg, __end, __io, __tmperr, 807*38fd1498Szrj __tm, __times[0]); 808*38fd1498Szrj break; 809*38fd1498Szrj case 'y': 810*38fd1498Szrj case 'C': // C99 811*38fd1498Szrj // Two digit year. 812*38fd1498Szrj case 'Y': 813*38fd1498Szrj // Year [1900). 814*38fd1498Szrj // NB: We parse either two digits, implicitly years since 815*38fd1498Szrj // 1900, or 4 digits, full year. In both cases we can 816*38fd1498Szrj // reconstruct [tm_year]. See also libstdc++/26701. 817*38fd1498Szrj __beg = _M_extract_num(__beg, __end, __mem, 0, 9999, 4, 818*38fd1498Szrj __io, __tmperr); 819*38fd1498Szrj if (!__tmperr) 820*38fd1498Szrj __tm->tm_year = __mem < 0 ? __mem + 100 : __mem - 1900; 821*38fd1498Szrj break; 822*38fd1498Szrj case 'Z': 823*38fd1498Szrj // Timezone info. 824*38fd1498Szrj if (__ctype.is(ctype_base::upper, *__beg)) 825*38fd1498Szrj { 826*38fd1498Szrj int __tmp; 827*38fd1498Szrj __beg = _M_extract_name(__beg, __end, __tmp, 828*38fd1498Szrj __timepunct_cache<_CharT>::_S_timezones, 829*38fd1498Szrj 14, __io, __tmperr); 830*38fd1498Szrj 831*38fd1498Szrj // GMT requires special effort. 832*38fd1498Szrj if (__beg != __end && !__tmperr && __tmp == 0 833*38fd1498Szrj && (*__beg == __ctype.widen('-') 834*38fd1498Szrj || *__beg == __ctype.widen('+'))) 835*38fd1498Szrj { 836*38fd1498Szrj __beg = _M_extract_num(__beg, __end, __tmp, 0, 23, 2, 837*38fd1498Szrj __io, __tmperr); 838*38fd1498Szrj __beg = _M_extract_num(__beg, __end, __tmp, 0, 59, 2, 839*38fd1498Szrj __io, __tmperr); 840*38fd1498Szrj } 841*38fd1498Szrj } 842*38fd1498Szrj else 843*38fd1498Szrj __tmperr |= ios_base::failbit; 844*38fd1498Szrj break; 845*38fd1498Szrj default: 846*38fd1498Szrj // Not recognized. 847*38fd1498Szrj __tmperr |= ios_base::failbit; 848*38fd1498Szrj } 849*38fd1498Szrj } 850*38fd1498Szrj else 851*38fd1498Szrj { 852*38fd1498Szrj // Verify format and input match, extract and discard. 853*38fd1498Szrj if (__format[__i] == *__beg) 854*38fd1498Szrj ++__beg; 855*38fd1498Szrj else 856*38fd1498Szrj __tmperr |= ios_base::failbit; 857*38fd1498Szrj } 858*38fd1498Szrj } 859*38fd1498Szrj 860*38fd1498Szrj if (__tmperr || __i != __len) 861*38fd1498Szrj __err |= ios_base::failbit; 862*38fd1498Szrj 863*38fd1498Szrj return __beg; 864*38fd1498Szrj } 865*38fd1498Szrj 866*38fd1498Szrj template<typename _CharT, typename _InIter> 867*38fd1498Szrj _InIter 868*38fd1498Szrj time_get<_CharT, _InIter>:: _M_extract_num(iter_type __beg,iter_type __end,int & __member,int __min,int __max,size_t __len,ios_base & __io,ios_base::iostate & __err) const869*38fd1498Szrj _M_extract_num(iter_type __beg, iter_type __end, int& __member, 870*38fd1498Szrj int __min, int __max, size_t __len, 871*38fd1498Szrj ios_base& __io, ios_base::iostate& __err) const 872*38fd1498Szrj { 873*38fd1498Szrj const locale& __loc = __io._M_getloc(); 874*38fd1498Szrj const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 875*38fd1498Szrj 876*38fd1498Szrj // As-is works for __len = 1, 2, 4, the values actually used. 877*38fd1498Szrj int __mult = __len == 2 ? 10 : (__len == 4 ? 1000 : 1); 878*38fd1498Szrj 879*38fd1498Szrj ++__min; 880*38fd1498Szrj size_t __i = 0; 881*38fd1498Szrj int __value = 0; 882*38fd1498Szrj for (; __beg != __end && __i < __len; ++__beg, (void)++__i) 883*38fd1498Szrj { 884*38fd1498Szrj const char __c = __ctype.narrow(*__beg, '*'); 885*38fd1498Szrj if (__c >= '0' && __c <= '9') 886*38fd1498Szrj { 887*38fd1498Szrj __value = __value * 10 + (__c - '0'); 888*38fd1498Szrj const int __valuec = __value * __mult; 889*38fd1498Szrj if (__valuec > __max || __valuec + __mult < __min) 890*38fd1498Szrj break; 891*38fd1498Szrj __mult /= 10; 892*38fd1498Szrj } 893*38fd1498Szrj else 894*38fd1498Szrj break; 895*38fd1498Szrj } 896*38fd1498Szrj if (__i == __len) 897*38fd1498Szrj __member = __value; 898*38fd1498Szrj // Special encoding for do_get_year, 'y', and 'Y' above. 899*38fd1498Szrj else if (__len == 4 && __i == 2) 900*38fd1498Szrj __member = __value - 100; 901*38fd1498Szrj else 902*38fd1498Szrj __err |= ios_base::failbit; 903*38fd1498Szrj 904*38fd1498Szrj return __beg; 905*38fd1498Szrj } 906*38fd1498Szrj 907*38fd1498Szrj // Assumptions: 908*38fd1498Szrj // All elements in __names are unique. 909*38fd1498Szrj template<typename _CharT, typename _InIter> 910*38fd1498Szrj _InIter 911*38fd1498Szrj time_get<_CharT, _InIter>:: _M_extract_name(iter_type __beg,iter_type __end,int & __member,const _CharT ** __names,size_t __indexlen,ios_base & __io,ios_base::iostate & __err) const912*38fd1498Szrj _M_extract_name(iter_type __beg, iter_type __end, int& __member, 913*38fd1498Szrj const _CharT** __names, size_t __indexlen, 914*38fd1498Szrj ios_base& __io, ios_base::iostate& __err) const 915*38fd1498Szrj { 916*38fd1498Szrj typedef char_traits<_CharT> __traits_type; 917*38fd1498Szrj const locale& __loc = __io._M_getloc(); 918*38fd1498Szrj const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 919*38fd1498Szrj 920*38fd1498Szrj int* __matches = static_cast<int*>(__builtin_alloca(sizeof(int) 921*38fd1498Szrj * __indexlen)); 922*38fd1498Szrj size_t __nmatches = 0; 923*38fd1498Szrj size_t __pos = 0; 924*38fd1498Szrj bool __testvalid = true; 925*38fd1498Szrj const char_type* __name; 926*38fd1498Szrj 927*38fd1498Szrj // Look for initial matches. 928*38fd1498Szrj // NB: Some of the locale data is in the form of all lowercase 929*38fd1498Szrj // names, and some is in the form of initially-capitalized 930*38fd1498Szrj // names. Look for both. 931*38fd1498Szrj if (__beg != __end) 932*38fd1498Szrj { 933*38fd1498Szrj const char_type __c = *__beg; 934*38fd1498Szrj for (size_t __i1 = 0; __i1 < __indexlen; ++__i1) 935*38fd1498Szrj if (__c == __names[__i1][0] 936*38fd1498Szrj || __c == __ctype.toupper(__names[__i1][0])) 937*38fd1498Szrj __matches[__nmatches++] = __i1; 938*38fd1498Szrj } 939*38fd1498Szrj 940*38fd1498Szrj while (__nmatches > 1) 941*38fd1498Szrj { 942*38fd1498Szrj // Find smallest matching string. 943*38fd1498Szrj size_t __minlen = __traits_type::length(__names[__matches[0]]); 944*38fd1498Szrj for (size_t __i2 = 1; __i2 < __nmatches; ++__i2) 945*38fd1498Szrj __minlen = std::min(__minlen, 946*38fd1498Szrj __traits_type::length(__names[__matches[__i2]])); 947*38fd1498Szrj ++__beg; 948*38fd1498Szrj ++__pos; 949*38fd1498Szrj if (__pos < __minlen && __beg != __end) 950*38fd1498Szrj for (size_t __i3 = 0; __i3 < __nmatches;) 951*38fd1498Szrj { 952*38fd1498Szrj __name = __names[__matches[__i3]]; 953*38fd1498Szrj if (!(__name[__pos] == *__beg)) 954*38fd1498Szrj __matches[__i3] = __matches[--__nmatches]; 955*38fd1498Szrj else 956*38fd1498Szrj ++__i3; 957*38fd1498Szrj } 958*38fd1498Szrj else 959*38fd1498Szrj break; 960*38fd1498Szrj } 961*38fd1498Szrj 962*38fd1498Szrj if (__nmatches == 1) 963*38fd1498Szrj { 964*38fd1498Szrj // Make sure found name is completely extracted. 965*38fd1498Szrj ++__beg; 966*38fd1498Szrj ++__pos; 967*38fd1498Szrj __name = __names[__matches[0]]; 968*38fd1498Szrj const size_t __len = __traits_type::length(__name); 969*38fd1498Szrj while (__pos < __len && __beg != __end && __name[__pos] == *__beg) 970*38fd1498Szrj ++__beg, (void)++__pos; 971*38fd1498Szrj 972*38fd1498Szrj if (__len == __pos) 973*38fd1498Szrj __member = __matches[0]; 974*38fd1498Szrj else 975*38fd1498Szrj __testvalid = false; 976*38fd1498Szrj } 977*38fd1498Szrj else 978*38fd1498Szrj __testvalid = false; 979*38fd1498Szrj if (!__testvalid) 980*38fd1498Szrj __err |= ios_base::failbit; 981*38fd1498Szrj 982*38fd1498Szrj return __beg; 983*38fd1498Szrj } 984*38fd1498Szrj 985*38fd1498Szrj template<typename _CharT, typename _InIter> 986*38fd1498Szrj _InIter 987*38fd1498Szrj time_get<_CharT, _InIter>:: _M_extract_wday_or_month(iter_type __beg,iter_type __end,int & __member,const _CharT ** __names,size_t __indexlen,ios_base & __io,ios_base::iostate & __err) const988*38fd1498Szrj _M_extract_wday_or_month(iter_type __beg, iter_type __end, int& __member, 989*38fd1498Szrj const _CharT** __names, size_t __indexlen, 990*38fd1498Szrj ios_base& __io, ios_base::iostate& __err) const 991*38fd1498Szrj { 992*38fd1498Szrj typedef char_traits<_CharT> __traits_type; 993*38fd1498Szrj const locale& __loc = __io._M_getloc(); 994*38fd1498Szrj const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); 995*38fd1498Szrj 996*38fd1498Szrj int* __matches = static_cast<int*>(__builtin_alloca(2 * sizeof(int) 997*38fd1498Szrj * __indexlen)); 998*38fd1498Szrj size_t __nmatches = 0; 999*38fd1498Szrj size_t* __matches_lengths = 0; 1000*38fd1498Szrj size_t __pos = 0; 1001*38fd1498Szrj 1002*38fd1498Szrj if (__beg != __end) 1003*38fd1498Szrj { 1004*38fd1498Szrj const char_type __c = *__beg; 1005*38fd1498Szrj for (size_t __i = 0; __i < 2 * __indexlen; ++__i) 1006*38fd1498Szrj if (__c == __names[__i][0] 1007*38fd1498Szrj || __c == __ctype.toupper(__names[__i][0])) 1008*38fd1498Szrj __matches[__nmatches++] = __i; 1009*38fd1498Szrj } 1010*38fd1498Szrj 1011*38fd1498Szrj if (__nmatches) 1012*38fd1498Szrj { 1013*38fd1498Szrj ++__beg; 1014*38fd1498Szrj ++__pos; 1015*38fd1498Szrj 1016*38fd1498Szrj __matches_lengths 1017*38fd1498Szrj = static_cast<size_t*>(__builtin_alloca(sizeof(size_t) 1018*38fd1498Szrj * __nmatches)); 1019*38fd1498Szrj for (size_t __i = 0; __i < __nmatches; ++__i) 1020*38fd1498Szrj __matches_lengths[__i] 1021*38fd1498Szrj = __traits_type::length(__names[__matches[__i]]); 1022*38fd1498Szrj } 1023*38fd1498Szrj 1024*38fd1498Szrj for (; __beg != __end; ++__beg, (void)++__pos) 1025*38fd1498Szrj { 1026*38fd1498Szrj size_t __nskipped = 0; 1027*38fd1498Szrj const char_type __c = *__beg; 1028*38fd1498Szrj for (size_t __i = 0; __i < __nmatches;) 1029*38fd1498Szrj { 1030*38fd1498Szrj const char_type* __name = __names[__matches[__i]]; 1031*38fd1498Szrj if (__pos >= __matches_lengths[__i]) 1032*38fd1498Szrj ++__nskipped, ++__i; 1033*38fd1498Szrj else if (!(__name[__pos] == __c)) 1034*38fd1498Szrj { 1035*38fd1498Szrj --__nmatches; 1036*38fd1498Szrj __matches[__i] = __matches[__nmatches]; 1037*38fd1498Szrj __matches_lengths[__i] = __matches_lengths[__nmatches]; 1038*38fd1498Szrj } 1039*38fd1498Szrj else 1040*38fd1498Szrj ++__i; 1041*38fd1498Szrj } 1042*38fd1498Szrj if (__nskipped == __nmatches) 1043*38fd1498Szrj break; 1044*38fd1498Szrj } 1045*38fd1498Szrj 1046*38fd1498Szrj if ((__nmatches == 1 && __matches_lengths[0] == __pos) 1047*38fd1498Szrj || (__nmatches == 2 && (__matches_lengths[0] == __pos 1048*38fd1498Szrj || __matches_lengths[1] == __pos))) 1049*38fd1498Szrj __member = (__matches[0] >= __indexlen 1050*38fd1498Szrj ? __matches[0] - __indexlen : __matches[0]); 1051*38fd1498Szrj else 1052*38fd1498Szrj __err |= ios_base::failbit; 1053*38fd1498Szrj 1054*38fd1498Szrj return __beg; 1055*38fd1498Szrj } 1056*38fd1498Szrj 1057*38fd1498Szrj template<typename _CharT, typename _InIter> 1058*38fd1498Szrj _InIter 1059*38fd1498Szrj time_get<_CharT, _InIter>:: do_get_time(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,tm * __tm) const1060*38fd1498Szrj do_get_time(iter_type __beg, iter_type __end, ios_base& __io, 1061*38fd1498Szrj ios_base::iostate& __err, tm* __tm) const 1062*38fd1498Szrj { 1063*38fd1498Szrj const locale& __loc = __io._M_getloc(); 1064*38fd1498Szrj const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 1065*38fd1498Szrj const char_type* __times[2]; 1066*38fd1498Szrj __tp._M_time_formats(__times); 1067*38fd1498Szrj __beg = _M_extract_via_format(__beg, __end, __io, __err, 1068*38fd1498Szrj __tm, __times[0]); 1069*38fd1498Szrj if (__beg == __end) 1070*38fd1498Szrj __err |= ios_base::eofbit; 1071*38fd1498Szrj return __beg; 1072*38fd1498Szrj } 1073*38fd1498Szrj 1074*38fd1498Szrj template<typename _CharT, typename _InIter> 1075*38fd1498Szrj _InIter 1076*38fd1498Szrj time_get<_CharT, _InIter>:: do_get_date(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,tm * __tm) const1077*38fd1498Szrj do_get_date(iter_type __beg, iter_type __end, ios_base& __io, 1078*38fd1498Szrj ios_base::iostate& __err, tm* __tm) const 1079*38fd1498Szrj { 1080*38fd1498Szrj const locale& __loc = __io._M_getloc(); 1081*38fd1498Szrj const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 1082*38fd1498Szrj const char_type* __dates[2]; 1083*38fd1498Szrj __tp._M_date_formats(__dates); 1084*38fd1498Szrj __beg = _M_extract_via_format(__beg, __end, __io, __err, 1085*38fd1498Szrj __tm, __dates[0]); 1086*38fd1498Szrj if (__beg == __end) 1087*38fd1498Szrj __err |= ios_base::eofbit; 1088*38fd1498Szrj return __beg; 1089*38fd1498Szrj } 1090*38fd1498Szrj 1091*38fd1498Szrj template<typename _CharT, typename _InIter> 1092*38fd1498Szrj _InIter 1093*38fd1498Szrj time_get<_CharT, _InIter>:: do_get_weekday(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,tm * __tm) const1094*38fd1498Szrj do_get_weekday(iter_type __beg, iter_type __end, ios_base& __io, 1095*38fd1498Szrj ios_base::iostate& __err, tm* __tm) const 1096*38fd1498Szrj { 1097*38fd1498Szrj const locale& __loc = __io._M_getloc(); 1098*38fd1498Szrj const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 1099*38fd1498Szrj const char_type* __days[14]; 1100*38fd1498Szrj __tp._M_days_abbreviated(__days); 1101*38fd1498Szrj __tp._M_days(__days + 7); 1102*38fd1498Szrj int __tmpwday; 1103*38fd1498Szrj ios_base::iostate __tmperr = ios_base::goodbit; 1104*38fd1498Szrj 1105*38fd1498Szrj __beg = _M_extract_wday_or_month(__beg, __end, __tmpwday, __days, 7, 1106*38fd1498Szrj __io, __tmperr); 1107*38fd1498Szrj if (!__tmperr) 1108*38fd1498Szrj __tm->tm_wday = __tmpwday; 1109*38fd1498Szrj else 1110*38fd1498Szrj __err |= ios_base::failbit; 1111*38fd1498Szrj 1112*38fd1498Szrj if (__beg == __end) 1113*38fd1498Szrj __err |= ios_base::eofbit; 1114*38fd1498Szrj return __beg; 1115*38fd1498Szrj } 1116*38fd1498Szrj 1117*38fd1498Szrj template<typename _CharT, typename _InIter> 1118*38fd1498Szrj _InIter 1119*38fd1498Szrj time_get<_CharT, _InIter>:: do_get_monthname(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,tm * __tm) const1120*38fd1498Szrj do_get_monthname(iter_type __beg, iter_type __end, 1121*38fd1498Szrj ios_base& __io, ios_base::iostate& __err, tm* __tm) const 1122*38fd1498Szrj { 1123*38fd1498Szrj const locale& __loc = __io._M_getloc(); 1124*38fd1498Szrj const __timepunct<_CharT>& __tp = use_facet<__timepunct<_CharT> >(__loc); 1125*38fd1498Szrj const char_type* __months[24]; 1126*38fd1498Szrj __tp._M_months_abbreviated(__months); 1127*38fd1498Szrj __tp._M_months(__months + 12); 1128*38fd1498Szrj int __tmpmon; 1129*38fd1498Szrj ios_base::iostate __tmperr = ios_base::goodbit; 1130*38fd1498Szrj 1131*38fd1498Szrj __beg = _M_extract_wday_or_month(__beg, __end, __tmpmon, __months, 12, 1132*38fd1498Szrj __io, __tmperr); 1133*38fd1498Szrj if (!__tmperr) 1134*38fd1498Szrj __tm->tm_mon = __tmpmon; 1135*38fd1498Szrj else 1136*38fd1498Szrj __err |= ios_base::failbit; 1137*38fd1498Szrj 1138*38fd1498Szrj if (__beg == __end) 1139*38fd1498Szrj __err |= ios_base::eofbit; 1140*38fd1498Szrj return __beg; 1141*38fd1498Szrj } 1142*38fd1498Szrj 1143*38fd1498Szrj template<typename _CharT, typename _InIter> 1144*38fd1498Szrj _InIter 1145*38fd1498Szrj time_get<_CharT, _InIter>:: do_get_year(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,tm * __tm) const1146*38fd1498Szrj do_get_year(iter_type __beg, iter_type __end, ios_base& __io, 1147*38fd1498Szrj ios_base::iostate& __err, tm* __tm) const 1148*38fd1498Szrj { 1149*38fd1498Szrj int __tmpyear; 1150*38fd1498Szrj ios_base::iostate __tmperr = ios_base::goodbit; 1151*38fd1498Szrj 1152*38fd1498Szrj __beg = _M_extract_num(__beg, __end, __tmpyear, 0, 9999, 4, 1153*38fd1498Szrj __io, __tmperr); 1154*38fd1498Szrj if (!__tmperr) 1155*38fd1498Szrj __tm->tm_year = __tmpyear < 0 ? __tmpyear + 100 : __tmpyear - 1900; 1156*38fd1498Szrj else 1157*38fd1498Szrj __err |= ios_base::failbit; 1158*38fd1498Szrj 1159*38fd1498Szrj if (__beg == __end) 1160*38fd1498Szrj __err |= ios_base::eofbit; 1161*38fd1498Szrj return __beg; 1162*38fd1498Szrj } 1163*38fd1498Szrj 1164*38fd1498Szrj #if __cplusplus >= 201103L 1165*38fd1498Szrj template<typename _CharT, typename _InIter> 1166*38fd1498Szrj inline 1167*38fd1498Szrj _InIter 1168*38fd1498Szrj time_get<_CharT, _InIter>:: get(iter_type __s,iter_type __end,ios_base & __io,ios_base::iostate & __err,tm * __tm,const char_type * __fmt,const char_type * __fmtend) const1169*38fd1498Szrj get(iter_type __s, iter_type __end, ios_base& __io, 1170*38fd1498Szrj ios_base::iostate& __err, tm* __tm, const char_type* __fmt, 1171*38fd1498Szrj const char_type* __fmtend) const 1172*38fd1498Szrj { 1173*38fd1498Szrj const locale& __loc = __io._M_getloc(); 1174*38fd1498Szrj ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); 1175*38fd1498Szrj __err = ios_base::goodbit; 1176*38fd1498Szrj while (__fmt != __fmtend && 1177*38fd1498Szrj __err == ios_base::goodbit) 1178*38fd1498Szrj { 1179*38fd1498Szrj if (__s == __end) 1180*38fd1498Szrj { 1181*38fd1498Szrj __err = ios_base::eofbit | ios_base::failbit; 1182*38fd1498Szrj break; 1183*38fd1498Szrj } 1184*38fd1498Szrj else if (__ctype.narrow(*__fmt, 0) == '%') 1185*38fd1498Szrj { 1186*38fd1498Szrj char __format; 1187*38fd1498Szrj char __mod = 0; 1188*38fd1498Szrj if (++__fmt == __fmtend) 1189*38fd1498Szrj { 1190*38fd1498Szrj __err = ios_base::failbit; 1191*38fd1498Szrj break; 1192*38fd1498Szrj } 1193*38fd1498Szrj const char __c = __ctype.narrow(*__fmt, 0); 1194*38fd1498Szrj if (__c != 'E' && __c != 'O') 1195*38fd1498Szrj __format = __c; 1196*38fd1498Szrj else if (++__fmt != __fmtend) 1197*38fd1498Szrj { 1198*38fd1498Szrj __mod = __c; 1199*38fd1498Szrj __format = __ctype.narrow(*__fmt, 0); 1200*38fd1498Szrj } 1201*38fd1498Szrj else 1202*38fd1498Szrj { 1203*38fd1498Szrj __err = ios_base::failbit; 1204*38fd1498Szrj break; 1205*38fd1498Szrj } 1206*38fd1498Szrj __s = this->do_get(__s, __end, __io, __err, __tm, __format, 1207*38fd1498Szrj __mod); 1208*38fd1498Szrj ++__fmt; 1209*38fd1498Szrj } 1210*38fd1498Szrj else if (__ctype.is(ctype_base::space, *__fmt)) 1211*38fd1498Szrj { 1212*38fd1498Szrj ++__fmt; 1213*38fd1498Szrj while (__fmt != __fmtend && 1214*38fd1498Szrj __ctype.is(ctype_base::space, *__fmt)) 1215*38fd1498Szrj ++__fmt; 1216*38fd1498Szrj 1217*38fd1498Szrj while (__s != __end && 1218*38fd1498Szrj __ctype.is(ctype_base::space, *__s)) 1219*38fd1498Szrj ++__s; 1220*38fd1498Szrj } 1221*38fd1498Szrj // TODO real case-insensitive comparison 1222*38fd1498Szrj else if (__ctype.tolower(*__s) == __ctype.tolower(*__fmt) || 1223*38fd1498Szrj __ctype.toupper(*__s) == __ctype.toupper(*__fmt)) 1224*38fd1498Szrj { 1225*38fd1498Szrj ++__s; 1226*38fd1498Szrj ++__fmt; 1227*38fd1498Szrj } 1228*38fd1498Szrj else 1229*38fd1498Szrj { 1230*38fd1498Szrj __err = ios_base::failbit; 1231*38fd1498Szrj break; 1232*38fd1498Szrj } 1233*38fd1498Szrj } 1234*38fd1498Szrj return __s; 1235*38fd1498Szrj } 1236*38fd1498Szrj 1237*38fd1498Szrj template<typename _CharT, typename _InIter> 1238*38fd1498Szrj inline 1239*38fd1498Szrj _InIter 1240*38fd1498Szrj time_get<_CharT, _InIter>:: do_get(iter_type __beg,iter_type __end,ios_base & __io,ios_base::iostate & __err,tm * __tm,char __format,char __mod) const1241*38fd1498Szrj do_get(iter_type __beg, iter_type __end, ios_base& __io, 1242*38fd1498Szrj ios_base::iostate& __err, tm* __tm, 1243*38fd1498Szrj char __format, char __mod) const 1244*38fd1498Szrj { 1245*38fd1498Szrj const locale& __loc = __io._M_getloc(); 1246*38fd1498Szrj ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); 1247*38fd1498Szrj __err = ios_base::goodbit; 1248*38fd1498Szrj 1249*38fd1498Szrj char_type __fmt[4]; 1250*38fd1498Szrj __fmt[0] = __ctype.widen('%'); 1251*38fd1498Szrj if (!__mod) 1252*38fd1498Szrj { 1253*38fd1498Szrj __fmt[1] = __format; 1254*38fd1498Szrj __fmt[2] = char_type(); 1255*38fd1498Szrj } 1256*38fd1498Szrj else 1257*38fd1498Szrj { 1258*38fd1498Szrj __fmt[1] = __mod; 1259*38fd1498Szrj __fmt[2] = __format; 1260*38fd1498Szrj __fmt[3] = char_type(); 1261*38fd1498Szrj } 1262*38fd1498Szrj 1263*38fd1498Szrj __beg = _M_extract_via_format(__beg, __end, __io, __err, __tm, __fmt); 1264*38fd1498Szrj if (__beg == __end) 1265*38fd1498Szrj __err |= ios_base::eofbit; 1266*38fd1498Szrj return __beg; 1267*38fd1498Szrj } 1268*38fd1498Szrj 1269*38fd1498Szrj #endif // __cplusplus >= 201103L 1270*38fd1498Szrj 1271*38fd1498Szrj template<typename _CharT, typename _OutIter> 1272*38fd1498Szrj _OutIter 1273*38fd1498Szrj time_put<_CharT, _OutIter>:: put(iter_type __s,ios_base & __io,char_type __fill,const tm * __tm,const _CharT * __beg,const _CharT * __end) const1274*38fd1498Szrj put(iter_type __s, ios_base& __io, char_type __fill, const tm* __tm, 1275*38fd1498Szrj const _CharT* __beg, const _CharT* __end) const 1276*38fd1498Szrj { 1277*38fd1498Szrj const locale& __loc = __io._M_getloc(); 1278*38fd1498Szrj ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); 1279*38fd1498Szrj for (; __beg != __end; ++__beg) 1280*38fd1498Szrj if (__ctype.narrow(*__beg, 0) != '%') 1281*38fd1498Szrj { 1282*38fd1498Szrj *__s = *__beg; 1283*38fd1498Szrj ++__s; 1284*38fd1498Szrj } 1285*38fd1498Szrj else if (++__beg != __end) 1286*38fd1498Szrj { 1287*38fd1498Szrj char __format; 1288*38fd1498Szrj char __mod = 0; 1289*38fd1498Szrj const char __c = __ctype.narrow(*__beg, 0); 1290*38fd1498Szrj if (__c != 'E' && __c != 'O') 1291*38fd1498Szrj __format = __c; 1292*38fd1498Szrj else if (++__beg != __end) 1293*38fd1498Szrj { 1294*38fd1498Szrj __mod = __c; 1295*38fd1498Szrj __format = __ctype.narrow(*__beg, 0); 1296*38fd1498Szrj } 1297*38fd1498Szrj else 1298*38fd1498Szrj break; 1299*38fd1498Szrj __s = this->do_put(__s, __io, __fill, __tm, __format, __mod); 1300*38fd1498Szrj } 1301*38fd1498Szrj else 1302*38fd1498Szrj break; 1303*38fd1498Szrj return __s; 1304*38fd1498Szrj } 1305*38fd1498Szrj 1306*38fd1498Szrj template<typename _CharT, typename _OutIter> 1307*38fd1498Szrj _OutIter 1308*38fd1498Szrj time_put<_CharT, _OutIter>:: do_put(iter_type __s,ios_base & __io,char_type,const tm * __tm,char __format,char __mod) const1309*38fd1498Szrj do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, 1310*38fd1498Szrj char __format, char __mod) const 1311*38fd1498Szrj { 1312*38fd1498Szrj const locale& __loc = __io._M_getloc(); 1313*38fd1498Szrj ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); 1314*38fd1498Szrj __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); 1315*38fd1498Szrj 1316*38fd1498Szrj // NB: This size is arbitrary. Should this be a data member, 1317*38fd1498Szrj // initialized at construction? 1318*38fd1498Szrj const size_t __maxlen = 128; 1319*38fd1498Szrj char_type __res[__maxlen]; 1320*38fd1498Szrj 1321*38fd1498Szrj // NB: In IEE 1003.1-200x, and perhaps other locale models, it 1322*38fd1498Szrj // is possible that the format character will be longer than one 1323*38fd1498Szrj // character. Possibilities include 'E' or 'O' followed by a 1324*38fd1498Szrj // format character: if __mod is not the default argument, assume 1325*38fd1498Szrj // it's a valid modifier. 1326*38fd1498Szrj char_type __fmt[4]; 1327*38fd1498Szrj __fmt[0] = __ctype.widen('%'); 1328*38fd1498Szrj if (!__mod) 1329*38fd1498Szrj { 1330*38fd1498Szrj __fmt[1] = __format; 1331*38fd1498Szrj __fmt[2] = char_type(); 1332*38fd1498Szrj } 1333*38fd1498Szrj else 1334*38fd1498Szrj { 1335*38fd1498Szrj __fmt[1] = __mod; 1336*38fd1498Szrj __fmt[2] = __format; 1337*38fd1498Szrj __fmt[3] = char_type(); 1338*38fd1498Szrj } 1339*38fd1498Szrj 1340*38fd1498Szrj __tp._M_put(__res, __maxlen, __fmt, __tm); 1341*38fd1498Szrj 1342*38fd1498Szrj // Write resulting, fully-formatted string to output iterator. 1343*38fd1498Szrj return std::__write(__s, __res, char_traits<char_type>::length(__res)); 1344*38fd1498Szrj } 1345*38fd1498Szrj 1346*38fd1498Szrj 1347*38fd1498Szrj // Inhibit implicit instantiations for required instantiations, 1348*38fd1498Szrj // which are defined via explicit instantiations elsewhere. 1349*38fd1498Szrj #if _GLIBCXX_EXTERN_TEMPLATE 1350*38fd1498Szrj extern template class moneypunct<char, false>; 1351*38fd1498Szrj extern template class moneypunct<char, true>; 1352*38fd1498Szrj extern template class moneypunct_byname<char, false>; 1353*38fd1498Szrj extern template class moneypunct_byname<char, true>; 1354*38fd1498Szrj extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_get<char>; 1355*38fd1498Szrj extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_put<char>; 1356*38fd1498Szrj extern template class __timepunct<char>; 1357*38fd1498Szrj extern template class time_put<char>; 1358*38fd1498Szrj extern template class time_put_byname<char>; 1359*38fd1498Szrj extern template class time_get<char>; 1360*38fd1498Szrj extern template class time_get_byname<char>; 1361*38fd1498Szrj extern template class messages<char>; 1362*38fd1498Szrj extern template class messages_byname<char>; 1363*38fd1498Szrj 1364*38fd1498Szrj extern template 1365*38fd1498Szrj const moneypunct<char, true>& 1366*38fd1498Szrj use_facet<moneypunct<char, true> >(const locale&); 1367*38fd1498Szrj 1368*38fd1498Szrj extern template 1369*38fd1498Szrj const moneypunct<char, false>& 1370*38fd1498Szrj use_facet<moneypunct<char, false> >(const locale&); 1371*38fd1498Szrj 1372*38fd1498Szrj extern template 1373*38fd1498Szrj const money_put<char>& 1374*38fd1498Szrj use_facet<money_put<char> >(const locale&); 1375*38fd1498Szrj 1376*38fd1498Szrj extern template 1377*38fd1498Szrj const money_get<char>& 1378*38fd1498Szrj use_facet<money_get<char> >(const locale&); 1379*38fd1498Szrj 1380*38fd1498Szrj extern template 1381*38fd1498Szrj const __timepunct<char>& 1382*38fd1498Szrj use_facet<__timepunct<char> >(const locale&); 1383*38fd1498Szrj 1384*38fd1498Szrj extern template 1385*38fd1498Szrj const time_put<char>& 1386*38fd1498Szrj use_facet<time_put<char> >(const locale&); 1387*38fd1498Szrj 1388*38fd1498Szrj extern template 1389*38fd1498Szrj const time_get<char>& 1390*38fd1498Szrj use_facet<time_get<char> >(const locale&); 1391*38fd1498Szrj 1392*38fd1498Szrj extern template 1393*38fd1498Szrj const messages<char>& 1394*38fd1498Szrj use_facet<messages<char> >(const locale&); 1395*38fd1498Szrj 1396*38fd1498Szrj extern template 1397*38fd1498Szrj bool 1398*38fd1498Szrj has_facet<moneypunct<char> >(const locale&); 1399*38fd1498Szrj 1400*38fd1498Szrj extern template 1401*38fd1498Szrj bool 1402*38fd1498Szrj has_facet<money_put<char> >(const locale&); 1403*38fd1498Szrj 1404*38fd1498Szrj extern template 1405*38fd1498Szrj bool 1406*38fd1498Szrj has_facet<money_get<char> >(const locale&); 1407*38fd1498Szrj 1408*38fd1498Szrj extern template 1409*38fd1498Szrj bool 1410*38fd1498Szrj has_facet<__timepunct<char> >(const locale&); 1411*38fd1498Szrj 1412*38fd1498Szrj extern template 1413*38fd1498Szrj bool 1414*38fd1498Szrj has_facet<time_put<char> >(const locale&); 1415*38fd1498Szrj 1416*38fd1498Szrj extern template 1417*38fd1498Szrj bool 1418*38fd1498Szrj has_facet<time_get<char> >(const locale&); 1419*38fd1498Szrj 1420*38fd1498Szrj extern template 1421*38fd1498Szrj bool 1422*38fd1498Szrj has_facet<messages<char> >(const locale&); 1423*38fd1498Szrj 1424*38fd1498Szrj #ifdef _GLIBCXX_USE_WCHAR_T 1425*38fd1498Szrj extern template class moneypunct<wchar_t, false>; 1426*38fd1498Szrj extern template class moneypunct<wchar_t, true>; 1427*38fd1498Szrj extern template class moneypunct_byname<wchar_t, false>; 1428*38fd1498Szrj extern template class moneypunct_byname<wchar_t, true>; 1429*38fd1498Szrj extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_get<wchar_t>; 1430*38fd1498Szrj extern template class _GLIBCXX_NAMESPACE_LDBL_OR_CXX11 money_put<wchar_t>; 1431*38fd1498Szrj extern template class __timepunct<wchar_t>; 1432*38fd1498Szrj extern template class time_put<wchar_t>; 1433*38fd1498Szrj extern template class time_put_byname<wchar_t>; 1434*38fd1498Szrj extern template class time_get<wchar_t>; 1435*38fd1498Szrj extern template class time_get_byname<wchar_t>; 1436*38fd1498Szrj extern template class messages<wchar_t>; 1437*38fd1498Szrj extern template class messages_byname<wchar_t>; 1438*38fd1498Szrj 1439*38fd1498Szrj extern template 1440*38fd1498Szrj const moneypunct<wchar_t, true>& 1441*38fd1498Szrj use_facet<moneypunct<wchar_t, true> >(const locale&); 1442*38fd1498Szrj 1443*38fd1498Szrj extern template 1444*38fd1498Szrj const moneypunct<wchar_t, false>& 1445*38fd1498Szrj use_facet<moneypunct<wchar_t, false> >(const locale&); 1446*38fd1498Szrj 1447*38fd1498Szrj extern template 1448*38fd1498Szrj const money_put<wchar_t>& 1449*38fd1498Szrj use_facet<money_put<wchar_t> >(const locale&); 1450*38fd1498Szrj 1451*38fd1498Szrj extern template 1452*38fd1498Szrj const money_get<wchar_t>& 1453*38fd1498Szrj use_facet<money_get<wchar_t> >(const locale&); 1454*38fd1498Szrj 1455*38fd1498Szrj extern template 1456*38fd1498Szrj const __timepunct<wchar_t>& 1457*38fd1498Szrj use_facet<__timepunct<wchar_t> >(const locale&); 1458*38fd1498Szrj 1459*38fd1498Szrj extern template 1460*38fd1498Szrj const time_put<wchar_t>& 1461*38fd1498Szrj use_facet<time_put<wchar_t> >(const locale&); 1462*38fd1498Szrj 1463*38fd1498Szrj extern template 1464*38fd1498Szrj const time_get<wchar_t>& 1465*38fd1498Szrj use_facet<time_get<wchar_t> >(const locale&); 1466*38fd1498Szrj 1467*38fd1498Szrj extern template 1468*38fd1498Szrj const messages<wchar_t>& 1469*38fd1498Szrj use_facet<messages<wchar_t> >(const locale&); 1470*38fd1498Szrj 1471*38fd1498Szrj extern template 1472*38fd1498Szrj bool 1473*38fd1498Szrj has_facet<moneypunct<wchar_t> >(const locale&); 1474*38fd1498Szrj 1475*38fd1498Szrj extern template 1476*38fd1498Szrj bool 1477*38fd1498Szrj has_facet<money_put<wchar_t> >(const locale&); 1478*38fd1498Szrj 1479*38fd1498Szrj extern template 1480*38fd1498Szrj bool 1481*38fd1498Szrj has_facet<money_get<wchar_t> >(const locale&); 1482*38fd1498Szrj 1483*38fd1498Szrj extern template 1484*38fd1498Szrj bool 1485*38fd1498Szrj has_facet<__timepunct<wchar_t> >(const locale&); 1486*38fd1498Szrj 1487*38fd1498Szrj extern template 1488*38fd1498Szrj bool 1489*38fd1498Szrj has_facet<time_put<wchar_t> >(const locale&); 1490*38fd1498Szrj 1491*38fd1498Szrj extern template 1492*38fd1498Szrj bool 1493*38fd1498Szrj has_facet<time_get<wchar_t> >(const locale&); 1494*38fd1498Szrj 1495*38fd1498Szrj extern template 1496*38fd1498Szrj bool 1497*38fd1498Szrj has_facet<messages<wchar_t> >(const locale&); 1498*38fd1498Szrj #endif 1499*38fd1498Szrj #endif 1500*38fd1498Szrj 1501*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 1502*38fd1498Szrj } // namespace std 1503*38fd1498Szrj 1504*38fd1498Szrj #endif 1505