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 streamsize(__n - _M_gcount 00602 - 1)); 00603 if (__size > 1) 00604 { 00605 const char_type* __p = traits_type::find(__sb->gptr(), 00606 __size, 00607 __delim); 00608 if (__p) 00609 __size = __p - __sb->gptr(); 00610 traits_type::copy(__s, __sb->gptr(), __size); 00611 __s += __size; 00612 __sb->gbump(__size); 00613 _M_gcount += __size; 00614 __c = __sb->sgetc(); 00615 } 00616 else 00617 { 00618 *__s++ = traits_type::to_char_type(__c); 00619 ++_M_gcount; 00620 __c = __sb->snextc(); 00621 } 00622 } 00623 00624 if (traits_type::eq_int_type(__c, __eof)) 00625 __err |= ios_base::eofbit; 00626 else if (traits_type::eq_int_type(__c, __idelim)) 00627 { 00628 ++_M_gcount; 00629 __sb->sbumpc(); 00630 } 00631 else 00632 __err |= ios_base::failbit; 00633 } 00634 catch(...) 00635 { this->_M_setstate(ios_base::badbit); } 00636 } 00637 *__s = char_type(); 00638 if (!_M_gcount) 00639 __err |= ios_base::failbit; 00640 if (__err) 00641 this->setstate(__err); 00642 return *this; 00643 } 00644 00645 // We provide three overloads, since the first two are much simpler 00646 // than the general case. Also, the latter two can thus adopt the 00647 // same "batchy" strategy used by getline above. 00648 template<typename _CharT, typename _Traits> 00649 basic_istream<_CharT, _Traits>& 00650 basic_istream<_CharT, _Traits>:: 00651 ignore(void) 00652 { 00653 _M_gcount = 0; 00654 sentry __cerb(*this, true); 00655 if (__cerb) 00656 { 00657 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 00658 try 00659 { 00660 const int_type __eof = traits_type::eof(); 00661 __streambuf_type* __sb = this->rdbuf(); 00662 00663 if (traits_type::eq_int_type(__sb->sbumpc(), __eof)) 00664 __err |= ios_base::eofbit; 00665 else 00666 _M_gcount = 1; 00667 } 00668 catch(...) 00669 { this->_M_setstate(ios_base::badbit); } 00670 if (__err) 00671 this->setstate(__err); 00672 } 00673 return *this; 00674 } 00675 00676 template<typename _CharT, typename _Traits> 00677 basic_istream<_CharT, _Traits>& 00678 basic_istream<_CharT, _Traits>:: 00679 ignore(streamsize __n) 00680 { 00681 if (__n == 1) 00682 return ignore(); 00683 00684 _M_gcount = 0; 00685 sentry __cerb(*this, true); 00686 if (__cerb && __n > 0) 00687 { 00688 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 00689 try 00690 { 00691 const int_type __eof = traits_type::eof(); 00692 __streambuf_type* __sb = this->rdbuf(); 00693 int_type __c = __sb->sgetc(); 00694 00695 const bool __bound = __n != numeric_limits<streamsize>::max(); 00696 if (__bound) 00697 --__n; 00698 while (_M_gcount <= __n 00699 && !traits_type::eq_int_type(__c, __eof)) 00700 { 00701 streamsize __size = __sb->egptr() - __sb->gptr(); 00702 if (__bound) 00703 __size = std::min(__size, streamsize(__n - _M_gcount + 1)); 00704 00705 if (__size > 1) 00706 { 00707 __sb->gbump(__size); 00708 _M_gcount += __size; 00709 __c = __sb->sgetc(); 00710 } 00711 else 00712 { 00713 ++_M_gcount; 00714 __c = __sb->snextc(); 00715 } 00716 } 00717 if (traits_type::eq_int_type(__c, __eof)) 00718 __err |= ios_base::eofbit; 00719 } 00720 catch(...) 00721 { this->_M_setstate(ios_base::badbit); } 00722 if (__err) 00723 this->setstate(__err); 00724 } 00725 return *this; 00726 } 00727 00728 template<typename _CharT, typename _Traits> 00729 basic_istream<_CharT, _Traits>& 00730 basic_istream<_CharT, _Traits>:: 00731 ignore(streamsize __n, int_type __delim) 00732 { 00733 if (traits_type::eq_int_type(__delim, traits_type::eof())) 00734 return ignore(__n); 00735 00736 _M_gcount = 0; 00737 sentry __cerb(*this, true); 00738 if (__cerb && __n > 0) 00739 { 00740 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 00741 try 00742 { 00743 const char_type __cdelim = traits_type::to_char_type(__delim); 00744 const int_type __eof = traits_type::eof(); 00745 __streambuf_type* __sb = this->rdbuf(); 00746 int_type __c = __sb->sgetc(); 00747 00748 const bool __bound = __n != numeric_limits<streamsize>::max(); 00749 if (__bound) 00750 --__n; 00751 while (_M_gcount <= __n 00752 && !traits_type::eq_int_type(__c, __eof) 00753 && !traits_type::eq_int_type(__c, __delim)) 00754 { 00755 streamsize __size = __sb->egptr() - __sb->gptr(); 00756 if (__bound) 00757 __size = std::min(__size, streamsize(__n - _M_gcount + 1)); 00758 00759 if (__size > 1) 00760 { 00761 const char_type* __p = traits_type::find(__sb->gptr(), 00762 __size, 00763 __cdelim); 00764 if (__p) 00765 __size = __p - __sb->gptr(); 00766 __sb->gbump(__size); 00767 _M_gcount += __size; 00768 __c = __sb->sgetc(); 00769 } 00770 else 00771 { 00772 ++_M_gcount; 00773 __c = __sb->snextc(); 00774 } 00775 } 00776 if (traits_type::eq_int_type(__c, __eof)) 00777 __err |= ios_base::eofbit; 00778 else if (traits_type::eq_int_type(__c, __delim)) 00779 { 00780 ++_M_gcount; 00781 __sb->sbumpc(); 00782 } 00783 } 00784 catch(...) 00785 { this->_M_setstate(ios_base::badbit); } 00786 if (__err) 00787 this->setstate(__err); 00788 } 00789 return *this; 00790 } 00791 00792 template<typename _CharT, typename _Traits> 00793 typename basic_istream<_CharT, _Traits>::int_type 00794 basic_istream<_CharT, _Traits>:: 00795 peek(void) 00796 { 00797 int_type __c = traits_type::eof(); 00798 _M_gcount = 0; 00799 sentry __cerb(*this, true); 00800 if (__cerb) 00801 { 00802 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 00803 try 00804 { 00805 __c = this->rdbuf()->sgetc(); 00806 if (traits_type::eq_int_type(__c, traits_type::eof())) 00807 __err |= ios_base::eofbit; 00808 } 00809 catch(...) 00810 { this->_M_setstate(ios_base::badbit); } 00811 if (__err) 00812 this->setstate(__err); 00813 } 00814 return __c; 00815 } 00816 00817 template<typename _CharT, typename _Traits> 00818 basic_istream<_CharT, _Traits>& 00819 basic_istream<_CharT, _Traits>:: 00820 read(char_type* __s, streamsize __n) 00821 { 00822 _M_gcount = 0; 00823 sentry __cerb(*this, true); 00824 if (__cerb) 00825 { 00826 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 00827 try 00828 { 00829 _M_gcount = this->rdbuf()->sgetn(__s, __n); 00830 if (_M_gcount != __n) 00831 __err |= (ios_base::eofbit | ios_base::failbit); 00832 } 00833 catch(...) 00834 { this->_M_setstate(ios_base::badbit); } 00835 if (__err) 00836 this->setstate(__err); 00837 } 00838 return *this; 00839 } 00840 00841 template<typename _CharT, typename _Traits> 00842 streamsize 00843 basic_istream<_CharT, _Traits>:: 00844 readsome(char_type* __s, streamsize __n) 00845 { 00846 _M_gcount = 0; 00847 sentry __cerb(*this, true); 00848 if (__cerb) 00849 { 00850 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 00851 try 00852 { 00853 // Cannot compare int_type with streamsize generically. 00854 const streamsize __num = this->rdbuf()->in_avail(); 00855 if (__num > 0) 00856 _M_gcount = this->rdbuf()->sgetn(__s, std::min(__num, __n)); 00857 else if (__num == -1) 00858 __err |= ios_base::eofbit; 00859 } 00860 catch(...) 00861 { this->_M_setstate(ios_base::badbit); } 00862 if (__err) 00863 this->setstate(__err); 00864 } 00865 return _M_gcount; 00866 } 00867 00868 template<typename _CharT, typename _Traits> 00869 basic_istream<_CharT, _Traits>& 00870 basic_istream<_CharT, _Traits>:: 00871 putback(char_type __c) 00872 { 00873 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00874 // 60. What is a formatted input function? 00875 _M_gcount = 0; 00876 sentry __cerb(*this, true); 00877 if (__cerb) 00878 { 00879 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 00880 try 00881 { 00882 const int_type __eof = traits_type::eof(); 00883 __streambuf_type* __sb = this->rdbuf(); 00884 if (!__sb 00885 || traits_type::eq_int_type(__sb->sputbackc(__c), __eof)) 00886 __err |= ios_base::badbit; 00887 } 00888 catch(...) 00889 { this->_M_setstate(ios_base::badbit); } 00890 if (__err) 00891 this->setstate(__err); 00892 } 00893 return *this; 00894 } 00895 00896 template<typename _CharT, typename _Traits> 00897 basic_istream<_CharT, _Traits>& 00898 basic_istream<_CharT, _Traits>:: 00899 unget(void) 00900 { 00901 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00902 // 60. What is a formatted input function? 00903 _M_gcount = 0; 00904 sentry __cerb(*this, true); 00905 if (__cerb) 00906 { 00907 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 00908 try 00909 { 00910 const int_type __eof = traits_type::eof(); 00911 __streambuf_type* __sb = this->rdbuf(); 00912 if (!__sb 00913 || traits_type::eq_int_type(__sb->sungetc(), __eof)) 00914 __err |= ios_base::badbit; 00915 } 00916 catch(...) 00917 { this->_M_setstate(ios_base::badbit); } 00918 if (__err) 00919 this->setstate(__err); 00920 } 00921 return *this; 00922 } 00923 00924 template<typename _CharT, typename _Traits> 00925 int 00926 basic_istream<_CharT, _Traits>:: 00927 sync(void) 00928 { 00929 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00930 // DR60. Do not change _M_gcount. 00931 int __ret = -1; 00932 sentry __cerb(*this, true); 00933 if (__cerb) 00934 { 00935 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 00936 try 00937 { 00938 __streambuf_type* __sb = this->rdbuf(); 00939 if (__sb) 00940 { 00941 if (__sb->pubsync() == -1) 00942 __err |= ios_base::badbit; 00943 else 00944 __ret = 0; 00945 } 00946 } 00947 catch(...) 00948 { this->_M_setstate(ios_base::badbit); } 00949 if (__err) 00950 this->setstate(__err); 00951 } 00952 return __ret; 00953 } 00954 00955 template<typename _CharT, typename _Traits> 00956 typename basic_istream<_CharT, _Traits>::pos_type 00957 basic_istream<_CharT, _Traits>:: 00958 tellg(void) 00959 { 00960 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00961 // DR60. Do not change _M_gcount. 00962 pos_type __ret = pos_type(-1); 00963 try 00964 { 00965 if (!this->fail()) 00966 __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in); 00967 } 00968 catch(...) 00969 { this->_M_setstate(ios_base::badbit); } 00970 return __ret; 00971 } 00972 00973 template<typename _CharT, typename _Traits> 00974 basic_istream<_CharT, _Traits>& 00975 basic_istream<_CharT, _Traits>:: 00976 seekg(pos_type __pos) 00977 { 00978 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00979 // DR60. Do not change _M_gcount. 00980 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 00981 try 00982 { 00983 if (!this->fail()) 00984 { 00985 // 136. seekp, seekg setting wrong streams? 00986 const pos_type __p = this->rdbuf()->pubseekpos(__pos, 00987 ios_base::in); 00988 00989 // 129. Need error indication from seekp() and seekg() 00990 if (__p == pos_type(off_type(-1))) 00991 __err |= ios_base::failbit; 00992 } 00993 } 00994 catch(...) 00995 { this->_M_setstate(ios_base::badbit); } 00996 if (__err) 00997 this->setstate(__err); 00998 return *this; 00999 } 01000 01001 template<typename _CharT, typename _Traits> 01002 basic_istream<_CharT, _Traits>& 01003 basic_istream<_CharT, _Traits>:: 01004 seekg(off_type __off, ios_base::seekdir __dir) 01005 { 01006 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01007 // DR60. Do not change _M_gcount. 01008 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 01009 try 01010 { 01011 if (!this->fail()) 01012 { 01013 // 136. seekp, seekg setting wrong streams? 01014 const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, 01015 ios_base::in); 01016 01017 // 129. Need error indication from seekp() and seekg() 01018 if (__p == pos_type(off_type(-1))) 01019 __err |= ios_base::failbit; 01020 } 01021 } 01022 catch(...) 01023 { this->_M_setstate(ios_base::badbit); } 01024 if (__err) 01025 this->setstate(__err); 01026 return *this; 01027 } 01028 01029 // 27.6.1.2.3 Character extraction templates 01030 template<typename _CharT, typename _Traits> 01031 basic_istream<_CharT, _Traits>& 01032 operator>>(basic_istream<_CharT, _Traits>& __in, _CharT& __c) 01033 { 01034 typedef basic_istream<_CharT, _Traits> __istream_type; 01035 typedef typename __istream_type::int_type __int_type; 01036 01037 typename __istream_type::sentry __cerb(__in, false); 01038 if (__cerb) 01039 { 01040 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 01041 try 01042 { 01043 const __int_type __cb = __in.rdbuf()->sbumpc(); 01044 if (!_Traits::eq_int_type(__cb, _Traits::eof())) 01045 __c = _Traits::to_char_type(__cb); 01046 else 01047 __err |= (ios_base::eofbit | ios_base::failbit); 01048 } 01049 catch(...) 01050 { __in._M_setstate(ios_base::badbit); } 01051 if (__err) 01052 __in.setstate(__err); 01053 } 01054 return __in; 01055 } 01056 01057 template<typename _CharT, typename _Traits> 01058 basic_istream<_CharT, _Traits>& 01059 operator>>(basic_istream<_CharT, _Traits>& __in, _CharT* __s) 01060 { 01061 typedef basic_istream<_CharT, _Traits> __istream_type; 01062 typedef typename __istream_type::__streambuf_type __streambuf_type; 01063 typedef typename _Traits::int_type int_type; 01064 typedef _CharT char_type; 01065 typedef ctype<_CharT> __ctype_type; 01066 01067 streamsize __extracted = 0; 01068 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 01069 typename __istream_type::sentry __cerb(__in, false); 01070 if (__cerb) 01071 { 01072 try 01073 { 01074 // Figure out how many characters to extract. 01075 streamsize __num = __in.width(); 01076 if (__num <= 0) 01077 __num = numeric_limits<streamsize>::max(); 01078 01079 const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); 01080 01081 const int_type __eof = _Traits::eof(); 01082 __streambuf_type* __sb = __in.rdbuf(); 01083 int_type __c = __sb->sgetc(); 01084 01085 while (__extracted < __num - 1 01086 && !_Traits::eq_int_type(__c, __eof) 01087 && !__ct.is(ctype_base::space, 01088 _Traits::to_char_type(__c))) 01089 { 01090 *__s++ = _Traits::to_char_type(__c); 01091 ++__extracted; 01092 __c = __sb->snextc(); 01093 } 01094 if (_Traits::eq_int_type(__c, __eof)) 01095 __err |= ios_base::eofbit; 01096 01097 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01098 // 68. Extractors for char* should store null at end 01099 *__s = char_type(); 01100 __in.width(0); 01101 } 01102 catch(...) 01103 { __in._M_setstate(ios_base::badbit); } 01104 } 01105 if (!__extracted) 01106 __err |= ios_base::failbit; 01107 if (__err) 01108 __in.setstate(__err); 01109 return __in; 01110 } 01111 01112 // 27.6.1.4 Standard basic_istream manipulators 01113 template<typename _CharT, typename _Traits> 01114 basic_istream<_CharT,_Traits>& 01115 ws(basic_istream<_CharT,_Traits>& __in) 01116 { 01117 typedef basic_istream<_CharT, _Traits> __istream_type; 01118 typedef typename __istream_type::__streambuf_type __streambuf_type; 01119 typedef typename __istream_type::__ctype_type __ctype_type; 01120 typedef typename __istream_type::int_type __int_type; 01121 01122 const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); 01123 const __int_type __eof = _Traits::eof(); 01124 __streambuf_type* __sb = __in.rdbuf(); 01125 __int_type __c = __sb->sgetc(); 01126 01127 while (!_Traits::eq_int_type(__c, __eof) 01128 && __ct.is(ctype_base::space, _Traits::to_char_type(__c))) 01129 __c = __sb->snextc(); 01130 01131 if (_Traits::eq_int_type(__c, __eof)) 01132 __in.setstate(ios_base::eofbit); 01133 return __in; 01134 } 01135 01136 // 21.3.7.9 basic_string::getline and operators 01137 template<typename _CharT, typename _Traits, typename _Alloc> 01138 basic_istream<_CharT, _Traits>& 01139 operator>>(basic_istream<_CharT, _Traits>& __in, 01140 basic_string<_CharT, _Traits, _Alloc>& __str) 01141 { 01142 typedef basic_istream<_CharT, _Traits> __istream_type; 01143 typedef typename __istream_type::int_type __int_type; 01144 typedef typename __istream_type::__streambuf_type __streambuf_type; 01145 typedef typename __istream_type::__ctype_type __ctype_type; 01146 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 01147 typedef typename __string_type::size_type __size_type; 01148 01149 __size_type __extracted = 0; 01150 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 01151 typename __istream_type::sentry __cerb(__in, false); 01152 if (__cerb) 01153 { 01154 try 01155 { 01156 // Avoid reallocation for common case. 01157 __str.erase(); 01158 _CharT __buf[128]; 01159 __size_type __len = 0; 01160 const streamsize __w = __in.width(); 01161 const __size_type __n = __w > 0 ? static_cast<__size_type>(__w) 01162 : __str.max_size(); 01163 const __ctype_type& __ct = use_facet<__ctype_type>(__in.getloc()); 01164 const __int_type __eof = _Traits::eof(); 01165 __streambuf_type* __sb = __in.rdbuf(); 01166 __int_type __c = __sb->sgetc(); 01167 01168 while (__extracted < __n 01169 && !_Traits::eq_int_type(__c, __eof) 01170 && !__ct.is(ctype_base::space, _Traits::to_char_type(__c))) 01171 { 01172 if (__len == sizeof(__buf) / sizeof(_CharT)) 01173 { 01174 __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); 01175 __len = 0; 01176 } 01177 __buf[__len++] = _Traits::to_char_type(__c); 01178 ++__extracted; 01179 __c = __sb->snextc(); 01180 } 01181 __str.append(__buf, __len); 01182 01183 if (_Traits::eq_int_type(__c, __eof)) 01184 __err |= ios_base::eofbit; 01185 __in.width(0); 01186 } 01187 catch(...) 01188 { 01189 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01190 // 91. Description of operator>> and getline() for string<> 01191 // might cause endless loop 01192 __in._M_setstate(ios_base::badbit); 01193 } 01194 } 01195 // 211. operator>>(istream&, string&) doesn't set failbit 01196 if (!__extracted) 01197 __err |= ios_base::failbit; 01198 if (__err) 01199 __in.setstate(__err); 01200 return __in; 01201 } 01202 01203 template<typename _CharT, typename _Traits, typename _Alloc> 01204 basic_istream<_CharT, _Traits>& 01205 getline(basic_istream<_CharT, _Traits>& __in, 01206 basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim) 01207 { 01208 typedef basic_istream<_CharT, _Traits> __istream_type; 01209 typedef typename __istream_type::int_type __int_type; 01210 typedef typename __istream_type::__streambuf_type __streambuf_type; 01211 typedef typename __istream_type::__ctype_type __ctype_type; 01212 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 01213 typedef typename __string_type::size_type __size_type; 01214 01215 __size_type __extracted = 0; 01216 const __size_type __n = __str.max_size(); 01217 ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 01218 typename __istream_type::sentry __cerb(__in, true); 01219 if (__cerb) 01220 { 01221 try 01222 { 01223 // Avoid reallocation for common case. 01224 __str.erase(); 01225 _CharT __buf[128]; 01226 __size_type __len = 0; 01227 const __int_type __idelim = _Traits::to_int_type(__delim); 01228 const __int_type __eof = _Traits::eof(); 01229 __streambuf_type* __sb = __in.rdbuf(); 01230 __int_type __c = __sb->sgetc(); 01231 01232 while (__extracted < __n 01233 && !_Traits::eq_int_type(__c, __eof) 01234 && !_Traits::eq_int_type(__c, __idelim)) 01235 { 01236 if (__len == sizeof(__buf) / sizeof(_CharT)) 01237 { 01238 __str.append(__buf, sizeof(__buf) / sizeof(_CharT)); 01239 __len = 0; 01240 } 01241 __buf[__len++] = _Traits::to_char_type(__c); 01242 ++__extracted; 01243 __c = __sb->snextc(); 01244 } 01245 __str.append(__buf, __len); 01246 01247 if (_Traits::eq_int_type(__c, __eof)) 01248 __err |= ios_base::eofbit; 01249 else if (_Traits::eq_int_type(__c, __idelim)) 01250 { 01251 ++__extracted; 01252 __sb->sbumpc(); 01253 } 01254 else 01255 __err |= ios_base::failbit; 01256 } 01257 catch(...) 01258 { 01259 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01260 // 91. Description of operator>> and getline() for string<> 01261 // might cause endless loop 01262 __in._M_setstate(ios_base::badbit); 01263 } 01264 } 01265 if (!__extracted) 01266 __err |= ios_base::failbit; 01267 if (__err) 01268 __in.setstate(__err); 01269 return __in; 01270 } 01271 01272 template<class _CharT, class _Traits, class _Alloc> 01273 inline basic_istream<_CharT,_Traits>& 01274 getline(basic_istream<_CharT, _Traits>& __in, 01275 basic_string<_CharT,_Traits,_Alloc>& __str) 01276 { return getline(__in, __str, __in.widen('\n')); } 01277 01278 // Inhibit implicit instantiations for required instantiations, 01279 // which are defined via explicit instantiations elsewhere. 01280 // NB: This syntax is a GNU extension. 01281 #if _GLIBCXX_EXTERN_TEMPLATE 01282 extern template class basic_istream<char>; 01283 extern template istream& ws(istream&); 01284 extern template istream& operator>>(istream&, char&); 01285 extern template istream& operator>>(istream&, char*); 01286 extern template istream& operator>>(istream&, unsigned char&); 01287 extern template istream& operator>>(istream&, signed char&); 01288 extern template istream& operator>>(istream&, unsigned char*); 01289 extern template istream& operator>>(istream&, signed char*); 01290 01291 #ifdef _GLIBCXX_USE_WCHAR_T 01292 extern template class basic_istream<wchar_t>; 01293 extern template wistream& ws(wistream&); 01294 extern template wistream& operator>>(wistream&, wchar_t&); 01295 extern template wistream& operator>>(wistream&, wchar_t*); 01296 #endif 01297 #endif 01298 } // namespace std 01299 01300 #endif

Generated on Sun Jul 25 00:12:33 2004 for libstdc++ source by doxygen 1.3.7