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