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