diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h index f0451b1..ad9c89f 100644 --- a/libstdc++-v3/include/bits/streambuf_iterator.h +++ b/libstdc++-v3/include/bits/streambuf_iterator.h @@ -103,7 +103,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_sbuf(0), _M_c(traits_type::eof()) { } #if __cplusplus >= 201103L - istreambuf_iterator(const istreambuf_iterator&) noexcept = default; + istreambuf_iterator(const istreambuf_iterator&) = default; ~istreambuf_iterator() = default; #endif @@ -122,28 +122,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION char_type operator*() const { + int_type __c = _M_get(); + #ifdef _GLIBCXX_DEBUG_PEDANTIC // Dereferencing a past-the-end istreambuf_iterator is a // libstdc++ extension - __glibcxx_requires_cond(!_M_at_eof(), + __glibcxx_requires_cond(!_S_at_eof(__c), _M_message(__gnu_debug::__msg_deref_istreambuf) ._M_iterator(*this)); #endif - return traits_type::to_char_type(_M_get()); + return traits_type::to_char_type(__c); } /// Advance the iterator. Calls streambuf.sbumpc(). istreambuf_iterator& operator++() { - __glibcxx_requires_cond(!_M_at_eof(), + __glibcxx_requires_cond(_M_sbuf + && (!_S_at_eof(_M_c) || !_S_at_eof(_M_sbuf->sgetc())), _M_message(__gnu_debug::__msg_inc_istreambuf) ._M_iterator(*this)); - if (_M_sbuf) - { + _M_sbuf->sbumpc(); _M_c = traits_type::eof(); - } return *this; } @@ -151,16 +152,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION istreambuf_iterator operator++(int) { - __glibcxx_requires_cond(!_M_at_eof(), + __glibcxx_requires_cond(_M_sbuf + && (!_S_at_eof(_M_c) || !_S_at_eof(_M_sbuf->sgetc())), _M_message(__gnu_debug::__msg_inc_istreambuf) ._M_iterator(*this)); istreambuf_iterator __old = *this; - if (_M_sbuf) - { __old._M_c = _M_sbuf->sbumpc(); _M_c = traits_type::eof(); - } return __old; } @@ -176,26 +175,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION int_type _M_get() const { - const int_type __eof = traits_type::eof(); - int_type __ret = __eof; - if (_M_sbuf) - { - if (!traits_type::eq_int_type(_M_c, __eof)) - __ret = _M_c; - else if (!traits_type::eq_int_type((__ret = _M_sbuf->sgetc()), - __eof)) - _M_c = __ret; - else + if (_M_sbuf && _S_at_eof(_M_c) && _S_at_eof(_M_c = _M_sbuf->sgetc())) _M_sbuf = 0; - } - return __ret; + return _M_c; } bool _M_at_eof() const + { return _S_at_eof(_M_get()); } + + static bool + _S_at_eof(int_type __c) { const int_type __eof = traits_type::eof(); - return traits_type::eq_int_type(_M_get(), __eof); + return traits_type::eq_int_type(__c, __eof); } }; @@ -373,13 +366,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef typename __is_iterator_type::traits_type traits_type; typedef typename __is_iterator_type::streambuf_type streambuf_type; typedef typename traits_type::int_type int_type; + const int_type __eof = traits_type::eof(); if (__first._M_sbuf && !__last._M_sbuf) { const int_type __ival = traits_type::to_int_type(__val); streambuf_type* __sb = __first._M_sbuf; int_type __c = __sb->sgetc(); - while (!traits_type::eq_int_type(__c, traits_type::eof()) + while (!traits_type::eq_int_type(__c, __eof) && !traits_type::eq_int_type(__c, __ival)) { streamsize __n = __sb->egptr() - __sb->gptr(); @@ -396,11 +390,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __c = __sb->snextc(); } - if (!traits_type::eq_int_type(__c, traits_type::eof())) - __first._M_c = __c; - else - __first._M_sbuf = 0; + __first._M_c = __eof; } + return __first; } diff --git a/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/2.cc b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/2.cc index b81f4d4..e3d99f9 100644 --- a/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/2.cc +++ b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/2.cc @@ -25,9 +25,7 @@ void test02(void) { - typedef std::istreambuf_iterator cistreambuf_iter; - typedef cistreambuf_iter::streambuf_type cstreambuf_type; const char slit01[] = "playa hermosa, liberia, guanacaste"; std::string str01(slit01); std::istringstream istrs00(str01); @@ -35,10 +33,17 @@ void test02(void) // ctor sanity checks cistreambuf_iter istrb_it01(istrs00); - cistreambuf_iter istrb_it02; - std::string tmp(istrb_it01, istrb_it02); + cistreambuf_iter istrb_eos; + VERIFY( istrb_it01 != istrb_eos ); + + std::string tmp(istrb_it01, istrb_eos); VERIFY( tmp == str01 ); + VERIFY( istrb_it01 != istrb_eos ); + cistreambuf_iter old = istrb_it01++; + VERIFY( old == istrb_eos ); + VERIFY( istrb_it01 == istrb_eos ); + cistreambuf_iter istrb_it03(0); cistreambuf_iter istrb_it04; VERIFY( istrb_it03 == istrb_it04 );