istream.tcc

Go to the documentation of this file.
00001 // istream classes -*- C++ -*-
00002 
00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
00004 // 2006, 2007
00005 // Free Software Foundation, Inc.
00006 //
00007 // This file is part of the GNU ISO C++ Library.  This library is free
00008 // software; you can redistribute it and/or modify it under the
00009 // terms of the GNU General Public License as published by the
00010 // Free Software Foundation; either version 2, or (at your option)
00011 // any later version.
00012 
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 
00018 // You should have received a copy of the GNU General Public License along
00019 // with this library; see the file COPYING.  If not, write to the Free
00020 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00021 // USA.
00022 
00023 // As a special exception, you may use this file as part of a free software
00024 // library without restriction.  Specifically, if other files instantiate
00025 // templates or use macros or inline functions from this file, or you compile
00026 // this file and link it with other files to produce an executable, this
00027 // file does not by itself cause the resulting executable to be covered by
00028 // the GNU General Public License.  This exception does not however
00029 // invalidate any other reasons why the executable file might be covered by
00030 // the GNU General Public License.
00031 
00032 /** @file istream.tcc
00033  *  This is an internal header file, included by other library headers.
00034  *  You should not attempt to use it directly.
00035  */
00036 
00037 //
00038 // ISO C++ 14882: 27.6.1  Input streams
00039 //
00040 
00041 #ifndef _ISTREAM_TCC
00042 #define _ISTREAM_TCC 1
00043 
00044 #pragma GCC system_header
00045 
00046 #include <locale>
00047 #include <ostream> // For flush()
00048 
00049 _GLIBCXX_BEGIN_NAMESPACE(std)
00050 
00051   template<typename _CharT, typename _Traits>
00052     basic_istream<_CharT, _Traits>::sentry::
00053     sentry(basic_istream<_CharT, _Traits>& __in, bool __noskip) : _M_ok(false)
00054     {
00055       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00056       if (__in.good())
00057     {
00058       if (__in.tie())
00059         __in.tie()->flush();
00060       if (!__noskip && (__in.flags() & ios_base::skipws))
00061         {
00062           const __int_type __eof = traits_type::eof();
00063           __streambuf_type* __sb = __in.rdbuf();
00064           __int_type __c = __sb->sgetc();
00065 
00066           const __ctype_type& __ct = __check_facet(__in._M_ctype);
00067           while (!traits_type::eq_int_type(__c, __eof)
00068              && __ct.is(ctype_base::space, 
00069                 traits_type::to_char_type(__c)))
00070         __c = __sb->snextc();
00071 
00072           // _GLIBCXX_RESOLVE_LIB_DEFECTS
00073           // 195. Should basic_istream::sentry's constructor ever
00074           // set eofbit?
00075           if (traits_type::eq_int_type(__c, __eof))
00076         __err |= ios_base::eofbit;
00077         }
00078     }
00079 
00080       if (__in.good() && __err == ios_base::goodbit)
00081     _M_ok = true;
00082       else
00083     {
00084       __err |= ios_base::failbit;
00085       __in.setstate(__err);
00086     }
00087     }
00088 
00089   template<typename _CharT, typename _Traits>
00090     template<typename _ValueT>
00091       basic_istream<_CharT, _Traits>&
00092       basic_istream<_CharT, _Traits>::
00093       _M_extract(_ValueT& __v)
00094       {
00095     sentry __cerb(*this, false);
00096     if (__cerb)
00097       {
00098         ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00099         try
00100           {
00101         const __num_get_type& __ng = __check_facet(this->_M_num_get);
00102         __ng.get(*this, 0, *this, __err, __v);
00103           }
00104         catch(...)
00105           { this->_M_setstate(ios_base::badbit); }
00106         if (__err)
00107           this->setstate(__err);
00108       }
00109     return *this;
00110       }
00111 
00112   template<typename _CharT, typename _Traits>
00113     basic_istream<_CharT, _Traits>&
00114     basic_istream<_CharT, _Traits>::
00115     operator>>(short& __n)
00116     {
00117       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00118       // 118. basic_istream uses nonexistent num_get member functions.
00119       long __l;
00120       _M_extract(__l);
00121       if (!this->fail())
00122     {
00123       if (numeric_limits<short>::min() <= __l
00124           && __l <= numeric_limits<short>::max())
00125         __n = __l;
00126       else
00127         this->setstate(ios_base::failbit);
00128     }
00129       return *this;
00130     }
00131     
00132   template<typename _CharT, typename _Traits>
00133     basic_istream<_CharT, _Traits>&
00134     basic_istream<_CharT, _Traits>::
00135     operator>>(int& __n)
00136     {
00137       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00138       // 118. basic_istream uses nonexistent num_get member functions.
00139       long __l;
00140       _M_extract(__l);
00141       if (!this->fail())
00142     {
00143       if (numeric_limits<int>::min() <= __l
00144           && __l <= numeric_limits<int>::max())
00145         __n = __l;
00146       else
00147         this->setstate(ios_base::failbit);
00148     }
00149       return *this;
00150     }
00151 
00152   template<typename _CharT, typename _Traits>
00153     basic_istream<_CharT, _Traits>&
00154     basic_istream<_CharT, _Traits>::
00155     operator>>(__streambuf_type* __sbout)
00156     {
00157       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00158       sentry __cerb(*this, false);
00159       if (__cerb && __sbout)
00160     {
00161       try
00162         {
00163           bool __ineof;
00164           if (!__copy_streambufs_eof(this->rdbuf(), __sbout, __ineof))
00165         __err |= ios_base::failbit;
00166           if (__ineof)
00167         __err |= ios_base::eofbit;
00168         }
00169       catch(...)
00170         { this->_M_setstate(ios_base::failbit); }
00171     }
00172       else if (!__sbout)
00173     __err |= ios_base::failbit;
00174       if (__err)
00175     this->setstate(__err);
00176       return *this;
00177     }
00178 
00179   template<typename _CharT, typename _Traits>
00180     typename basic_istream<_CharT, _Traits>::int_type
00181     basic_istream<_CharT, _Traits>::
00182     get(void)
00183     {
00184       const int_type __eof = traits_type::eof();
00185       int_type __c = __eof;
00186       _M_gcount = 0;
00187       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00188       sentry __cerb(*this, true);
00189       if (__cerb)
00190     {
00191       try
00192         {
00193           __c = this->rdbuf()->sbumpc();
00194           // 27.6.1.1 paragraph 3
00195           if (!traits_type::eq_int_type(__c, __eof))
00196         _M_gcount = 1;
00197           else
00198         __err |= ios_base::eofbit;
00199         }
00200       catch(...)
00201         { this->_M_setstate(ios_base::badbit); }
00202     }
00203       if (!_M_gcount)
00204     __err |= ios_base::failbit;
00205       if (__err)
00206     this->setstate(__err);
00207       return __c;
00208     }
00209 
00210   template<typename _CharT, typename _Traits>
00211     basic_istream<_CharT, _Traits>&
00212     basic_istream<_CharT, _Traits>::
00213     get(char_type& __c)
00214     {
00215       _M_gcount = 0;
00216       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00217       sentry __cerb(*this, true);
00218       if (__cerb)
00219     {
00220       try
00221         {
00222           const int_type __cb = this->rdbuf()->sbumpc();
00223           // 27.6.1.1 paragraph 3
00224           if (!traits_type::eq_int_type(__cb, traits_type::eof()))
00225         {
00226           _M_gcount = 1;
00227           __c = traits_type::to_char_type(__cb);
00228         }
00229           else
00230         __err |= ios_base::eofbit;
00231         }
00232       catch(...)
00233         { this->_M_setstate(ios_base::badbit); }
00234     }
00235       if (!_M_gcount)
00236     __err |= ios_base::failbit;
00237       if (__err)
00238     this->setstate(__err);
00239       return *this;
00240     }
00241 
00242   template<typename _CharT, typename _Traits>
00243     basic_istream<_CharT, _Traits>&
00244     basic_istream<_CharT, _Traits>::
00245     get(char_type* __s, streamsize __n, char_type __delim)
00246     {
00247       _M_gcount = 0;
00248       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00249       sentry __cerb(*this, true);
00250       if (__cerb)
00251     {
00252       try
00253         {
00254           const int_type __idelim = traits_type::to_int_type(__delim);
00255           const int_type __eof = traits_type::eof();
00256           __streambuf_type* __sb = this->rdbuf();
00257           int_type __c = __sb->sgetc();
00258 
00259           while (_M_gcount + 1 < __n
00260              && !traits_type::eq_int_type(__c, __eof)
00261              && !traits_type::eq_int_type(__c, __idelim))
00262         {
00263           *__s++ = traits_type::to_char_type(__c);
00264           ++_M_gcount;
00265           __c = __sb->snextc();
00266         }
00267           if (traits_type::eq_int_type(__c, __eof))
00268         __err |= ios_base::eofbit;
00269         }
00270       catch(...)
00271         { this->_M_setstate(ios_base::badbit); }
00272     }
00273       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00274       // 243. get and getline when sentry reports failure.
00275       if (__n > 0)
00276     *__s = char_type();
00277       if (!_M_gcount)
00278     __err |= ios_base::failbit;
00279       if (__err)
00280     this->setstate(__err);
00281       return *this;
00282     }
00283 
00284   template<typename _CharT, typename _Traits>
00285     basic_istream<_CharT, _Traits>&
00286     basic_istream<_CharT, _Traits>::
00287     get(__streambuf_type& __sb, char_type __delim)
00288     {
00289       _M_gcount = 0;
00290       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00291       sentry __cerb(*this, true);
00292       if (__cerb)
00293     {
00294       try
00295         {
00296           const int_type __idelim = traits_type::to_int_type(__delim);
00297           const int_type __eof = traits_type::eof();
00298           __streambuf_type* __this_sb = this->rdbuf();
00299           int_type __c = __this_sb->sgetc();
00300           char_type __c2 = traits_type::to_char_type(__c);
00301 
00302           while (!traits_type::eq_int_type(__c, __eof)
00303              && !traits_type::eq_int_type(__c, __idelim)
00304              && !traits_type::eq_int_type(__sb.sputc(__c2), __eof))
00305         {
00306           ++_M_gcount;
00307           __c = __this_sb->snextc();
00308           __c2 = traits_type::to_char_type(__c);
00309         }
00310           if (traits_type::eq_int_type(__c, __eof))
00311         __err |= ios_base::eofbit;
00312         }
00313       catch(...)
00314         { this->_M_setstate(ios_base::badbit); }
00315     }
00316       if (!_M_gcount)
00317     __err |= ios_base::failbit;
00318       if (__err)
00319     this->setstate(__err);
00320       return *this;
00321     }
00322 
00323   template<typename _CharT, typename _Traits>
00324     basic_istream<_CharT, _Traits>&
00325     basic_istream<_CharT, _Traits>::
00326     getline(char_type* __s, streamsize __n, char_type __delim)
00327     {
00328       _M_gcount = 0;
00329       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00330       sentry __cerb(*this, true);
00331       if (__cerb)
00332         {
00333           try
00334             {
00335               const int_type __idelim = traits_type::to_int_type(__delim);
00336               const int_type __eof = traits_type::eof();
00337               __streambuf_type* __sb = this->rdbuf();
00338               int_type __c = __sb->sgetc();
00339 
00340               while (_M_gcount + 1 < __n
00341                      && !traits_type::eq_int_type(__c, __eof)
00342                      && !traits_type::eq_int_type(__c, __idelim))
00343                 {
00344                   *__s++ = traits_type::to_char_type(__c);
00345                   __c = __sb->snextc();
00346                   ++_M_gcount;
00347                 }
00348               if (traits_type::eq_int_type(__c, __eof))
00349                 __err |= ios_base::eofbit;
00350               else
00351                 {
00352                   if (traits_type::eq_int_type(__c, __idelim))
00353                     {
00354                       __sb->sbumpc();
00355                       ++_M_gcount;
00356                     }
00357                   else
00358                     __err |= ios_base::failbit;
00359                 }
00360             }
00361           catch(...)
00362             { this->_M_setstate(ios_base::badbit); }
00363         }
00364       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00365       // 243. get and getline when sentry reports failure.
00366       if (__n > 0)
00367     *__s = char_type();
00368       if (!_M_gcount)
00369         __err |= ios_base::failbit;
00370       if (__err)
00371         this->setstate(__err);
00372       return *this;
00373     }
00374 
00375   // We provide three overloads, since the first two are much simpler
00376   // than the general case. Also, the latter two can thus adopt the
00377   // same "batchy" strategy used by getline above.
00378   template<typename _CharT, typename _Traits>
00379     basic_istream<_CharT, _Traits>&
00380     basic_istream<_CharT, _Traits>::
00381     ignore(void)
00382     {
00383       _M_gcount = 0;
00384       sentry __cerb(*this, true);
00385       if (__cerb)
00386     {
00387       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00388       try
00389         {
00390           const int_type __eof = traits_type::eof();
00391           __streambuf_type* __sb = this->rdbuf();
00392 
00393           if (traits_type::eq_int_type(__sb->sbumpc(), __eof))
00394         __err |= ios_base::eofbit;
00395           else
00396         _M_gcount = 1;
00397         }
00398       catch(...)
00399         { this->_M_setstate(ios_base::badbit); }
00400       if (__err)
00401         this->setstate(__err);
00402     }
00403       return *this;
00404     }
00405 
00406   template<typename _CharT, typename _Traits>
00407     basic_istream<_CharT, _Traits>&
00408     basic_istream<_CharT, _Traits>::
00409     ignore(streamsize __n)
00410     {
00411       _M_gcount = 0;
00412       sentry __cerb(*this, true);
00413       if (__cerb && __n > 0)
00414         {
00415           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00416           try
00417             {
00418               const int_type __eof = traits_type::eof();
00419               __streambuf_type* __sb = this->rdbuf();
00420               int_type __c = __sb->sgetc();
00421 
00422           // N.B. On LFS-enabled platforms streamsize is still 32 bits
00423           // wide: if we want to implement the standard mandated behavior
00424           // for n == max() (see 27.6.1.3/24) we are at risk of signed
00425           // integer overflow: thus these contortions. Also note that,
00426           // by definition, when more than 2G chars are actually ignored,
00427           // _M_gcount (the return value of gcount, that is) cannot be
00428           // really correct, being unavoidably too small.
00429           bool __large_ignore = false;
00430           while (true)
00431         {
00432           while (_M_gcount < __n
00433              && !traits_type::eq_int_type(__c, __eof))
00434             {
00435               ++_M_gcount;
00436               __c = __sb->snextc();
00437             }
00438           if (__n == numeric_limits<streamsize>::max()
00439               && !traits_type::eq_int_type(__c, __eof))
00440             {
00441               _M_gcount = numeric_limits<streamsize>::min();
00442               __large_ignore = true;
00443             }
00444           else
00445             break;
00446         }
00447 
00448           if (__large_ignore)
00449         _M_gcount = numeric_limits<streamsize>::max();
00450 
00451           if (traits_type::eq_int_type(__c, __eof))
00452                 __err |= ios_base::eofbit;
00453             }
00454           catch(...)
00455             { this->_M_setstate(ios_base::badbit); }
00456           if (__err)
00457             this->setstate(__err);
00458         }
00459       return *this;
00460     }
00461 
00462   template<typename _CharT, typename _Traits>
00463     basic_istream<_CharT, _Traits>&
00464     basic_istream<_CharT, _Traits>::
00465     ignore(streamsize __n, int_type __delim)
00466     {
00467       _M_gcount = 0;
00468       sentry __cerb(*this, true);
00469       if (__cerb && __n > 0)
00470         {
00471           ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00472           try
00473             {
00474               const int_type __eof = traits_type::eof();
00475               __streambuf_type* __sb = this->rdbuf();
00476               int_type __c = __sb->sgetc();
00477 
00478           // See comment above.
00479           bool __large_ignore = false;
00480           while (true)
00481         {
00482           while (_M_gcount < __n
00483              && !traits_type::eq_int_type(__c, __eof)
00484              && !traits_type::eq_int_type(__c, __delim))
00485             {
00486               ++_M_gcount;
00487               __c = __sb->snextc();
00488             }
00489           if (__n == numeric_limits<streamsize>::max()
00490               && !traits_type::eq_int_type(__c, __eof)
00491               && !traits_type::eq_int_type(__c, __delim))
00492             {
00493               _M_gcount = numeric_limits<streamsize>::min();
00494               __large_ignore = true;
00495             }
00496           else
00497             break;
00498         }
00499 
00500           if (__large_ignore)
00501         _M_gcount = numeric_limits<streamsize>::max();
00502 
00503               if (traits_type::eq_int_type(__c, __eof))
00504                 __err |= ios_base::eofbit;
00505           else if (traits_type::eq_int_type(__c, __delim))
00506         {
00507           if (_M_gcount < numeric_limits<streamsize>::max())
00508             ++_M_gcount;
00509           __sb->sbumpc();
00510         }
00511             }
00512           catch(...)
00513             { this->_M_setstate(ios_base::badbit); }
00514           if (__err)
00515             this->setstate(__err);
00516         }
00517       return *this;
00518     }
00519 
00520   template<typename _CharT, typename _Traits>
00521     typename basic_istream<_CharT, _Traits>::int_type
00522     basic_istream<_CharT, _Traits>::
00523     peek(void)
00524     {
00525       int_type __c = traits_type::eof();
00526       _M_gcount = 0;
00527       sentry __cerb(*this, true);
00528       if (__cerb)
00529     {
00530       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00531       try
00532         {
00533           __c = this->rdbuf()->sgetc();
00534           if (traits_type::eq_int_type(__c, traits_type::eof()))
00535         __err |= ios_base::eofbit;
00536         }
00537       catch(...)
00538         { this->_M_setstate(ios_base::badbit); }
00539       if (__err)
00540         this->setstate(__err);
00541     }
00542       return __c;
00543     }
00544 
00545   template<typename _CharT, typename _Traits>
00546     basic_istream<_CharT, _Traits>&
00547     basic_istream<_CharT, _Traits>::
00548     read(char_type* __s, streamsize __n)
00549     {
00550       _M_gcount = 0;
00551       sentry __cerb(*this, true);
00552       if (__cerb)
00553     {
00554       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00555       try
00556         {
00557           _M_gcount = this->rdbuf()->sgetn(__s, __n);
00558           if (_M_gcount != __n)
00559         __err |= (ios_base::eofbit | ios_base::failbit);
00560         }
00561       catch(...)
00562         { this->_M_setstate(ios_base::badbit); }
00563       if (__err)
00564         this->setstate(__err);
00565     }
00566       return *this;
00567     }
00568 
00569   template<typename _CharT, typename _Traits>
00570     streamsize
00571     basic_istream<_CharT, _Traits>::
00572     readsome(char_type* __s, streamsize __n)
00573     {
00574       _M_gcount = 0;
00575       sentry __cerb(*this, true);
00576       if (__cerb)
00577     {
00578       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00579       try
00580         {
00581           // Cannot compare int_type with streamsize generically.
00582           const streamsize __num = this->rdbuf()->in_avail();
00583           if (__num > 0)
00584         _M_gcount = this->rdbuf()->sgetn(__s, std::min(__num, __n));
00585           else if (__num == -1)
00586         __err |= ios_base::eofbit;
00587         }
00588       catch(...)
00589         { this->_M_setstate(ios_base::badbit); }
00590       if (__err)
00591         this->setstate(__err);
00592     }
00593       return _M_gcount;
00594     }
00595 
00596   template<typename _CharT, typename _Traits>
00597     basic_istream<_CharT, _Traits>&
00598     basic_istream<_CharT, _Traits>::
00599     putback(char_type __c)
00600     {
00601       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00602       // 60. What is a formatted input function?
00603       _M_gcount = 0;
00604       sentry __cerb(*this, true);
00605       if (__cerb)
00606     {
00607       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00608       try
00609         {
00610           const int_type __eof = traits_type::eof();
00611           __streambuf_type* __sb = this->rdbuf();
00612           if (!__sb
00613           || traits_type::eq_int_type(__sb->sputbackc(__c), __eof))
00614         __err |= ios_base::badbit;
00615         }
00616       catch(...)
00617         { this->_M_setstate(ios_base::badbit); }
00618       if (__err)
00619         this->setstate(__err);
00620     }
00621       return *this;
00622     }
00623 
00624   template<typename _CharT, typename _Traits>
00625     basic_istream<_CharT, _Traits>&
00626     basic_istream<_CharT, _Traits>::
00627     unget(void)
00628     {
00629       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00630       // 60. What is a formatted input function?
00631       _M_gcount = 0;
00632       sentry __cerb(*this, true);
00633       if (__cerb)
00634     {
00635       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00636       try
00637         {
00638           const int_type __eof = traits_type::eof();
00639           __streambuf_type* __sb = this->rdbuf();
00640           if (!__sb
00641           || traits_type::eq_int_type(__sb->sungetc(), __eof))
00642         __err |= ios_base::badbit;
00643         }
00644       catch(...)
00645         { this->_M_setstate(ios_base::badbit); }
00646       if (__err)
00647         this->setstate(__err);
00648     }
00649       return *this;
00650     }
00651 
00652   template<typename _CharT, typename _Traits>
00653     int
00654     basic_istream<_CharT, _Traits>::
00655     sync(void)
00656     {
00657       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00658       // DR60.  Do not change _M_gcount.
00659       int __ret = -1;
00660       sentry __cerb(*this, true);
00661       if (__cerb)
00662     {
00663       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00664       try
00665         {
00666           __streambuf_type* __sb = this->rdbuf();
00667           if (__sb)
00668         {
00669           if (__sb->pubsync() == -1)
00670             __err |= ios_base::badbit;
00671           else
00672             __ret = 0;
00673         }
00674         }
00675       catch(...)
00676         { this->_M_setstate(ios_base::badbit); }
00677       if (__err)
00678         this->setstate(__err);
00679     }
00680       return __ret;
00681     }
00682 
00683   template<typename _CharT, typename _Traits>
00684     typename basic_istream<_CharT, _Traits>::pos_type
00685     basic_istream<_CharT, _Traits>::
00686     tellg(void)
00687     {
00688       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00689       // DR60.  Do not change _M_gcount.
00690       pos_type __ret = pos_type(-1);
00691       try
00692     {
00693       if (!this->fail())
00694         __ret = this->rdbuf()->pubseekoff(0, ios_base::cur,
00695                           ios_base::in);
00696     }
00697       catch(...)
00698     { this->_M_setstate(ios_base::badbit); }
00699       return __ret;
00700     }
00701 
00702   template<typename _CharT, typename _Traits>
00703     basic_istream<_CharT, _Traits>&
00704     basic_istream<_CharT, _Traits>::
00705     seekg(pos_type __pos)
00706     {
00707       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00708       // DR60.  Do not change _M_gcount.
00709       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00710       try
00711     {
00712       if (!this->fail())
00713         {
00714           // 136.  seekp, seekg setting wrong streams?
00715           const pos_type __p = this->rdbuf()->pubseekpos(__pos,
00716                                  ios_base::in);
00717           
00718           // 129.  Need error indication from seekp() and seekg()
00719           if (__p == pos_type(off_type(-1)))
00720         __err |= ios_base::failbit;
00721         }
00722     }
00723       catch(...)
00724     { this->_M_setstate(ios_base::badbit); }
00725       if (__err)
00726     this->setstate(__err);
00727       return *this;
00728     }
00729 
00730   template<typename _CharT, typename _Traits>
00731     basic_istream<_CharT, _Traits>&
00732     basic_istream<_CharT, _Traits>::
00733     seekg(off_type __off, ios_base::seekdir __dir)
00734     {
00735       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00736       // DR60.  Do not change _M_gcount.
00737       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00738       try
00739     {
00740       if (!this->fail())
00741         {
00742           // 136.  seekp, seekg setting wrong streams?
00743           const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
00744                                  ios_base::in);
00745           
00746           // 129.  Need error indication from seekp() and seekg()
00747           if (__p == pos_type(off_type(-1)))
00748         __err |= ios_base::failbit;
00749         }
00750     }
00751       catch(...)
00752     { this->_M_setstate(ios_base::badbit); }
00753       if (__err)
00754     this->setstate(__err);
00755       return *this;
00756     }
00757 
00758   // 27.6.1.2.3 Character extraction templates
00759   template<typename _CharT, typename _Traits>
00760     basic_istream<_CharT, _Traits>&
00761     operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c)
00762     {
00763       typedef basic_istream<_CharT, _Traits>        __istream_type;
00764       typedef typename __istream_type::int_type         __int_type;
00765 
00766       typename __istream_type::sentry __cerb(__in, false);
00767       if (__cerb)
00768     {
00769       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00770       try
00771         {
00772           const __int_type __cb = __in.rdbuf()->sbumpc();
00773           if (!_Traits::eq_int_type(__cb, _Traits::eof()))
00774         __c = _Traits::to_char_type(__cb);
00775           else
00776         __err |= (ios_base::eofbit | ios_base::failbit);
00777         }
00778       catch(...)
00779         { __in._M_setstate(ios_base::badbit); }
00780       if (__err)
00781         __in.setstate(__err);
00782     }
00783       return __in;
00784     }
00785 
00786   template<typename _CharT, typename _Traits>
00787     basic_istream<_CharT, _Traits>&
00788     operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s)
00789     {
00790       typedef basic_istream<_CharT, _Traits>        __istream_type;
00791       typedef typename __istream_type::__streambuf_type __streambuf_type;
00792       typedef typename _Traits::int_type        int_type;
00793       typedef _CharT                    char_type;
00794       typedef ctype<_CharT>             __ctype_type;
00795 
00796       streamsize __extracted = 0;
00797       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00798       typename __istream_type::sentry __cerb(__in, false);
00799       if (__cerb)
00800     {
00801       try
00802         {
00803           // Figure out how many characters to extract.
00804           streamsize __num = __in.width();
00805           if (__num <= 0)
00806         __num = numeric_limits<streamsize>::max();
00807 
00808           const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
00809 
00810           const int_type __eof = _Traits::eof();
00811           __streambuf_type* __sb = __in.rdbuf();
00812           int_type __c = __sb->sgetc();
00813 
00814           while (__extracted < __num - 1
00815              && !_Traits::eq_int_type(__c, __eof)
00816              && !__ct.is(ctype_base::space,
00817                  _Traits::to_char_type(__c)))
00818         {
00819           *__s++ = _Traits::to_char_type(__c);
00820           ++__extracted;
00821           __c = __sb->snextc();
00822         }
00823           if (_Traits::eq_int_type(__c, __eof))
00824         __err |= ios_base::eofbit;
00825 
00826           // _GLIBCXX_RESOLVE_LIB_DEFECTS
00827           // 68.  Extractors for char* should store null at end
00828           *__s = char_type();
00829           __in.width(0);
00830         }
00831       catch(...)
00832         { __in._M_setstate(ios_base::badbit); }
00833     }
00834       if (!__extracted)
00835     __err |= ios_base::failbit;
00836       if (__err)
00837     __in.setstate(__err);
00838       return __in;
00839     }
00840 
00841   // 27.6.1.4 Standard basic_istream manipulators
00842   template<typename _CharT, typename _Traits>
00843     basic_istream<_CharT,_Traits>&
00844     ws(basic_istream<_CharT,_Traits>& __in)
00845     {
00846       typedef basic_istream<_CharT, _Traits>        __istream_type;
00847       typedef typename __istream_type::__streambuf_type __streambuf_type;
00848       typedef typename __istream_type::__ctype_type __ctype_type;
00849       typedef typename __istream_type::int_type     __int_type;
00850 
00851       const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
00852       const __int_type __eof = _Traits::eof();
00853       __streambuf_type* __sb = __in.rdbuf();
00854       __int_type __c = __sb->sgetc();
00855 
00856       while (!_Traits::eq_int_type(__c, __eof)
00857          && __ct.is(ctype_base::space, _Traits::to_char_type(__c)))
00858     __c = __sb->snextc();
00859 
00860        if (_Traits::eq_int_type(__c, __eof))
00861      __in.setstate(ios_base::eofbit);
00862       return __in;
00863     }
00864 
00865   // 21.3.7.9 basic_string::getline and operators
00866   template<typename _CharT, typename _Traits, typename _Alloc>
00867     basic_istream<_CharT, _Traits>&
00868     operator>>(basic_istream<_CharT, _Traits>& __in,
00869            basic_string<_CharT, _Traits, _Alloc>& __str)
00870     {
00871       typedef basic_istream<_CharT, _Traits>        __istream_type;
00872       typedef typename __istream_type::int_type     __int_type;
00873       typedef typename __istream_type::__streambuf_type __streambuf_type;
00874       typedef typename __istream_type::__ctype_type __ctype_type;
00875       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
00876       typedef typename __string_type::size_type     __size_type;
00877 
00878       __size_type __extracted = 0;
00879       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00880       typename __istream_type::sentry __cerb(__in, false);
00881       if (__cerb)
00882     {
00883       try
00884         {
00885           // Avoid reallocation for common case.
00886           __str.erase();
00887           _CharT __buf[128];
00888           __size_type __len = 0;          
00889           const streamsize __w = __in.width();
00890           const __size_type __n = __w > 0 ? static_cast<__size_type>(__w)
00891                                       : __str.max_size();
00892           const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc());
00893           const __int_type __eof = _Traits::eof();
00894           __streambuf_type* __sb = __in.rdbuf();
00895           __int_type __c = __sb->sgetc();
00896 
00897           while (__extracted < __n
00898              && !_Traits::eq_int_type(__c, __eof)
00899              && !__ct.is(ctype_base::space, _Traits::to_char_type(__c)))
00900         {
00901           if (__len == sizeof(__buf) / sizeof(_CharT))
00902             {
00903               __str.append(__buf, sizeof(__buf) / sizeof(_CharT));
00904               __len = 0;
00905             }
00906           __buf[__len++] = _Traits::to_char_type(__c);
00907           ++__extracted;
00908           __c = __sb->snextc();
00909         }
00910           __str.append(__buf, __len);
00911 
00912           if (_Traits::eq_int_type(__c, __eof))
00913         __err |= ios_base::eofbit;
00914           __in.width(0);
00915         }
00916       catch(...)
00917         {
00918           // _GLIBCXX_RESOLVE_LIB_DEFECTS
00919           // 91. Description of operator>> and getline() for string<>
00920           // might cause endless loop
00921           __in._M_setstate(ios_base::badbit);
00922         }
00923     }
00924       // 211.  operator>>(istream&, string&) doesn't set failbit
00925       if (!__extracted)
00926     __err |= ios_base::failbit;
00927       if (__err)
00928     __in.setstate(__err);
00929       return __in;
00930     }
00931 
00932   template<typename _CharT, typename _Traits, typename _Alloc>
00933     basic_istream<_CharT, _Traits>&
00934     getline(basic_istream<_CharT, _Traits>& __in,
00935         basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim)
00936     {
00937       typedef basic_istream<_CharT, _Traits>        __istream_type;
00938       typedef typename __istream_type::int_type     __int_type;
00939       typedef typename __istream_type::__streambuf_type __streambuf_type;
00940       typedef typename __istream_type::__ctype_type __ctype_type;
00941       typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
00942       typedef typename __string_type::size_type     __size_type;
00943 
00944       __size_type __extracted = 0;
00945       const __size_type __n = __str.max_size();
00946       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00947       typename __istream_type::sentry __cerb(__in, true);
00948       if (__cerb)
00949     {
00950       try
00951         {
00952           __str.erase();
00953           const __int_type __idelim = _Traits::to_int_type(__delim);
00954           const __int_type __eof = _Traits::eof();
00955           __streambuf_type* __sb = __in.rdbuf();
00956           __int_type __c = __sb->sgetc();
00957 
00958           while (__extracted < __n
00959              && !_Traits::eq_int_type(__c, __eof)
00960              && !_Traits::eq_int_type(__c, __idelim))
00961         {
00962           __str += _Traits::to_char_type(__c);
00963           ++__extracted;
00964           __c = __sb->snextc();
00965         }
00966 
00967           if (_Traits::eq_int_type(__c, __eof))
00968         __err |= ios_base::eofbit;
00969           else if (_Traits::eq_int_type(__c, __idelim))
00970         {
00971           ++__extracted;          
00972           __sb->sbumpc();
00973         }
00974           else
00975         __err |= ios_base::failbit;
00976         }
00977       catch(...)
00978         {
00979           // _GLIBCXX_RESOLVE_LIB_DEFECTS
00980           // 91. Description of operator>> and getline() for string<>
00981           // might cause endless loop
00982           __in._M_setstate(ios_base::badbit);
00983         }
00984     }
00985       if (!__extracted)
00986     __err |= ios_base::failbit;
00987       if (__err)
00988     __in.setstate(__err);
00989       return __in;
00990     }
00991 
00992   // Inhibit implicit instantiations for required instantiations,
00993   // which are defined via explicit instantiations elsewhere.
00994   // NB:  This syntax is a GNU extension.
00995 #if _GLIBCXX_EXTERN_TEMPLATE
00996   extern template class basic_istream<char>;
00997   extern template istream& ws(istream&);
00998   extern template istream& operator>>(istream&, char&);
00999   extern template istream& operator>>(istream&, char*);
01000   extern template istream& operator>>(istream&, unsigned char&);
01001   extern template istream& operator>>(istream&, signed char&);
01002   extern template istream& operator>>(istream&, unsigned char*);
01003   extern template istream& operator>>(istream&, signed char*);
01004 
01005   extern template istream& istream::_M_extract(unsigned short&);
01006   extern template istream& istream::_M_extract(unsigned int&);  
01007   extern template istream& istream::_M_extract(long&);
01008   extern template istream& istream::_M_extract(unsigned long&);
01009   extern template istream& istream::_M_extract(bool&);
01010 #ifdef _GLIBCXX_USE_LONG_LONG
01011   extern template istream& istream::_M_extract(long long&);
01012   extern template istream& istream::_M_extract(unsigned long long&);
01013 #endif
01014   extern template istream& istream::_M_extract(float&);
01015   extern template istream& istream::_M_extract(double&);
01016   extern template istream& istream::_M_extract(long double&);
01017   extern template istream& istream::_M_extract(void*&);
01018 
01019   extern template class basic_iostream<char>;
01020 
01021 #ifdef _GLIBCXX_USE_WCHAR_T
01022   extern template class basic_istream<wchar_t>;
01023   extern template wistream& ws(wistream&);
01024   extern template wistream& operator>>(wistream&, wchar_t&);
01025   extern template wistream& operator>>(wistream&, wchar_t*);
01026 
01027   extern template wistream& wistream::_M_extract(unsigned short&);
01028   extern template wistream& wistream::_M_extract(unsigned int&);  
01029   extern template wistream& wistream::_M_extract(long&);
01030   extern template wistream& wistream::_M_extract(unsigned long&);
01031   extern template wistream& wistream::_M_extract(bool&);
01032 #ifdef _GLIBCXX_USE_LONG_LONG
01033   extern template wistream& wistream::_M_extract(long long&);
01034   extern template wistream& wistream::_M_extract(unsigned long long&);
01035 #endif
01036   extern template wistream& wistream::_M_extract(float&);
01037   extern template wistream& wistream::_M_extract(double&);
01038   extern template wistream& wistream::_M_extract(long double&);
01039   extern template wistream& wistream::_M_extract(void*&);
01040 
01041   extern template class basic_iostream<wchar_t>;
01042 #endif
01043 #endif
01044 
01045 _GLIBCXX_END_NAMESPACE
01046 
01047 #endif

Generated on Thu Nov 1 13:11:59 2007 for libstdc++ by  doxygen 1.5.1