From: Petr Ovtchenkov Date: Wed, 4 Oct 2017 16:15:18 +0000 (+0000) Subject: 2017-10-04 Petr Ovtchenkov X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4e91452412294f3cc1c63de8c35e88d2c08fe6ee;p=gcc.git 2017-10-04 Petr Ovtchenkov François Dumont * include/bits/streambuf_iterator.h (istreambuf_iterator<>::operator*()): Do not capture iterator state in Debug assertion. (istreambuf_iterator<>::operator++()): Likewise and remove _M_sbuf check. (istreambuf_iterator<>::operator++(int)): Likewise. (istreambuf_iterator<>::_M_get()): Remove _M_c assignment. (istreambuf_iterator<>::_S_is_eof()): New. (istreambuf_iterator<>::_M_at_eof()): Adapt, use latter. (find(istreambuf_iterator<>, istreambuf_iterator<>, _CharT)): Return an iterator with _M_c set to eof to capture streambuf state on evaluation. (testsuite/24_iterators/istreambuf_iterator/2.cc): Add checks. Co-Authored-By: François Dumont From-SVN: r253417 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4559f79b2f9..4d371b8b9f2 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,19 @@ +2017-10-04 Petr Ovtchenkov + François Dumont + + * include/bits/streambuf_iterator.h + (istreambuf_iterator<>::operator*()): Do not capture iterator state + in Debug assertion. + (istreambuf_iterator<>::operator++()): Likewise and remove _M_sbuf check. + (istreambuf_iterator<>::operator++(int)): Likewise. + (istreambuf_iterator<>::_M_get()): Remove _M_c assignment. + (istreambuf_iterator<>::_S_is_eof()): New. + (istreambuf_iterator<>::_M_at_eof()): Adapt, use latter. + (find(istreambuf_iterator<>, istreambuf_iterator<>, _CharT)): + Return an iterator with _M_c set to eof to capture streambuf state + on evaluation. + (testsuite/24_iterators/istreambuf_iterator/2.cc): Add checks. + 2017-10-03 Jakub Jelinek * include/std/charconv (__unsigned_least_t): Fix number of closing >s for diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h index f0451b12ce3..64b8cfd7895 100644 --- a/libstdc++-v3/include/bits/streambuf_iterator.h +++ b/libstdc++-v3/include/bits/streambuf_iterator.h @@ -95,7 +95,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // NB: This implementation assumes the "end of stream" value // is EOF, or -1. mutable streambuf_type* _M_sbuf; - mutable int_type _M_c; + int_type _M_c; public: /// Construct end of input stream iterator. @@ -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_is_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_is_eof(_M_c) || !_S_is_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(); - } + + _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_is_eof(_M_c) || !_S_is_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(); - } + __old._M_c = _M_sbuf->sbumpc(); + _M_c = traits_type::eof(); return __old; } @@ -176,26 +175,21 @@ _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 - _M_sbuf = 0; - } + int_type __ret = _M_c; + if (_M_sbuf && _S_is_eof(__ret) && _S_is_eof(__ret = _M_sbuf->sgetc())) + _M_sbuf = 0; return __ret; } bool _M_at_eof() const + { return _S_is_eof(_M_get()); } + + static bool + _S_is_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 +367,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 +391,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 b81f4d443a9..572ea9f23bc 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,14 @@ 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 istrb_it03(0); cistreambuf_iter istrb_it04; VERIFY( istrb_it03 == istrb_it04 );