2017-10-04 Petr Ovtchenkov <ptr@void-ptr.info>

François Dumont  <fdumont@gcc.gnu.org>

	* 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 <fdumont@gcc.gnu.org>

From-SVN: r253417
This commit is contained in:
Petr Ovtchenkov 2017-10-04 16:15:18 +00:00 committed by François Dumont
parent 6411847fcf
commit 4e91452412
3 changed files with 48 additions and 37 deletions

View File

@ -1,3 +1,19 @@
2017-10-04 Petr Ovtchenkov <ptr@void-ptr.info>
François Dumont <fdumont@gcc.gnu.org>
* 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 <jakub@redhat.com>
* include/std/charconv (__unsigned_least_t): Fix number of closing >s for

View File

@ -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;
}

View File

@ -25,9 +25,7 @@
void test02(void)
{
typedef std::istreambuf_iterator<char> 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 );