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

Generated on Wed Apr 27 18:35:12 2005 for libstdc++ source by  doxygen 1.4.2