# istream.tcc

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