Message ID | fbc295ed-b9c4-a847-d33a-3141aa8f21cc@gmail.com |
---|---|
State | New |
Headers | show |
Series | std::advance istreambuf_iterator overload | expand |
On 09/11/17 22:12 +0100, François Dumont wrote: >Hi > > Working on istreambuf_iterator I realized that this iterator would >really benefit from an std::advance overload so here it is. > Tested under Linux x86_64 normal and debug modes, ok to commit ? > >François > >diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h >index 0a6c7f9..b60626a 100644 >--- a/libstdc++-v3/include/bits/streambuf_iterator.h >+++ b/libstdc++-v3/include/bits/streambuf_iterator.h >@@ -417,6 +421,55 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > return __last; > } > >+ template<typename _CharT, typename _Distance> >+ inline _GLIBCXX17_CONSTEXPR void This function can never be constexpr. >+ advance(istreambuf_iterator<_CharT>& __i, _Distance __n) >+ { >+ if (__n == 0) >+ return; >+ >+ __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; This function relies on private members of istreambuf_iterator which may not be present in a user-defined specialization of istreambuf_iterator. I think realistically you can only do this optimization for istreambuf_iterator<char> and istreambuf_iterator<wchar_t>. Look at how the std::copy and std::find overloads are contrained with __is_char. >+ int_type __c = __sb->sgetc(); >+ while (__n && !traits_type::eq_int_type(__c, __eof)) Can we use __n > 0 as the condition? Would it give better behaviour for negative values in non-debug mode? >+ { >+ streamsize __size = __sb->egptr() - __sb->gptr(); >+ if (__size > __n) >+ { >+ __sb->__safe_gbump(__n); >+ __n = 0; >+ } >+ else if (__size > 1) >+ { >+ __sb->__safe_gbump(__size); >+ __n -= __size; >+ __c = __sb->underflow(); >+ } >+ else >+ { >+ --__n; >+ __c = __sb->snextc(); >+ } It seems like it should be possible to optimize this loop, but I don't see an obvious way to improve it. >+ } >+ >+ __glibcxx_requires_cond(__n == 0, >+ _M_message(__gnu_debug::__msg_inc_istreambuf) >+ ._M_iterator(__i)); >+ __i._M_c = __eof; >+ if (traits_type::eq_int_type(__c, __eof)) >+ __i._M_sbuf = 0; >+ } >+ >diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1.cc >new file mode 100644 >index 0000000..7c3f882 >--- /dev/null >+++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1.cc Thanks for the comprehensive tests, they look great.
On 10/11/2017 21:57, Jonathan Wakely wrote: > On 09/11/17 22:12 +0100, François Dumont wrote: >> Hi >> >> Working on istreambuf_iterator I realized that this iterator >> would really benefit from an std::advance overload so here it is. > > >> Tested under Linux x86_64 normal and debug modes, ok to commit ? >> >> François >> > >> diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h >> b/libstdc++-v3/include/bits/streambuf_iterator.h >> index 0a6c7f9..b60626a 100644 >> --- a/libstdc++-v3/include/bits/streambuf_iterator.h >> +++ b/libstdc++-v3/include/bits/streambuf_iterator.h >> @@ -417,6 +421,55 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >> return __last; >> } >> >> + template<typename _CharT, typename _Distance> >> + inline _GLIBCXX17_CONSTEXPR void > > This function can never be constexpr. I just replicate the _GLIBCXX17_CONSTEXPR qualification of the general std::advance overload. I am not clear about those different constexpr concepts but I also found strange that it could be consider as such. > >> + advance(istreambuf_iterator<_CharT>& __i, _Distance __n) >> + { >> + if (__n == 0) >> + return; >> + >> + __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; > > This function relies on private members of istreambuf_iterator which > may not be present in a user-defined specialization of > istreambuf_iterator. > > I think realistically you can only do this optimization for > istreambuf_iterator<char> and istreambuf_iterator<wchar_t>. Look at > how the std::copy and std::find overloads are contrained with > __is_char. I wondered why copy or find were constrained this way, thanks for explaining. I have done the same for std::advance. > >> + int_type __c = __sb->sgetc(); >> + while (__n && !traits_type::eq_int_type(__c, __eof)) > > Can we use __n > 0 as the condition? Would it give better behaviour > for negative values in non-debug mode? Indeed, it is better with this check. > >> + { >> + streamsize __size = __sb->egptr() - __sb->gptr(); >> + if (__size > __n) >> + { >> + __sb->__safe_gbump(__n); >> + __n = 0; >> + } >> + else if (__size > 1) >> + { >> + __sb->__safe_gbump(__size); >> + __n -= __size; >> + __c = __sb->underflow(); >> + } >> + else >> + { >> + --__n; >> + __c = __sb->snextc(); >> + } > > It seems like it should be possible to optimize this loop, but I don't > see an obvious way to improve it. It sounds like a Fermat quotes :-) But I thought twice about this implementation and here is a new proposal. François diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h index 0a6c7f9..177f6f7 100644 --- a/libstdc++-v3/include/bits/streambuf_iterator.h +++ b/libstdc++-v3/include/bits/streambuf_iterator.h @@ -86,6 +86,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, const _CharT2&); + template<typename _CharT2, typename _Distance> + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + void>::__type + advance(istreambuf_iterator<_CharT2>&, _Distance); + private: // 24.5.3 istreambuf_iterator // p 1 @@ -417,6 +422,50 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __last; } + template<typename _CharT, typename _Distance> + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + void>::__type + advance(istreambuf_iterator<_CharT>& __i, _Distance __n) + { + if (__n == 0) + return; + + __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) + { + __sb->__safe_gbump(__n); + __n = 0; + break; + } + + __sb->__safe_gbump(__size); + __n -= __size; + if (traits_type::eq_int_type(__sb->underflow(), __eof)) + break; + } + + __glibcxx_requires_cond(__n == 0, + _M_message(__gnu_debug::__msg_inc_istreambuf) + ._M_iterator(__i)); + __i._M_c = __eof; + if (traits_type::eq_int_type(__sb->sgetc(), __eof)) + __i._M_sbuf = 0; + } + // @} group iterators _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/std/streambuf b/libstdc++-v3/include/std/streambuf index a05b46e..c1fd395 100644 --- a/libstdc++-v3/include/std/streambuf +++ b/libstdc++-v3/include/std/streambuf @@ -159,6 +159,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, const _CharT2&); + template<typename _CharT2, typename _Distance> + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + void>::__type + advance(istreambuf_iterator<_CharT2>&, _Distance); + template<typename _CharT2, typename _Traits2> friend basic_istream<_CharT2, _Traits2>& operator>>(basic_istream<_CharT2, _Traits2>&, _CharT2*); diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1.cc new file mode 100644 index 0000000..7c3f882 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1.cc @@ -0,0 +1,56 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +#include <iterator> +#include <sstream> +#include <algorithm> +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<char> in_iterator_type; + + const char data1[] = "Drei Phantasien nach Friedrich Holderlin"; + const string str1(data1); + istringstream iss1(str1); + in_iterator_type beg1(iss1); + in_iterator_type end1; + + VERIFY( *beg1 == 'D' ); + + advance(beg1, 1); + + VERIFY( beg1 != end1 ); + VERIFY( *beg1 == 'r' ); + + advance(beg1, 0); + VERIFY( *beg1 == 'r' ); + + advance(beg1, 38); + VERIFY( *beg1 == 'n' ); + + advance(beg1, 1); + VERIFY( beg1 == end1 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1_neg.cc new file mode 100644 index 0000000..d1b8cde --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1_neg.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<char> in_iterator_type; + in_iterator_type end1; + + advance(end1, -1); // Invalid -1 value. +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2.cc new file mode 100644 index 0000000..c99111e --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2.cc @@ -0,0 +1,82 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-require-fileio "" } + +#include <iterator> +#include <fstream> +#include <algorithm> + +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<char> in_iterator_type; + + unsigned found = 0; + + { + ifstream fbuf("istream_unformatted-1.txt"); + + in_iterator_type beg(fbuf); + in_iterator_type end; + + for (;;) + { + beg = find(beg, end, '1'); + if (beg == end) + break; + + ++found; + VERIFY( *beg == '1' ); + + advance(beg, 9); + VERIFY( *beg == '0' ); + } + } + + { + ifstream fbuf("istream_unformatted-1.txt"); + + in_iterator_type beg(fbuf); + in_iterator_type end; + + beg = find(beg, end, '1'); + VERIFY( beg != end ); + VERIFY( *beg == '1' ); + + advance(beg, 9); + VERIFY( *beg == '0' ); + + unsigned line_length = 10; + while (*++beg != '1') + ++line_length; + + // Try to jump directly to the end through advance. + advance(beg, (found - 2) * line_length + 9); + VERIFY( *beg == '0' ); + VERIFY( find(beg, end, '1') == end ); + } +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2_neg.cc new file mode 100644 index 0000000..9d18778 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2_neg.cc @@ -0,0 +1,40 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<char> in_iterator_type; + in_iterator_type end1; + + advance(end1, 0); // Ok. + + advance(end1, 1); // Invalid. +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/3_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/3_neg.cc new file mode 100644 index 0000000..af2bed6 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/3_neg.cc @@ -0,0 +1,43 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <sstream> +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<char> in_iterator_type; + + const char data1[] = "Drei Phantasien nach Friedrich Holderlin"; + const string str1(data1); + istringstream iss1(str1); + in_iterator_type beg1(iss1); + + advance(beg1, 50); // Invalid +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1.cc new file mode 100644 index 0000000..18839ca --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1.cc @@ -0,0 +1,56 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +#include <iterator> +#include <sstream> +#include <algorithm> +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<wchar_t> in_iterator_type; + + const wchar_t data1[] = L"Drei Phantasien nach Friedrich Holderlin"; + const wstring str1(data1); + wistringstream iss1(str1); + in_iterator_type beg1(iss1); + in_iterator_type end1; + + VERIFY( *beg1 == L'D' ); + + advance(beg1, 1); + + VERIFY( beg1 != end1 ); + VERIFY( *beg1 == L'r' ); + + advance(beg1, 0); + VERIFY( *beg1 == L'r' ); + + advance(beg1, 38); + VERIFY( *beg1 == L'n' ); + + advance(beg1, 1); + VERIFY( beg1 == end1 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1_neg.cc new file mode 100644 index 0000000..cd1b7a1 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1_neg.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<wchar_t> in_iterator_type; + in_iterator_type end1; + + advance(end1, -1); // Invalid -1 value. +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2.cc new file mode 100644 index 0000000..91cc939 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2.cc @@ -0,0 +1,82 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-require-fileio "" } + +#include <iterator> +#include <fstream> +#include <algorithm> + +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<wchar_t> in_iterator_type; + + unsigned found = 0; + + { + wifstream fbuf("istream_unformatted-1.txt"); + + in_iterator_type beg(fbuf); + in_iterator_type end; + + for (;;) + { + beg = find(beg, end, L'1'); + if (beg == end) + break; + + ++found; + VERIFY( *beg == L'1' ); + + advance(beg, 9); + VERIFY( *beg == L'0' ); + } + } + + { + wifstream fbuf("istream_unformatted-1.txt"); + + in_iterator_type beg(fbuf); + in_iterator_type end; + + beg = find(beg, end, L'1'); + VERIFY( beg != end ); + VERIFY( *beg == L'1' ); + + advance(beg, 9); + VERIFY( *beg == L'0' ); + + unsigned line_length = 10; + while (*++beg != L'1') + ++line_length; + + // Try to jump directly to the end through advance. + advance(beg, (found - 2) * line_length + 9); + VERIFY( *beg == L'0' ); + VERIFY( find(beg, end, L'1') == end ); + } +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2_neg.cc new file mode 100644 index 0000000..ea280f9 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2_neg.cc @@ -0,0 +1,40 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<wchar_t> in_iterator_type; + in_iterator_type end1; + + advance(end1, 0); // Ok. + + advance(end1, 1); // Invalid. +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/3_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/3_neg.cc new file mode 100644 index 0000000..c5bf122 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/3_neg.cc @@ -0,0 +1,43 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <sstream> +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<wchar_t> in_iterator_type; + + const wchar_t data1[] = L"Drei Phantasien nach Friedrich Holderlin"; + const wstring str1(data1); + wistringstream iss1(str1); + in_iterator_type beg1(iss1); + + advance(beg1, 50); // Invalid +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/char/2.cc b/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/char/2.cc index 125d597..b288787 100644 --- a/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/char/2.cc +++ b/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/char/2.cc @@ -46,8 +46,7 @@ void test01() ++found; VERIFY( *beg == '1' ); - for (unsigned sk = 0; sk < 9; sk++) - ++beg; + advance(beg, 9); VERIFY( *beg == '0' ); } VERIFY( found == 1500 ); diff --git a/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc b/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc index e8d2b88..6393f49 100644 --- a/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc +++ b/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc @@ -44,8 +44,7 @@ void test01() ++found; VERIFY( *beg == L'1' ); - for (unsigned sk = 0; sk < 9; sk++) - ++beg; + advance(beg, 9); VERIFY( *beg == L'0' ); } VERIFY( found == 1500 );
2017-11-13 21:23 GMT+01:00 François Dumont <frs.dumont@gmail.com>: > On 10/11/2017 21:57, Jonathan Wakely wrote: >>> diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h >>> b/libstdc++-v3/include/bits/streambuf_iterator.h >>> index 0a6c7f9..b60626a 100644 >>> --- a/libstdc++-v3/include/bits/streambuf_iterator.h >>> +++ b/libstdc++-v3/include/bits/streambuf_iterator.h >>> @@ -417,6 +421,55 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >>> return __last; >>> } >>> >>> + template<typename _CharT, typename _Distance> >>> + inline _GLIBCXX17_CONSTEXPR void >> >> >> This function can never be constexpr. > > I just replicate the _GLIBCXX17_CONSTEXPR qualification of the general > std::advance overload. I am not clear about those different constexpr > concepts but I also found strange that it could be consider as such. The general std::advance function can be constexpr, depending on the actual iterator, e.g. #include <iterator> template<class T> constexpr T* next(T* p) { std::advance(p, 1); return p; } int main() { static int arr[2] = {1, 2}; constexpr int* p = next(arr); } but as Jonathan already said, for std::istreambuf_iterator<T> this can never be true (because of the involved IO operations). - Daniel
On Mon, Nov 13, 2017 at 3:32 PM, Daniel Krügler <daniel.kruegler@gmail.com> wrote: > but as Jonathan already said, for std::istreambuf_iterator<T> this can > never be true (because of the involved IO operations). > Except, of course, if you advance by zero. It's not a very useful case, for sure...
Here is the latest version I plan to commit after validation. I'd like to keep the change to the money_get/get/[char/wchar_t]/9.cc tests. At the moment those tests passes only because there is no operation on the is iterator (like a check for eof). If we add any, internal _M_buf will be reseted and tests will start to fail. Tested under Linux x86_64 normal and debug modes. Ok to commit ? François On 16/11/2017 21:06, Tim Song wrote: > On Mon, Nov 13, 2017 at 3:32 PM, Daniel Krügler > <daniel.kruegler@gmail.com> wrote: >> but as Jonathan already said, for std::istreambuf_iterator<T> this can >> never be true (because of the involved IO operations). >> > Except, of course, if you advance by zero. It's not a very useful > case, for sure... > diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h index 081afe5..98f29b4 100644 --- a/libstdc++-v3/include/bits/streambuf_iterator.h +++ b/libstdc++-v3/include/bits/streambuf_iterator.h @@ -86,6 +86,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, const _CharT2&); + template<typename _CharT2, typename _Distance> + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + void>::__type + advance(istreambuf_iterator<_CharT2>&, _Distance); + private: // 24.5.3 istreambuf_iterator // p 1 @@ -397,6 +402,49 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __first; } + template<typename _CharT, typename _Distance> + typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, + void>::__type + advance(istreambuf_iterator<_CharT>& __i, _Distance __n) + { + if (__n == 0) + return; + + __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) + { + __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_c = __eof; + } + // @} group iterators _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/std/streambuf b/libstdc++-v3/include/std/streambuf index a05b46e..c1fd395 100644 --- a/libstdc++-v3/include/std/streambuf +++ b/libstdc++-v3/include/std/streambuf @@ -159,6 +159,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, const _CharT2&); + template<typename _CharT2, typename _Distance> + friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, + void>::__type + advance(istreambuf_iterator<_CharT2>&, _Distance); + template<typename _CharT2, typename _Traits2> friend basic_istream<_CharT2, _Traits2>& operator>>(basic_istream<_CharT2, _Traits2>&, _CharT2*); diff --git a/libstdc++-v3/testsuite/22_locale/money_get/get/char/9.cc b/libstdc++-v3/testsuite/22_locale/money_get/get/char/9.cc index 9b69956..476e38f 100644 --- a/libstdc++-v3/testsuite/22_locale/money_get/get/char/9.cc +++ b/libstdc++-v3/testsuite/22_locale/money_get/get/char/9.cc @@ -41,7 +41,6 @@ int main() = std::use_facet<std::money_get<char> >(liffey.getloc()); typedef std::istreambuf_iterator<char> iterator_type; - iterator_type is(liffey); iterator_type end; std::ios_base::iostate err01 = std::ios_base::goodbit; @@ -50,7 +49,7 @@ int main() // Feed it 1 digit too many, which should fail. liffey.str("12.3456"); - greed.get(is, end, false, liffey, err01, coins); + greed.get(liffey, end, false, liffey, err01, coins); if (! (err01 & std::ios_base::failbit )) fails |= 0x01; @@ -58,7 +57,7 @@ int main() // Feed it exactly what it wants, which should succeed. liffey.str("12.345"); - greed.get(is, end, false, liffey, err01, coins); + greed.get(liffey, end, false, liffey, err01, coins); if ( err01 & std::ios_base::failbit ) fails |= 0x02; @@ -66,7 +65,7 @@ int main() // Feed it 1 digit too few, which should fail. liffey.str("12.34"); - greed.get(is, end, false, liffey, err01, coins); + greed.get(liffey, end, false, liffey, err01, coins); if (! ( err01 & std::ios_base::failbit )) fails |= 0x04; @@ -74,7 +73,7 @@ int main() // Feed it only a decimal-point, which should fail. liffey.str("12."); - greed.get(is, end, false, liffey, err01, coins); + greed.get(liffey, end, false, liffey, err01, coins); if (! (err01 & std::ios_base::failbit )) fails |= 0x08; @@ -82,7 +81,7 @@ int main() // Feed it no decimal-point at all, which should succeed. liffey.str("12"); - greed.get(is, end, false, liffey, err01, coins); + greed.get(liffey, end, false, liffey, err01, coins); if ( err01 & std::ios_base::failbit ) fails |= 0x10; diff --git a/libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/9.cc b/libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/9.cc index a08a713..e5f8def 100644 --- a/libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/9.cc +++ b/libstdc++-v3/testsuite/22_locale/money_get/get/wchar_t/9.cc @@ -41,7 +41,6 @@ int main() = std::use_facet<std::money_get<wchar_t> >(liffey.getloc()); typedef std::istreambuf_iterator<wchar_t> iterator_type; - iterator_type is(liffey); iterator_type end; std::ios_base::iostate err01 = std::ios_base::goodbit; @@ -50,7 +49,7 @@ int main() // Feed it 1 digit too many, which should fail. liffey.str(L"12.3456"); - greed.get(is, end, false, liffey, err01, coins); + greed.get(liffey, end, false, liffey, err01, coins); if (! (err01 & std::ios_base::failbit )) fails |= 0x01; @@ -58,7 +57,7 @@ int main() // Feed it exactly what it wants, which should succeed. liffey.str(L"12.345"); - greed.get(is, end, false, liffey, err01, coins); + greed.get(liffey, end, false, liffey, err01, coins); if ( err01 & std::ios_base::failbit ) fails |= 0x02; @@ -66,7 +65,7 @@ int main() // Feed it 1 digit too few, which should fail. liffey.str(L"12.34"); - greed.get(is, end, false, liffey, err01, coins); + greed.get(liffey, end, false, liffey, err01, coins); if (! ( err01 & std::ios_base::failbit )) fails |= 0x04; @@ -74,7 +73,7 @@ int main() // Feed it only a decimal-point, which should fail. liffey.str(L"12."); - greed.get(is, end, false, liffey, err01, coins); + greed.get(liffey, end, false, liffey, err01, coins); if (! (err01 & std::ios_base::failbit )) fails |= 0x08; @@ -82,7 +81,7 @@ int main() // Feed it no decimal-point at all, which should succeed. liffey.str(L"12"); - greed.get(is, end, false, liffey, err01, coins); + greed.get(liffey, end, false, liffey, err01, coins); if ( err01 & std::ios_base::failbit ) fails |= 0x10; diff --git a/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/debug/1_neg.cc b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/debug/1_neg.cc new file mode 100644 index 0000000..241fc58 --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/debug/1_neg.cc @@ -0,0 +1,35 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <iterator> + +void test01() +{ + typedef std::istreambuf_iterator<char> cistreambuf_iter; + + cistreambuf_iter eof; + ++eof; // Invalid. +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/debug/2_neg.cc b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/debug/2_neg.cc new file mode 100644 index 0000000..407f00b --- /dev/null +++ b/libstdc++-v3/testsuite/24_iterators/istreambuf_iterator/debug/2_neg.cc @@ -0,0 +1,35 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <iterator> + +void test01() +{ + typedef std::istreambuf_iterator<char> cistreambuf_iter; + + cistreambuf_iter eof; + eof++; // Invalid. +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1.cc new file mode 100644 index 0000000..7c3f882 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1.cc @@ -0,0 +1,56 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +#include <iterator> +#include <sstream> +#include <algorithm> +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<char> in_iterator_type; + + const char data1[] = "Drei Phantasien nach Friedrich Holderlin"; + const string str1(data1); + istringstream iss1(str1); + in_iterator_type beg1(iss1); + in_iterator_type end1; + + VERIFY( *beg1 == 'D' ); + + advance(beg1, 1); + + VERIFY( beg1 != end1 ); + VERIFY( *beg1 == 'r' ); + + advance(beg1, 0); + VERIFY( *beg1 == 'r' ); + + advance(beg1, 38); + VERIFY( *beg1 == 'n' ); + + advance(beg1, 1); + VERIFY( beg1 == end1 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1_neg.cc new file mode 100644 index 0000000..d1b8cde --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1_neg.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<char> in_iterator_type; + in_iterator_type end1; + + advance(end1, -1); // Invalid -1 value. +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2.cc new file mode 100644 index 0000000..c99111e --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2.cc @@ -0,0 +1,82 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-require-fileio "" } + +#include <iterator> +#include <fstream> +#include <algorithm> + +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<char> in_iterator_type; + + unsigned found = 0; + + { + ifstream fbuf("istream_unformatted-1.txt"); + + in_iterator_type beg(fbuf); + in_iterator_type end; + + for (;;) + { + beg = find(beg, end, '1'); + if (beg == end) + break; + + ++found; + VERIFY( *beg == '1' ); + + advance(beg, 9); + VERIFY( *beg == '0' ); + } + } + + { + ifstream fbuf("istream_unformatted-1.txt"); + + in_iterator_type beg(fbuf); + in_iterator_type end; + + beg = find(beg, end, '1'); + VERIFY( beg != end ); + VERIFY( *beg == '1' ); + + advance(beg, 9); + VERIFY( *beg == '0' ); + + unsigned line_length = 10; + while (*++beg != '1') + ++line_length; + + // Try to jump directly to the end through advance. + advance(beg, (found - 2) * line_length + 9); + VERIFY( *beg == '0' ); + VERIFY( find(beg, end, '1') == end ); + } +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2_neg.cc new file mode 100644 index 0000000..9d18778 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2_neg.cc @@ -0,0 +1,40 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<char> in_iterator_type; + in_iterator_type end1; + + advance(end1, 0); // Ok. + + advance(end1, 1); // Invalid. +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/3_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/3_neg.cc new file mode 100644 index 0000000..af2bed6 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/3_neg.cc @@ -0,0 +1,43 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <sstream> +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<char> in_iterator_type; + + const char data1[] = "Drei Phantasien nach Friedrich Holderlin"; + const string str1(data1); + istringstream iss1(str1); + in_iterator_type beg1(iss1); + + advance(beg1, 50); // Invalid +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1.cc new file mode 100644 index 0000000..18839ca --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1.cc @@ -0,0 +1,56 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +#include <iterator> +#include <sstream> +#include <algorithm> +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<wchar_t> in_iterator_type; + + const wchar_t data1[] = L"Drei Phantasien nach Friedrich Holderlin"; + const wstring str1(data1); + wistringstream iss1(str1); + in_iterator_type beg1(iss1); + in_iterator_type end1; + + VERIFY( *beg1 == L'D' ); + + advance(beg1, 1); + + VERIFY( beg1 != end1 ); + VERIFY( *beg1 == L'r' ); + + advance(beg1, 0); + VERIFY( *beg1 == L'r' ); + + advance(beg1, 38); + VERIFY( *beg1 == L'n' ); + + advance(beg1, 1); + VERIFY( beg1 == end1 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1_neg.cc new file mode 100644 index 0000000..cd1b7a1 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1_neg.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<wchar_t> in_iterator_type; + in_iterator_type end1; + + advance(end1, -1); // Invalid -1 value. +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2.cc new file mode 100644 index 0000000..91cc939 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2.cc @@ -0,0 +1,82 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-require-fileio "" } + +#include <iterator> +#include <fstream> +#include <algorithm> + +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<wchar_t> in_iterator_type; + + unsigned found = 0; + + { + wifstream fbuf("istream_unformatted-1.txt"); + + in_iterator_type beg(fbuf); + in_iterator_type end; + + for (;;) + { + beg = find(beg, end, L'1'); + if (beg == end) + break; + + ++found; + VERIFY( *beg == L'1' ); + + advance(beg, 9); + VERIFY( *beg == L'0' ); + } + } + + { + wifstream fbuf("istream_unformatted-1.txt"); + + in_iterator_type beg(fbuf); + in_iterator_type end; + + beg = find(beg, end, L'1'); + VERIFY( beg != end ); + VERIFY( *beg == L'1' ); + + advance(beg, 9); + VERIFY( *beg == L'0' ); + + unsigned line_length = 10; + while (*++beg != L'1') + ++line_length; + + // Try to jump directly to the end through advance. + advance(beg, (found - 2) * line_length + 9); + VERIFY( *beg == L'0' ); + VERIFY( find(beg, end, L'1') == end ); + } +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2_neg.cc new file mode 100644 index 0000000..ea280f9 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2_neg.cc @@ -0,0 +1,40 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<wchar_t> in_iterator_type; + in_iterator_type end1; + + advance(end1, 0); // Ok. + + advance(end1, 1); // Invalid. +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/3_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/3_neg.cc new file mode 100644 index 0000000..c5bf122 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/3_neg.cc @@ -0,0 +1,43 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <sstream> +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<wchar_t> in_iterator_type; + + const wchar_t data1[] = L"Drei Phantasien nach Friedrich Holderlin"; + const wstring str1(data1); + wistringstream iss1(str1); + in_iterator_type beg1(iss1); + + advance(beg1, 50); // Invalid +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/char/2.cc b/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/char/2.cc index 125d597..b288787 100644 --- a/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/char/2.cc +++ b/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/char/2.cc @@ -46,8 +46,7 @@ void test01() ++found; VERIFY( *beg == '1' ); - for (unsigned sk = 0; sk < 9; sk++) - ++beg; + advance(beg, 9); VERIFY( *beg == '0' ); } VERIFY( found == 1500 ); diff --git a/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc b/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc index e8d2b88..6393f49 100644 --- a/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc +++ b/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc @@ -44,8 +44,7 @@ void test01() ++found; VERIFY( *beg == L'1' ); - for (unsigned sk = 0; sk < 9; sk++) - ++beg; + advance(beg, 9); VERIFY( *beg == L'0' ); } VERIFY( found == 1500 );
On 20/11/17 07:40 +0100, François Dumont wrote: >Here is the latest version I plan to commit after validation. I like the simplified logic for the while-loop. >I'd like to keep the change to the money_get/get/[char/wchar_t]/9.cc >tests. At the moment those tests passes only because there is no >operation on the is iterator (like a check for eof). If we add any, >internal _M_buf will be reseted and tests will start to fail. Those changes seem useful then, thanks. >Tested under Linux x86_64 normal and debug modes. > >Ok to commit ? OK for trunk, thanks!
diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h index 0a6c7f9..b60626a 100644 --- a/libstdc++-v3/include/bits/streambuf_iterator.h +++ b/libstdc++-v3/include/bits/streambuf_iterator.h @@ -86,6 +86,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, const _CharT2&); + template<typename _CharT2, typename _Distance> + friend void _GLIBCXX17_CONSTEXPR + advance(istreambuf_iterator<_CharT2>&, _Distance); + private: // 24.5.3 istreambuf_iterator // p 1 @@ -417,6 +421,55 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __last; } + template<typename _CharT, typename _Distance> + inline _GLIBCXX17_CONSTEXPR void + advance(istreambuf_iterator<_CharT>& __i, _Distance __n) + { + if (__n == 0) + return; + + __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; + int_type __c = __sb->sgetc(); + while (__n && !traits_type::eq_int_type(__c, __eof)) + { + streamsize __size = __sb->egptr() - __sb->gptr(); + if (__size > __n) + { + __sb->__safe_gbump(__n); + __n = 0; + } + else if (__size > 1) + { + __sb->__safe_gbump(__size); + __n -= __size; + __c = __sb->underflow(); + } + else + { + --__n; + __c = __sb->snextc(); + } + } + + __glibcxx_requires_cond(__n == 0, + _M_message(__gnu_debug::__msg_inc_istreambuf) + ._M_iterator(__i)); + __i._M_c = __eof; + if (traits_type::eq_int_type(__c, __eof)) + __i._M_sbuf = 0; + } + // @} group iterators _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/std/streambuf b/libstdc++-v3/include/std/streambuf index a05b46e..da92199 100644 --- a/libstdc++-v3/include/std/streambuf +++ b/libstdc++-v3/include/std/streambuf @@ -159,6 +159,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION find(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, const _CharT2&); + template<typename _CharT2, typename _Distance> + friend _GLIBCXX17_CONSTEXPR void + advance(istreambuf_iterator<_CharT2>&, _Distance); + template<typename _CharT2, typename _Traits2> friend basic_istream<_CharT2, _Traits2>& operator>>(basic_istream<_CharT2, _Traits2>&, _CharT2*); diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1.cc new file mode 100644 index 0000000..7c3f882 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1.cc @@ -0,0 +1,56 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +#include <iterator> +#include <sstream> +#include <algorithm> +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<char> in_iterator_type; + + const char data1[] = "Drei Phantasien nach Friedrich Holderlin"; + const string str1(data1); + istringstream iss1(str1); + in_iterator_type beg1(iss1); + in_iterator_type end1; + + VERIFY( *beg1 == 'D' ); + + advance(beg1, 1); + + VERIFY( beg1 != end1 ); + VERIFY( *beg1 == 'r' ); + + advance(beg1, 0); + VERIFY( *beg1 == 'r' ); + + advance(beg1, 38); + VERIFY( *beg1 == 'n' ); + + advance(beg1, 1); + VERIFY( beg1 == end1 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1_neg.cc new file mode 100644 index 0000000..d1b8cde --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/1_neg.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<char> in_iterator_type; + in_iterator_type end1; + + advance(end1, -1); // Invalid -1 value. +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2.cc new file mode 100644 index 0000000..c99111e --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2.cc @@ -0,0 +1,82 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-require-fileio "" } + +#include <iterator> +#include <fstream> +#include <algorithm> + +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<char> in_iterator_type; + + unsigned found = 0; + + { + ifstream fbuf("istream_unformatted-1.txt"); + + in_iterator_type beg(fbuf); + in_iterator_type end; + + for (;;) + { + beg = find(beg, end, '1'); + if (beg == end) + break; + + ++found; + VERIFY( *beg == '1' ); + + advance(beg, 9); + VERIFY( *beg == '0' ); + } + } + + { + ifstream fbuf("istream_unformatted-1.txt"); + + in_iterator_type beg(fbuf); + in_iterator_type end; + + beg = find(beg, end, '1'); + VERIFY( beg != end ); + VERIFY( *beg == '1' ); + + advance(beg, 9); + VERIFY( *beg == '0' ); + + unsigned line_length = 10; + while (*++beg != '1') + ++line_length; + + // Try to jump directly to the end through advance. + advance(beg, (found - 2) * line_length + 9); + VERIFY( *beg == '0' ); + VERIFY( find(beg, end, '1') == end ); + } +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2_neg.cc new file mode 100644 index 0000000..9d18778 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/2_neg.cc @@ -0,0 +1,40 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<char> in_iterator_type; + in_iterator_type end1; + + advance(end1, 0); // Ok. + + advance(end1, 1); // Invalid. +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/3_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/3_neg.cc new file mode 100644 index 0000000..af2bed6 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/char/3_neg.cc @@ -0,0 +1,43 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <sstream> +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<char> in_iterator_type; + + const char data1[] = "Drei Phantasien nach Friedrich Holderlin"; + const string str1(data1); + istringstream iss1(str1); + in_iterator_type beg1(iss1); + + advance(beg1, 50); // Invalid +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1.cc new file mode 100644 index 0000000..18839ca --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1.cc @@ -0,0 +1,56 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +#include <iterator> +#include <sstream> +#include <algorithm> +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<wchar_t> in_iterator_type; + + const wchar_t data1[] = L"Drei Phantasien nach Friedrich Holderlin"; + const wstring str1(data1); + wistringstream iss1(str1); + in_iterator_type beg1(iss1); + in_iterator_type end1; + + VERIFY( *beg1 == L'D' ); + + advance(beg1, 1); + + VERIFY( beg1 != end1 ); + VERIFY( *beg1 == L'r' ); + + advance(beg1, 0); + VERIFY( *beg1 == L'r' ); + + advance(beg1, 38); + VERIFY( *beg1 == L'n' ); + + advance(beg1, 1); + VERIFY( beg1 == end1 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1_neg.cc new file mode 100644 index 0000000..cd1b7a1 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/1_neg.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<wchar_t> in_iterator_type; + in_iterator_type end1; + + advance(end1, -1); // Invalid -1 value. +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2.cc new file mode 100644 index 0000000..91cc939 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2.cc @@ -0,0 +1,82 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-require-fileio "" } + +#include <iterator> +#include <fstream> +#include <algorithm> + +#include <testsuite_hooks.h> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<wchar_t> in_iterator_type; + + unsigned found = 0; + + { + wifstream fbuf("istream_unformatted-1.txt"); + + in_iterator_type beg(fbuf); + in_iterator_type end; + + for (;;) + { + beg = find(beg, end, L'1'); + if (beg == end) + break; + + ++found; + VERIFY( *beg == L'1' ); + + advance(beg, 9); + VERIFY( *beg == L'0' ); + } + } + + { + wifstream fbuf("istream_unformatted-1.txt"); + + in_iterator_type beg(fbuf); + in_iterator_type end; + + beg = find(beg, end, L'1'); + VERIFY( beg != end ); + VERIFY( *beg == L'1' ); + + advance(beg, 9); + VERIFY( *beg == L'0' ); + + unsigned line_length = 10; + while (*++beg != L'1') + ++line_length; + + // Try to jump directly to the end through advance. + advance(beg, (found - 2) * line_length + 9); + VERIFY( *beg == L'0' ); + VERIFY( find(beg, end, L'1') == end ); + } +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2_neg.cc new file mode 100644 index 0000000..ea280f9 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/2_neg.cc @@ -0,0 +1,40 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<wchar_t> in_iterator_type; + in_iterator_type end1; + + advance(end1, 0); // Ok. + + advance(end1, 1); // Invalid. +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/3_neg.cc b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/3_neg.cc new file mode 100644 index 0000000..c5bf122 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/advance/istreambuf_iterators/wchar_t/3_neg.cc @@ -0,0 +1,43 @@ +// Copyright (C) 2017 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 +// <http://www.gnu.org/licenses/>. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include <sstream> +#include <iterator> +#include <algorithm> + +void test01() +{ + using namespace std; + + typedef istreambuf_iterator<wchar_t> in_iterator_type; + + const wchar_t data1[] = L"Drei Phantasien nach Friedrich Holderlin"; + const wstring str1(data1); + wistringstream iss1(str1); + in_iterator_type beg1(iss1); + + advance(beg1, 50); // Invalid +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/char/2.cc b/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/char/2.cc index 125d597..b288787 100644 --- a/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/char/2.cc +++ b/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/char/2.cc @@ -46,8 +46,7 @@ void test01() ++found; VERIFY( *beg == '1' ); - for (unsigned sk = 0; sk < 9; sk++) - ++beg; + advance(beg, 9); VERIFY( *beg == '0' ); } VERIFY( found == 1500 ); diff --git a/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc b/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc index e8d2b88..6393f49 100644 --- a/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc +++ b/libstdc++-v3/testsuite/25_algorithms/find/istreambuf_iterators/wchar_t/2.cc @@ -44,8 +44,7 @@ void test01() ++found; VERIFY( *beg == L'1' ); - for (unsigned sk = 0; sk < 9; sk++) - ++beg; + advance(beg, 9); VERIFY( *beg == L'0' ); } VERIFY( found == 1500 );