Home | History | Annotate | Download | only in bits
      1 // istream classes -*- C++ -*-
      2 
      3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
      4 // 2006, 2007, 2008, 2009
      5 // Free Software Foundation, Inc.
      6 //
      7 // This file is part of the GNU ISO C++ Library.  This library is free
      8 // software; you can redistribute it and/or modify it under the
      9 // terms of the GNU General Public License as published by the
     10 // Free Software Foundation; either version 3, or (at your option)
     11 // any later version.
     12 
     13 // This library is distributed in the hope that it will be useful,
     14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 // GNU General Public License for more details.
     17 
     18 // Under Section 7 of GPL version 3, you are granted additional
     19 // permissions described in the GCC Runtime Library Exception, version
     20 // 3.1, as published by the Free Software Foundation.
     21 
     22 // You should have received a copy of the GNU General Public License and
     23 // a copy of the GCC Runtime Library Exception along with this program;
     24 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     25 // <http://www.gnu.org/licenses/>.
     26 
     27 /** @file istream.tcc
     28  *  This is an internal header file, included by other library headers.
     29  *  You should not attempt to use it directly.
     30  */
     31 
     32 //
     33 // ISO C++ 14882: 27.6.1  Input streams
     34 //
     35 
     36 #ifndef _ISTREAM_TCC
     37 #define _ISTREAM_TCC 1
     38 
     39 #pragma GCC system_header
     40 
     41 #include <cxxabi-forced.h>
     42 
     43 _GLIBCXX_BEGIN_NAMESPACE(std)
     44 
     45   template<typename _CharT, typename _Traits>
     46     basic_istream<_CharT, _Traits>::sentry::
     47     sentry(basic_istream<_CharT, _Traits>& __in, bool __noskip) : _M_ok(false)
     48     {
     49       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
     50       if (__in.good())
     51 	{
     52 	  if (__in.tie())
     53 	    __in.tie()->flush();
     54 	  if (!__noskip && bool(__in.flags() & ios_base::skipws))
     55 	    {
     56 	      const __int_type __eof = traits_type::eof();
     57 	      __streambuf_type* __sb = __in.rdbuf();
     58 	      __int_type __c = __sb->sgetc();
     59 
     60 	      const __ctype_type& __ct = __check_facet(__in._M_ctype);
     61 	      while (!traits_type::eq_int_type(__c, __eof)
     62 		     && __ct.is(ctype_base::space, 
     63 				traits_type::to_char_type(__c)))
     64 		__c = __sb->snextc();
     65 
     66 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
     67 	      // 195. Should basic_istream::sentry's constructor ever
     68 	      // set eofbit?
     69 	      if (traits_type::eq_int_type(__c, __eof))
     70 		__err |= ios_base::eofbit;
     71 	    }
     72 	}
     73 
     74       if (__in.good() && __err == ios_base::goodbit)
     75 	_M_ok = true;
     76       else
     77 	{
     78 	  __err |= ios_base::failbit;
     79 	  __in.setstate(__err);
     80 	}
     81     }
     82 
     83   template<typename _CharT, typename _Traits>
     84     template<typename _ValueT>
     85       basic_istream<_CharT, _Traits>&
     86       basic_istream<_CharT, _Traits>::
     87       _M_extract(_ValueT& __v)
     88       {
     89 	sentry __cerb(*this, false);
     90 	if (__cerb)
     91 	  {
     92 	    ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
     93 	    __try
     94 	      {
     95 		const __num_get_type& __ng = __check_facet(this->_M_num_get);
     96 		__ng.get(*this, 0, *this, __err, __v);
     97 	      }
     98 	    __catch(__cxxabiv1::__forced_unwind&)
     99 	      {
    100 		this->_M_setstate(ios_base::badbit);		
    101 		__throw_exception_again;
    102 	      }
    103 	    __catch(...)
    104 	      { this->_M_setstate(ios_base::badbit); }
    105 	    if (__err)
    106 	      this->setstate(__err);
    107 	  }
    108 	return *this;
    109       }
    110 
    111   template<typename _CharT, typename _Traits>
    112     basic_istream<_CharT, _Traits>&
    113     basic_istream<_CharT, _Traits>::
    114     operator>>(short& __n)
    115     {
    116       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    117       // 118. basic_istream uses nonexistent num_get member functions.
    118       long __l;
    119       _M_extract(__l);
    120       if (!this->fail())
    121 	{
    122 	  if (__gnu_cxx::__numeric_traits<short>::__min <= __l
    123 	      && __l <= __gnu_cxx::__numeric_traits<short>::__max)
    124 	    __n = short(__l);
    125 	  else
    126 	    this->setstate(ios_base::failbit);
    127 	}
    128       return *this;
    129     }
    130     
    131   template<typename _CharT, typename _Traits>
    132     basic_istream<_CharT, _Traits>&
    133     basic_istream<_CharT, _Traits>::
    134     operator>>(int& __n)
    135     {
    136       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    137       // 118. basic_istream uses nonexistent num_get member functions.
    138       long __l;
    139       _M_extract(__l);
    140       if (!this->fail())
    141 	{
    142 	  if (__gnu_cxx::__numeric_traits<int>::__min <= __l
    143 	      && __l <= __gnu_cxx::__numeric_traits<int>::__max)
    144 	    __n = int(__l);
    145 	  else
    146 	    this->setstate(ios_base::failbit);
    147 	}
    148       return *this;
    149     }
    150 
    151   template<typename _CharT, typename _Traits>
    152     basic_istream<_CharT, _Traits>&
    153     basic_istream<_CharT, _Traits>::
    154     operator>>(__streambuf_type* __sbout)
    155     {
    156       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    157       sentry __cerb(*this, false);
    158       if (__cerb && __sbout)
    159 	{
    160 	  __try
    161 	    {
    162 	      bool __ineof;
    163 	      if (!__copy_streambufs_eof(this->rdbuf(), __sbout, __ineof))
    164 		__err |= ios_base::failbit;
    165 	      if (__ineof)
    166 		__err |= ios_base::eofbit;
    167 	    }
    168 	  __catch(__cxxabiv1::__forced_unwind&)
    169 	    {
    170 	      this->_M_setstate(ios_base::failbit);
    171 	      __throw_exception_again;
    172 	    }
    173 	  __catch(...)
    174 	    { this->_M_setstate(ios_base::failbit); }
    175 	}
    176       else if (!__sbout)
    177 	__err |= ios_base::failbit;
    178       if (__err)
    179 	this->setstate(__err);
    180       return *this;
    181     }
    182 
    183   template<typename _CharT, typename _Traits>
    184     typename basic_istream<_CharT, _Traits>::int_type
    185     basic_istream<_CharT, _Traits>::
    186     get(void)
    187     {
    188       const int_type __eof = traits_type::eof();
    189       int_type __c = __eof;
    190       _M_gcount = 0;
    191       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    192       sentry __cerb(*this, true);
    193       if (__cerb)
    194 	{
    195 	  __try
    196 	    {
    197 	      __c = this->rdbuf()->sbumpc();
    198 	      // 27.6.1.1 paragraph 3
    199 	      if (!traits_type::eq_int_type(__c, __eof))
    200 		_M_gcount = 1;
    201 	      else
    202 		__err |= ios_base::eofbit;
    203 	    }
    204 	  __catch(__cxxabiv1::__forced_unwind&)
    205 	    {
    206 	      this->_M_setstate(ios_base::badbit);
    207 	      __throw_exception_again;
    208 	    }
    209 	  __catch(...)
    210 	    { this->_M_setstate(ios_base::badbit); }
    211 	}
    212       if (!_M_gcount)
    213 	__err |= ios_base::failbit;
    214       if (__err)
    215 	this->setstate(__err);
    216       return __c;
    217     }
    218 
    219   template<typename _CharT, typename _Traits>
    220     basic_istream<_CharT, _Traits>&
    221     basic_istream<_CharT, _Traits>::
    222     get(char_type& __c)
    223     {
    224       _M_gcount = 0;
    225       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    226       sentry __cerb(*this, true);
    227       if (__cerb)
    228 	{
    229 	  __try
    230 	    {
    231 	      const int_type __cb = this->rdbuf()->sbumpc();
    232 	      // 27.6.1.1 paragraph 3
    233 	      if (!traits_type::eq_int_type(__cb, traits_type::eof()))
    234 		{
    235 		  _M_gcount = 1;
    236 		  __c = traits_type::to_char_type(__cb);
    237 		}
    238 	      else
    239 		__err |= ios_base::eofbit;
    240 	    }
    241 	  __catch(__cxxabiv1::__forced_unwind&)
    242 	    {
    243 	      this->_M_setstate(ios_base::badbit);
    244 	      __throw_exception_again;
    245 	    }
    246 	  __catch(...)
    247 	    { this->_M_setstate(ios_base::badbit); }
    248 	}
    249       if (!_M_gcount)
    250 	__err |= ios_base::failbit;
    251       if (__err)
    252 	this->setstate(__err);
    253       return *this;
    254     }
    255 
    256   template<typename _CharT, typename _Traits>
    257     basic_istream<_CharT, _Traits>&
    258     basic_istream<_CharT, _Traits>::
    259     get(char_type* __s, streamsize __n, char_type __delim)
    260     {
    261       _M_gcount = 0;
    262       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    263       sentry __cerb(*this, true);
    264       if (__cerb)
    265 	{
    266 	  __try
    267 	    {
    268 	      const int_type __idelim = traits_type::to_int_type(__delim);
    269 	      const int_type __eof = traits_type::eof();
    270 	      __streambuf_type* __sb = this->rdbuf();
    271 	      int_type __c = __sb->sgetc();
    272 
    273 	      while (_M_gcount + 1 < __n
    274 		     && !traits_type::eq_int_type(__c, __eof)
    275 		     && !traits_type::eq_int_type(__c, __idelim))
    276 		{
    277 		  *__s++ = traits_type::to_char_type(__c);
    278 		  ++_M_gcount;
    279 		  __c = __sb->snextc();
    280 		}
    281 	      if (traits_type::eq_int_type(__c, __eof))
    282 		__err |= ios_base::eofbit;
    283 	    }
    284 	  __catch(__cxxabiv1::__forced_unwind&)
    285 	    {
    286 	      this->_M_setstate(ios_base::badbit);
    287 	      __throw_exception_again;
    288 	    }
    289 	  __catch(...)
    290 	    { this->_M_setstate(ios_base::badbit); }
    291 	}
    292       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    293       // 243. get and getline when sentry reports failure.
    294       if (__n > 0)
    295 	*__s = char_type();
    296       if (!_M_gcount)
    297 	__err |= ios_base::failbit;
    298       if (__err)
    299 	this->setstate(__err);
    300       return *this;
    301     }
    302 
    303   template<typename _CharT, typename _Traits>
    304     basic_istream<_CharT, _Traits>&
    305     basic_istream<_CharT, _Traits>::
    306     get(__streambuf_type& __sb, char_type __delim)
    307     {
    308       _M_gcount = 0;
    309       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    310       sentry __cerb(*this, true);
    311       if (__cerb)
    312 	{
    313 	  __try
    314 	    {
    315 	      const int_type __idelim = traits_type::to_int_type(__delim);
    316 	      const int_type __eof = traits_type::eof();
    317 	      __streambuf_type* __this_sb = this->rdbuf();
    318 	      int_type __c = __this_sb->sgetc();
    319 	      char_type __c2 = traits_type::to_char_type(__c);
    320 
    321 	      while (!traits_type::eq_int_type(__c, __eof)
    322 		     && !traits_type::eq_int_type(__c, __idelim)
    323 		     && !traits_type::eq_int_type(__sb.sputc(__c2), __eof))
    324 		{
    325 		  ++_M_gcount;
    326 		  __c = __this_sb->snextc();
    327 		  __c2 = traits_type::to_char_type(__c);
    328 		}
    329 	      if (traits_type::eq_int_type(__c, __eof))
    330 		__err |= ios_base::eofbit;
    331 	    }
    332 	  __catch(__cxxabiv1::__forced_unwind&)
    333 	    {
    334 	      this->_M_setstate(ios_base::badbit);
    335 	      __throw_exception_again;
    336 	    }
    337 	  __catch(...)
    338 	    { this->_M_setstate(ios_base::badbit); }
    339 	}
    340       if (!_M_gcount)
    341 	__err |= ios_base::failbit;
    342       if (__err)
    343 	this->setstate(__err);
    344       return *this;
    345     }
    346 
    347   template<typename _CharT, typename _Traits>
    348     basic_istream<_CharT, _Traits>&
    349     basic_istream<_CharT, _Traits>::
    350     getline(char_type* __s, streamsize __n, char_type __delim)
    351     {
    352       _M_gcount = 0;
    353       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    354       sentry __cerb(*this, true);
    355       if (__cerb)
    356         {
    357           __try
    358             {
    359               const int_type __idelim = traits_type::to_int_type(__delim);
    360               const int_type __eof = traits_type::eof();
    361               __streambuf_type* __sb = this->rdbuf();
    362               int_type __c = __sb->sgetc();
    363 
    364               while (_M_gcount + 1 < __n
    365                      && !traits_type::eq_int_type(__c, __eof)
    366                      && !traits_type::eq_int_type(__c, __idelim))
    367                 {
    368                   *__s++ = traits_type::to_char_type(__c);
    369                   __c = __sb->snextc();
    370                   ++_M_gcount;
    371                 }
    372               if (traits_type::eq_int_type(__c, __eof))
    373                 __err |= ios_base::eofbit;
    374               else
    375                 {
    376                   if (traits_type::eq_int_type(__c, __idelim))
    377                     {
    378                       __sb->sbumpc();
    379                       ++_M_gcount;
    380                     }
    381                   else
    382                     __err |= ios_base::failbit;
    383                 }
    384             }
    385 	  __catch(__cxxabiv1::__forced_unwind&)
    386 	    {
    387 	      this->_M_setstate(ios_base::badbit);
    388 	      __throw_exception_again;
    389 	    }
    390           __catch(...)
    391             { this->_M_setstate(ios_base::badbit); }
    392         }
    393       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    394       // 243. get and getline when sentry reports failure.
    395       if (__n > 0)
    396 	*__s = char_type();
    397       if (!_M_gcount)
    398         __err |= ios_base::failbit;
    399       if (__err)
    400         this->setstate(__err);
    401       return *this;
    402     }
    403 
    404   // We provide three overloads, since the first two are much simpler
    405   // than the general case. Also, the latter two can thus adopt the
    406   // same "batchy" strategy used by getline above.
    407   template<typename _CharT, typename _Traits>
    408     basic_istream<_CharT, _Traits>&
    409     basic_istream<_CharT, _Traits>::
    410     ignore(void)
    411     {
    412       _M_gcount = 0;
    413       sentry __cerb(*this, true);
    414       if (__cerb)
    415 	{
    416 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    417 	  __try
    418 	    {
    419 	      const int_type __eof = traits_type::eof();
    420 	      __streambuf_type* __sb = this->rdbuf();
    421 
    422 	      if (traits_type::eq_int_type(__sb->sbumpc(), __eof))
    423 		__err |= ios_base::eofbit;
    424 	      else
    425 		_M_gcount = 1;
    426 	    }
    427 	  __catch(__cxxabiv1::__forced_unwind&)
    428 	    {
    429 	      this->_M_setstate(ios_base::badbit);
    430 	      __throw_exception_again;
    431 	    }
    432 	  __catch(...)
    433 	    { this->_M_setstate(ios_base::badbit); }
    434 	  if (__err)
    435 	    this->setstate(__err);
    436 	}
    437       return *this;
    438     }
    439 
    440   template<typename _CharT, typename _Traits>
    441     basic_istream<_CharT, _Traits>&
    442     basic_istream<_CharT, _Traits>::
    443     ignore(streamsize __n)
    444     {
    445       _M_gcount = 0;
    446       sentry __cerb(*this, true);
    447       if (__cerb && __n > 0)
    448         {
    449           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    450           __try
    451             {
    452               const int_type __eof = traits_type::eof();
    453               __streambuf_type* __sb = this->rdbuf();
    454               int_type __c = __sb->sgetc();
    455 
    456 	      // N.B. On LFS-enabled platforms streamsize is still 32 bits
    457 	      // wide: if we want to implement the standard mandated behavior
    458 	      // for n == max() (see 27.6.1.3/24) we are at risk of signed
    459 	      // integer overflow: thus these contortions. Also note that,
    460 	      // by definition, when more than 2G chars are actually ignored,
    461 	      // _M_gcount (the return value of gcount, that is) cannot be
    462 	      // really correct, being unavoidably too small.
    463 	      bool __large_ignore = false;
    464 	      while (true)
    465 		{
    466 		  while (_M_gcount < __n
    467 			 && !traits_type::eq_int_type(__c, __eof))
    468 		    {
    469 		      ++_M_gcount;
    470 		      __c = __sb->snextc();
    471 		    }
    472 		  if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max
    473 		      && !traits_type::eq_int_type(__c, __eof))
    474 		    {
    475 		      _M_gcount =
    476 			__gnu_cxx::__numeric_traits<streamsize>::__min;
    477 		      __large_ignore = true;
    478 		    }
    479 		  else
    480 		    break;
    481 		}
    482 
    483 	      if (__large_ignore)
    484 		_M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max;
    485 
    486 	      if (traits_type::eq_int_type(__c, __eof))
    487                 __err |= ios_base::eofbit;
    488             }
    489 	  __catch(__cxxabiv1::__forced_unwind&)
    490 	    {
    491 	      this->_M_setstate(ios_base::badbit);
    492 	      __throw_exception_again;
    493 	    }
    494           __catch(...)
    495             { this->_M_setstate(ios_base::badbit); }
    496           if (__err)
    497             this->setstate(__err);
    498         }
    499       return *this;
    500     }
    501 
    502   template<typename _CharT, typename _Traits>
    503     basic_istream<_CharT, _Traits>&
    504     basic_istream<_CharT, _Traits>::
    505     ignore(streamsize __n, int_type __delim)
    506     {
    507       _M_gcount = 0;
    508       sentry __cerb(*this, true);
    509       if (__cerb && __n > 0)
    510         {
    511           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    512           __try
    513             {
    514               const int_type __eof = traits_type::eof();
    515               __streambuf_type* __sb = this->rdbuf();
    516               int_type __c = __sb->sgetc();
    517 
    518 	      // See comment above.
    519 	      bool __large_ignore = false;
    520 	      while (true)
    521 		{
    522 		  while (_M_gcount < __n
    523 			 && !traits_type::eq_int_type(__c, __eof)
    524 			 && !traits_type::eq_int_type(__c, __delim))
    525 		    {
    526 		      ++_M_gcount;
    527 		      __c = __sb->snextc();
    528 		    }
    529 		  if (__n == __gnu_cxx::__numeric_traits<streamsize>::__max
    530 		      && !traits_type::eq_int_type(__c, __eof)
    531 		      && !traits_type::eq_int_type(__c, __delim))
    532 		    {
    533 		      _M_gcount =
    534 			__gnu_cxx::__numeric_traits<streamsize>::__min;
    535 		      __large_ignore = true;
    536 		    }
    537 		  else
    538 		    break;
    539 		}
    540 
    541 	      if (__large_ignore)
    542 		_M_gcount = __gnu_cxx::__numeric_traits<streamsize>::__max;
    543 
    544               if (traits_type::eq_int_type(__c, __eof))
    545                 __err |= ios_base::eofbit;
    546 	      else if (traits_type::eq_int_type(__c, __delim))
    547 		{
    548 		  if (_M_gcount
    549 		      < __gnu_cxx::__numeric_traits<streamsize>::__max)
    550 		    ++_M_gcount;
    551 		  __sb->sbumpc();
    552 		}
    553             }
    554 	  __catch(__cxxabiv1::__forced_unwind&)
    555 	    {
    556 	      this->_M_setstate(ios_base::badbit);
    557 	      __throw_exception_again;
    558 	    }
    559           __catch(...)
    560             { this->_M_setstate(ios_base::badbit); }
    561           if (__err)
    562             this->setstate(__err);
    563         }
    564       return *this;
    565     }
    566 
    567   template<typename _CharT, typename _Traits>
    568     typename basic_istream<_CharT, _Traits>::int_type
    569     basic_istream<_CharT, _Traits>::
    570     peek(void)
    571     {
    572       int_type __c = traits_type::eof();
    573       _M_gcount = 0;
    574       sentry __cerb(*this, true);
    575       if (__cerb)
    576 	{
    577 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    578 	  __try
    579 	    {
    580 	      __c = this->rdbuf()->sgetc();
    581 	      if (traits_type::eq_int_type(__c, traits_type::eof()))
    582 		__err |= ios_base::eofbit;
    583 	    }
    584 	  __catch(__cxxabiv1::__forced_unwind&)
    585 	    {
    586 	      this->_M_setstate(ios_base::badbit);
    587 	      __throw_exception_again;
    588 	    }
    589 	  __catch(...)
    590 	    { this->_M_setstate(ios_base::badbit); }
    591 	  if (__err)
    592 	    this->setstate(__err);
    593 	}
    594       return __c;
    595     }
    596 
    597   template<typename _CharT, typename _Traits>
    598     basic_istream<_CharT, _Traits>&
    599     basic_istream<_CharT, _Traits>::
    600     read(char_type* __s, streamsize __n)
    601     {
    602       _M_gcount = 0;
    603       sentry __cerb(*this, true);
    604       if (__cerb)
    605 	{
    606 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    607 	  __try
    608 	    {
    609 	      _M_gcount = this->rdbuf()->sgetn(__s, __n);
    610 	      if (_M_gcount != __n)
    611 		__err |= (ios_base::eofbit | ios_base::failbit);
    612 	    }
    613 	  __catch(__cxxabiv1::__forced_unwind&)
    614 	    {
    615 	      this->_M_setstate(ios_base::badbit);
    616 	      __throw_exception_again;
    617 	    }
    618 	  __catch(...)
    619 	    { this->_M_setstate(ios_base::badbit); }
    620 	  if (__err)
    621 	    this->setstate(__err);
    622 	}
    623       return *this;
    624     }
    625 
    626   template<typename _CharT, typename _Traits>
    627     streamsize
    628     basic_istream<_CharT, _Traits>::
    629     readsome(char_type* __s, streamsize __n)
    630     {
    631       _M_gcount = 0;
    632       sentry __cerb(*this, true);
    633       if (__cerb)
    634 	{
    635 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    636 	  __try
    637 	    {
    638 	      // Cannot compare int_type with streamsize generically.
    639 	      const streamsize __num = this->rdbuf()->in_avail();
    640 	      if (__num > 0)
    641 		_M_gcount = this->rdbuf()->sgetn(__s, std::min(__num, __n));
    642 	      else if (__num == -1)
    643 		__err |= ios_base::eofbit;
    644 	    }
    645 	  __catch(__cxxabiv1::__forced_unwind&)
    646 	    {
    647 	      this->_M_setstate(ios_base::badbit);
    648 	      __throw_exception_again;
    649 	    }
    650 	  __catch(...)
    651 	    { this->_M_setstate(ios_base::badbit); }
    652 	  if (__err)
    653 	    this->setstate(__err);
    654 	}
    655       return _M_gcount;
    656     }
    657 
    658   template<typename _CharT, typename _Traits>
    659     basic_istream<_CharT, _Traits>&
    660     basic_istream<_CharT, _Traits>::
    661     putback(char_type __c)
    662     {
    663       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    664       // 60. What is a formatted input function?
    665       _M_gcount = 0;
    666       sentry __cerb(*this, true);
    667       if (__cerb)
    668 	{
    669 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    670 	  __try
    671 	    {
    672 	      const int_type __eof = traits_type::eof();
    673 	      __streambuf_type* __sb = this->rdbuf();
    674 	      if (!__sb
    675 		  || traits_type::eq_int_type(__sb->sputbackc(__c), __eof))
    676 		__err |= ios_base::badbit;
    677 	    }
    678 	  __catch(__cxxabiv1::__forced_unwind&)
    679 	    {
    680 	      this->_M_setstate(ios_base::badbit);
    681 	      __throw_exception_again;
    682 	    }
    683 	  __catch(...)
    684 	    { this->_M_setstate(ios_base::badbit); }
    685 	  if (__err)
    686 	    this->setstate(__err);
    687 	}
    688       return *this;
    689     }
    690 
    691   template<typename _CharT, typename _Traits>
    692     basic_istream<_CharT, _Traits>&
    693     basic_istream<_CharT, _Traits>::
    694     unget(void)
    695     {
    696       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    697       // 60. What is a formatted input function?
    698       _M_gcount = 0;
    699       sentry __cerb(*this, true);
    700       if (__cerb)
    701 	{
    702 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    703 	  __try
    704 	    {
    705 	      const int_type __eof = traits_type::eof();
    706 	      __streambuf_type* __sb = this->rdbuf();
    707 	      if (!__sb
    708 		  || traits_type::eq_int_type(__sb->sungetc(), __eof))
    709 		__err |= ios_base::badbit;
    710 	    }
    711 	  __catch(__cxxabiv1::__forced_unwind&)
    712 	    {
    713 	      this->_M_setstate(ios_base::badbit);
    714 	      __throw_exception_again;
    715 	    }
    716 	  __catch(...)
    717 	    { this->_M_setstate(ios_base::badbit); }
    718 	  if (__err)
    719 	    this->setstate(__err);
    720 	}
    721       return *this;
    722     }
    723 
    724   template<typename _CharT, typename _Traits>
    725     int
    726     basic_istream<_CharT, _Traits>::
    727     sync(void)
    728     {
    729       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    730       // DR60.  Do not change _M_gcount.
    731       int __ret = -1;
    732       sentry __cerb(*this, true);
    733       if (__cerb)
    734 	{
    735 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    736 	  __try
    737 	    {
    738 	      __streambuf_type* __sb = this->rdbuf();
    739 	      if (__sb)
    740 		{
    741 		  if (__sb->pubsync() == -1)
    742 		    __err |= ios_base::badbit;
    743 		  else
    744 		    __ret = 0;
    745 		}
    746 	    }
    747 	  __catch(__cxxabiv1::__forced_unwind&)
    748 	    {
    749 	      this->_M_setstate(ios_base::badbit);
    750 	      __throw_exception_again;
    751 	    }
    752 	  __catch(...)
    753 	    { this->_M_setstate(ios_base::badbit); }
    754 	  if (__err)
    755 	    this->setstate(__err);
    756 	}
    757       return __ret;
    758     }
    759 
    760   template<typename _CharT, typename _Traits>
    761     typename basic_istream<_CharT, _Traits>::pos_type
    762     basic_istream<_CharT, _Traits>::
    763     tellg(void)
    764     {
    765       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    766       // DR60.  Do not change _M_gcount.
    767       pos_type __ret = pos_type(-1);
    768       __try
    769 	{
    770 	  if (!this->fail())
    771 	    __ret = this->rdbuf()->pubseekoff(0, ios_base::cur,
    772 					      ios_base::in);
    773 	}
    774       __catch(__cxxabiv1::__forced_unwind&)
    775 	{
    776 	  this->_M_setstate(ios_base::badbit);
    777 	  __throw_exception_again;
    778 	}
    779       __catch(...)
    780 	{ this->_M_setstate(ios_base::badbit); }
    781       return __ret;
    782     }
    783 
    784   template<typename _CharT, typename _Traits>
    785     basic_istream<_CharT, _Traits>&
    786     basic_istream<_CharT, _Traits>::
    787     seekg(pos_type __pos)
    788     {
    789       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    790       // DR60.  Do not change _M_gcount.
    791       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    792       __try
    793 	{
    794 	  if (!this->fail())
    795 	    {
    796 	      // 136.  seekp, seekg setting wrong streams?
    797 	      const pos_type __p = this->rdbuf()->pubseekpos(__pos,
    798 							     ios_base::in);
    799 	      
    800 	      // 129.  Need error indication from seekp() and seekg()
    801 	      if (__p == pos_type(off_type(-1)))
    802 		__err |= ios_base::failbit;
    803 	    }
    804 	}
    805       __catch(__cxxabiv1::__forced_unwind&)
    806 	{
    807 	  this->_M_setstate(ios_base::badbit);
    808 	  __throw_exception_again;
    809 	}
    810       __catch(...)
    811 	{ this->_M_setstate(ios_base::badbit); }
    812       if (__err)
    813 	this->setstate(__err);
    814       return *this;
    815     }
    816 
    817   template<typename _CharT, typename _Traits>
    818     basic_istream<_CharT, _Traits>&
    819     basic_istream<_CharT, _Traits>::
    820     seekg(off_type __off, ios_base::seekdir __dir)
    821     {
    822       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    823       // DR60.  Do not change _M_gcount.
    824       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    825       __try
    826 	{
    827 	  if (!this->fail())
    828 	    {
    829 	      // 136.  seekp, seekg setting wrong streams?
    830 	      const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
    831 							     ios_base::in);
    832 	      
    833 	      // 129.  Need error indication from seekp() and seekg()
    834 	      if (__p == pos_type(off_type(-1)))
    835 		__err |= ios_base::failbit;
    836 	    }
    837 	}
    838       __catch(__cxxabiv1::__forced_unwind&)
    839 	{
    840 	  this->_M_setstate(ios_base::badbit);
    841 	  __throw_exception_again;
    842 	}
    843       __catch(...)
    844 	{ this->_M_setstate(ios_base::badbit); }
    845       if (__err)
    846 	this->setstate(__err);
    847       return *this;
    848     }
    849 
    850   // 27.6.1.2.3 Character extraction templates
    851   template<typename _CharT, typename _Traits>
    852     basic_istream<_CharT, _Traits>&
    853     operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c)
    854     {
    855       typedef basic_istream<_CharT, _Traits>		__istream_type;
    856       typedef typename __istream_type::int_type         __int_type;
    857 
    858       typename __istream_type::sentry __cerb(__in, false);
    859       if (__cerb)
    860 	{
    861 	  ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    862 	  __try
    863 	    {
    864 	      const __int_type __cb = __in.rdbuf()->sbumpc();
    865 	      if (!_Traits::eq_int_type(__cb, _Traits::eof()))
    866 		__c = _Traits::to_char_type(__cb);
    867 	      else
    868 		__err |= (ios_base::eofbit | ios_base::failbit);
    869 	    }
    870 	  __catch(__cxxabiv1::__forced_unwind&)
    871 	    {
    872 	      __in._M_setstate(ios_base::badbit);
    873 	      __throw_exception_again;
    874 	    }
    875 	  __catch(...)
    876 	    { __in._M_setstate(ios_base::badbit); }
    877 	  if (__err)
    878 	    __in.setstate(__err);
    879 	}
    880       return __in;
    881     }
    882 
    883   template<typename _CharT, typename _Traits>
    884     basic_istream<_CharT, _Traits>&
    885     operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s)
    886     {
    887       typedef basic_istream<_CharT, _Traits>		__istream_type;
    888       typedef basic_streambuf<_CharT, _Traits>          __streambuf_type;
    889       typedef typename _Traits::int_type		int_type;
    890       typedef _CharT					char_type;
    891       typedef ctype<_CharT>				__ctype_type;
    892 
    893       streamsize __extracted = 0;
    894       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
    895       typename __istream_type::sentry __cerb(__in, false);
    896       if (__cerb)
    897 	{
    898 	  __try
    899 	    {
    900 	      // Figure out how many characters to extract.
    901 	      streamsize __num = __in.width();
    902 	      if (__num <= 0)
    903 		__num = __gnu_cxx::__numeric_traits<streamsize>::__max;
    904 
    905 	      const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
    906 
    907 	      const int_type __eof = _Traits::eof();
    908 	      __streambuf_type* __sb = __in.rdbuf();
    909 	      int_type __c = __sb->sgetc();
    910 
    911 	      while (__extracted < __num - 1
    912 		     && !_Traits::eq_int_type(__c, __eof)
    913 		     && !__ct.is(ctype_base::space,
    914 				 _Traits::to_char_type(__c)))
    915 		{
    916 		  *__s++ = _Traits::to_char_type(__c);
    917 		  ++__extracted;
    918 		  __c = __sb->snextc();
    919 		}
    920 	      if (_Traits::eq_int_type(__c, __eof))
    921 		__err |= ios_base::eofbit;
    922 
    923 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
    924 	      // 68.  Extractors for char* should store null at end
    925 	      *__s = char_type();
    926 	      __in.width(0);
    927 	    }
    928 	  __catch(__cxxabiv1::__forced_unwind&)
    929 	    {
    930 	      __in._M_setstate(ios_base::badbit);
    931 	      __throw_exception_again;
    932 	    }
    933 	  __catch(...)
    934 	    { __in._M_setstate(ios_base::badbit); }
    935 	}
    936       if (!__extracted)
    937 	__err |= ios_base::failbit;
    938       if (__err)
    939 	__in.setstate(__err);
    940       return __in;
    941     }
    942 
    943   // 27.6.1.4 Standard basic_istream manipulators
    944   template<typename _CharT, typename _Traits>
    945     basic_istream<_CharT, _Traits>&
    946     ws(basic_istream<_CharT, _Traits>& __in)
    947     {
    948       typedef basic_istream<_CharT, _Traits>		__istream_type;
    949       typedef basic_streambuf<_CharT, _Traits>          __streambuf_type;
    950       typedef typename __istream_type::int_type		__int_type;
    951       typedef ctype<_CharT>				__ctype_type;
    952 
    953       const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
    954       const __int_type __eof = _Traits::eof();
    955       __streambuf_type* __sb = __in.rdbuf();
    956       __int_type __c = __sb->sgetc();
    957 
    958       while (!_Traits::eq_int_type(__c, __eof)
    959 	     && __ct.is(ctype_base::space, _Traits::to_char_type(__c)))
    960 	__c = __sb->snextc();
    961 
    962        if (_Traits::eq_int_type(__c, __eof))
    963 	 __in.setstate(ios_base::eofbit);
    964       return __in;
    965     }
    966 
    967   // Inhibit implicit instantiations for required instantiations,
    968   // which are defined via explicit instantiations elsewhere.
    969   // NB:  This syntax is a GNU extension.
    970 #if _GLIBCXX_EXTERN_TEMPLATE
    971   extern template class basic_istream<char>;
    972   extern template istream& ws(istream&);
    973   extern template istream& operator>>(istream&, char&);
    974   extern template istream& operator>>(istream&, char*);
    975   extern template istream& operator>>(istream&, unsigned char&);
    976   extern template istream& operator>>(istream&, signed char&);
    977   extern template istream& operator>>(istream&, unsigned char*);
    978   extern template istream& operator>>(istream&, signed char*);
    979 
    980   extern template istream& istream::_M_extract(unsigned short&);
    981   extern template istream& istream::_M_extract(unsigned int&);  
    982   extern template istream& istream::_M_extract(long&);
    983   extern template istream& istream::_M_extract(unsigned long&);
    984   extern template istream& istream::_M_extract(bool&);
    985 #ifdef _GLIBCXX_USE_LONG_LONG
    986   extern template istream& istream::_M_extract(long long&);
    987   extern template istream& istream::_M_extract(unsigned long long&);
    988 #endif
    989   extern template istream& istream::_M_extract(float&);
    990   extern template istream& istream::_M_extract(double&);
    991   extern template istream& istream::_M_extract(long double&);
    992   extern template istream& istream::_M_extract(void*&);
    993 
    994   extern template class basic_iostream<char>;
    995 
    996 #ifdef _GLIBCXX_USE_WCHAR_T
    997   extern template class basic_istream<wchar_t>;
    998   extern template wistream& ws(wistream&);
    999   extern template wistream& operator>>(wistream&, wchar_t&);
   1000   extern template wistream& operator>>(wistream&, wchar_t*);
   1001 
   1002   extern template wistream& wistream::_M_extract(unsigned short&);
   1003   extern template wistream& wistream::_M_extract(unsigned int&);  
   1004   extern template wistream& wistream::_M_extract(long&);
   1005   extern template wistream& wistream::_M_extract(unsigned long&);
   1006   extern template wistream& wistream::_M_extract(bool&);
   1007 #ifdef _GLIBCXX_USE_LONG_LONG
   1008   extern template wistream& wistream::_M_extract(long long&);
   1009   extern template wistream& wistream::_M_extract(unsigned long long&);
   1010 #endif
   1011   extern template wistream& wistream::_M_extract(float&);
   1012   extern template wistream& wistream::_M_extract(double&);
   1013   extern template wistream& wistream::_M_extract(long double&);
   1014   extern template wistream& wistream::_M_extract(void*&);
   1015 
   1016   extern template class basic_iostream<wchar_t>;
   1017 #endif
   1018 #endif
   1019 
   1020 _GLIBCXX_END_NAMESPACE
   1021 
   1022 #endif
   1023