diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h index 134b3486b9a..17dd3972d45 100644 --- a/libstdc++-v3/include/bits/streambuf_iterator.h +++ b/libstdc++-v3/include/bits/streambuf_iterator.h @@ -431,37 +431,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_assert(__n > 0); __glibcxx_requires_cond(!__i._M_at_eof(), - _M_message(__gnu_debug::__msg_inc_istreambuf) - ._M_iterator(__i)); - - typedef istreambuf_iterator<_CharT> __is_iterator_type; - 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(); - - streambuf_type* __sb = __i._M_sbuf; - while (__n > 0) - { - streamsize __size = __sb->egptr() - __sb->gptr(); - if (__size > __n) + _M_message(__gnu_debug::__msg_advance_oob) + ._M_iterator(__i) + ._M_integer(__n)); + + typedef basic_streambuf<_CharT> __streambuf_t; + typedef typename __streambuf_t::pos_type __pos_t; + __pos_t __cur_pos + = __i._M_sbuf->pubseekoff(0, ios_base::cur, ios_base::in); + __pos_t __new_pos + = __i._M_sbuf->pubseekoff(__n, ios_base::cur, ios_base::in); + __i._M_c = char_traits<_CharT>::eof(); + + if (__new_pos - __cur_pos != __n) { - __sb->__safe_gbump(__n); - break; - } - - __sb->__safe_gbump(__size); - __n -= __size; - if (traits_type::eq_int_type(__sb->underflow(), __eof)) - { - __glibcxx_requires_cond(__n == 0, - _M_message(__gnu_debug::__msg_inc_istreambuf) - ._M_iterator(__i)); - break; - } + __i._M_sbuf = 0; + __glibcxx_requires_cond(!__i._M_at_eof(), + _M_message(__gnu_debug::__msg_advance_oob) + ._M_iterator(__i) + ._M_integer(__n)); } - - __i._M_c = __eof; } // @} group iterators diff --git a/libstdc++-v3/include/std/streambuf b/libstdc++-v3/include/std/streambuf index 3442f19bd78..ef03da39bc2 100644 --- a/libstdc++-v3/include/std/streambuf +++ b/libstdc++-v3/include/std/streambuf @@ -155,11 +155,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, const _CharT2&); - template - friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, - void>::__type - advance(istreambuf_iterator<_CharT2>&, _Distance); - template friend basic_istream<_CharT2, _Traits2>& operator>>(basic_istream<_CharT2, _Traits2>&, _CharT2*); diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/3.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/3.cc new file mode 100644 index 00000000000..8763e7fa78e --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/3.cc @@ -0,0 +1,49 @@ +// Copyright (C) 2017-2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// Debug mode would detect the invalid std::advance call. +// { dg-require-normal-mode "" } + +#include +#include +#include + +#include + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator in_iterator_type; + + const char data1[] = "Drei Phantasien nach Friedrich Holderlin"; + istringstream iss1(data1); + in_iterator_type beg1(iss1); + in_iterator_type end1; + + VERIFY( beg1 != end1 ); + + advance(beg1, sizeof(data1)); + + VERIFY( beg1 == end1 ); +} + +int main() +{ + test01(); + return 0; +}