_istream.c
来自「stl的源码」· C语言 代码 · 共 1,430 行 · 第 1/4 页
C
1,430 行
return __tmp;}template <class _CharT, class _Traits>basic_istream<_CharT, _Traits>&basic_istream<_CharT, _Traits>::get(_CharT& __c) { sentry __sentry(*this, _No_Skip_WS()); this->_M_gcount = 0; if (__sentry) { typename _Traits::int_type __tmp = _Traits::eof(); _STLP_TRY { __tmp = this->rdbuf()->sbumpc(); } _STLP_CATCH_ALL { this->_M_handle_exception(ios_base::badbit); } if (!this->_S_eof(__tmp)) { this->_M_gcount = 1; __c = _Traits::to_char_type(__tmp); } } if (this->_M_gcount == 0) this->setstate(ios_base::eofbit | ios_base::failbit); return *this;}// Read characters and discard them. The standard specifies a single// function with two arguments, each with a default. We instead use// three overloded functions, because it's possible to implement the// first two more efficiently than the fully general third version.template <class _CharT, class _Traits>basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::ignore() { sentry __sentry(*this, _No_Skip_WS()); this->_M_gcount = 0; if (__sentry) { int_type __c; _STLP_TRY { __c = this->rdbuf()->sbumpc(); } _STLP_CATCH_ALL { this->_M_handle_exception(ios_base::badbit); return *this; } if (!this->_S_eof(__c)) this->_M_gcount = 1; else this->setstate(ios_base::eofbit); } return *this;}// Putbacktemplate <class _CharT, class _Traits>basic_istream<_CharT, _Traits>&basic_istream<_CharT, _Traits>::putback(_CharT __c) { this->_M_gcount = 0; sentry __sentry(*this, _No_Skip_WS()); if (__sentry) { typename _Traits::int_type __tmp = _Traits::eof(); basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf();// if (!__buf || this->_S_eof(__buf->sputbackc(__c))) if (__buf) { _STLP_TRY { __tmp = __buf->sputbackc(__c); } _STLP_CATCH_ALL { this->_M_handle_exception(ios_base::badbit); } } if (this->_S_eof(__tmp)) this->setstate(ios_base::badbit); } else this->setstate(ios_base::failbit); return *this;}template <class _CharT, class _Traits>basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::unget() { this->_M_gcount = 0; sentry __sentry(*this, _No_Skip_WS()); if (__sentry) { basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); // if (!__buf || _Traits::eq_int_type(__buf->sungetc(), _Traits::eof())) if (__buf) { _STLP_TRY { if (this->_S_eof(__buf->sungetc())) this->setstate(ios_base::badbit); } _STLP_CATCH_ALL { this->_M_handle_exception(ios_base::badbit); } } else this->setstate(ios_base::badbit); } else this->setstate(ios_base::failbit); return *this;}// Positioning and buffer control.template <class _CharT, class _Traits>int basic_istream<_CharT, _Traits>::sync() { sentry __sentry(*this, _No_Skip_WS()); basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); if (__buf) { if (__buf->pubsync() == -1) { this->setstate(ios_base::badbit); return -1; } else return 0; } else return -1;}template <class _CharT, class _Traits>__BIS_pos_type__basic_istream<_CharT, _Traits>::tellg() { sentry __sentry(*this, _No_Skip_WS()); basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); return (__buf && !this->fail()) ? __buf->pubseekoff(0, ios_base::cur, ios_base::in) : pos_type(-1);}template <class _CharT, class _Traits>basic_istream<_CharT, _Traits>&basic_istream<_CharT, _Traits>::seekg(pos_type __pos) { sentry __sentry(*this, _No_Skip_WS()); basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); if (!this->fail() && __buf) { if (__buf->pubseekpos(__pos, ios_base::in) == pos_type(-1)) { this->setstate(ios_base::failbit); } } return *this;}template <class _CharT, class _Traits>basic_istream<_CharT, _Traits>&basic_istream<_CharT, _Traits>::seekg(off_type __off, ios_base::seekdir __dir) { sentry __sentry(*this, _No_Skip_WS()); basic_streambuf<_CharT, _Traits>* __buf = this->rdbuf(); if (!this->fail() && __buf) __buf->pubseekoff(__off, __dir, ios_base::in); return *this;}// Formatted input of characters and character arrays.template <class _CharT, class _Traits>void basic_istream<_CharT, _Traits>::_M_formatted_get(_CharT& __c) {// typename _Traits::int_type __tmp = _Traits::eof(); sentry __sentry(*this); // Skip whitespace. if (__sentry) { typename _Traits::int_type __tmp;// = _Traits::eof(); _STLP_TRY { __tmp = this->rdbuf()->sbumpc(); } _STLP_CATCH_ALL { this->_M_handle_exception(ios_base::badbit); return; } if (!this->_S_eof(__tmp)) __c = _Traits::to_char_type(__tmp); else this->setstate(ios_base::eofbit | ios_base::failbit); }}//---------------------------------------------------------------------------// istream's helper functions.// A generic function for unbuffered input. We stop when we reach EOF,// or when we have extracted _Num characters, or when the function object// __is_delim return true. In the last case, it extracts the character// for which __is_delim is true, if and only if __extract_delim is true.// It appends a null character to the end of the string; this means that// it may store up to _Num + 1 characters.//// __is_getline governs two corner cases: reading _Num characters without// encountering delim or eof (in which case failbit is set if __is_getline// is true); and reading _Num characters where the _Num+1'st character is// eof (in which case eofbit is set if __is_getline is true).//// It is assumed that __is_delim never throws.//// Return value is the number of characters extracted, including the// delimiter if it is extracted. Note that the number of characaters// extracted isn't necessarily the same as the number stored._STLP_MOVE_TO_PRIV_NAMESPACEtemplate < class _CharT, class _Traits, class _Is_Delim>streamsize _STLP_CALL__read_unbuffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __buf, streamsize _Num, _CharT* __s, _Is_Delim __is_delim, bool __extract_delim, bool __append_null, bool __is_getline){ streamsize __n = 0; ios_base::iostate __status = 0; typedef typename basic_istream<_CharT, _Traits>::int_type int_type; // The operations that can potentially throw are sbumpc, snextc, and sgetc. _STLP_TRY { for (;;) { if (__n == _Num) { if (__is_getline) // didn't find delimiter as one of the _Num chars __status |= ios_base::failbit; break; } int_type __c = __buf->sbumpc(); // sschwarz if (__that->_S_eof(__c)) { if (__n < _Num || __is_getline) __status |= ios_base::eofbit; break; } else if (__is_delim(_Traits::to_char_type(__c))) { if (__extract_delim) { // Extract and discard current character. ++__n; } else if ( !__pushback(__buf, _Traits::to_char_type(__c)) ) { // leave delimiter __status |= ios_base::failbit; } break; } // regular character *__s++ = _Traits::to_char_type(__c); ++__n; } } _STLP_CATCH_ALL { __that->_M_handle_exception(ios_base::badbit); *__s = _STLP_DEFAULT_CONSTRUCTED(_CharT); return __n; } if (__append_null) *__s = _STLP_DEFAULT_CONSTRUCTED(_CharT); if (__status) __that->setstate(__status); // This might throw. return __n;}// Much like __read_unbuffered, but with one additional function object:// __scan_delim(first, last) returns the first pointer p in [first, last)// such that __is_delim(p) is true.template < class _CharT, class _Traits, class _Is_Delim, class _Scan_Delim>streamsize _STLP_CALL__read_buffered(basic_istream<_CharT, _Traits>* __that, basic_streambuf<_CharT, _Traits>* __buf, streamsize _Num, _CharT* __s, _Is_Delim __is_delim, _Scan_Delim __scan_delim, bool __extract_delim, bool __append_null, bool __is_getline) { streamsize __n = 0; ios_base::iostate __status = 0; bool __done = false; _STLP_TRY { while (__buf->_M_egptr() != __buf->_M_gptr() && !__done) { const _CharT* __first = __buf->_M_gptr(); const _CharT* __last = __buf->_M_egptr(); //casting numeric_limits<ptrdiff_t>::max to streamsize only works is ptrdiff_t is signed or streamsize representation //is larger than ptrdiff_t one. _STLP_STATIC_ASSERT((sizeof(streamsize) > sizeof(ptrdiff_t)) || ((sizeof(streamsize) == sizeof(ptrdiff_t)) && numeric_limits<ptrdiff_t>::is_signed)) ptrdiff_t __request = __STATIC_CAST(ptrdiff_t, (min) (__STATIC_CAST(streamsize, (numeric_limits<ptrdiff_t>::max)()), _Num - __n)); const _CharT* __p = __scan_delim(__first, __last); ptrdiff_t __chunk = (min) (ptrdiff_t(__p - __first), __request); _Traits::copy(__s, __first, __chunk); __s += __chunk; __n += __chunk; __buf->_M_gbump((int)__chunk); // We terminated by finding delim. if (__p != __last && __p - __first <= __request) { if (__extract_delim) { __n += 1; __buf->_M_gbump(1); } __done = true; } // We terminated by reading all the characters we were asked for. else if (__n == _Num) { // Find out if we have reached eof. This matters for getline. if (__is_getline) { if (__chunk == __last - __first) { if (__that->_S_eof(__buf->sgetc())) __status |= ios_base::eofbit; } else __status |= ios_base::failbit; } __done = true; } // The buffer contained fewer than _Num - __n characters. Either we're // at eof, or we should refill the buffer and try again. else { if (__that->_S_eof(__buf->sgetc())) { __status |= ios_base::eofbit; __done = true; } } } // Close the while loop. } _STLP_CATCH_ALL { __that->_M_handle_exception(ios_base::badbit); __done = true; } if (__done) { if (__append_null) *__s = _STLP_DEFAULT_CONSTRUCTED(_CharT); if (__status != 0) __that->setstate(__status); // This might throw. return __n; } // If execution has reached this point, then we have an empty buffer but // we have not reached eof. What that means is that the streambuf has // decided to switch from buffered to unbuffered input. We switch to // to __read_unbuffered. return __n + __read_unbuffered(__that, __buf, _Num - __n, __s, __is_delim, __extract_delim,__append_null,__is_getline);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?