_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 + -
显示快捷键?