From 8ab38f6cbc16025515571cd40f0f0d872d39c5ba Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Dumont?= Date: Sun, 6 Oct 2019 15:29:04 +0000 Subject: [PATCH] Add std::copy_n istreambuf_iterator specialization * include/bits/stl_algo.h (__copy_n_a(_IIte, _Size, _OIte)): New. (__copy_n_a(istreambuf_iterator<>, _Size, _CharT*)): New declaration. (__copy_n(_IIte, _Size, _OIte, input_iterator_tag)): Adapt to use latter. * include/bits/streambuf_iterator.h (istreambuf_iterator<>): Declare std::__copy_n_a friend. (__copy_n_a(istreambuf_iterator<>, _Size, _CharT*)): New. * testsuite/25_algorithms/copy_n/istreambuf_iterator/1.cc: New. * testsuite/25_algorithms/copy_n/istreambuf_iterator/1_neg.cc: New. * testsuite/25_algorithms/copy_n/istreambuf_iterator/2_neg.cc: New. From-SVN: r276638 --- libstdc++-v3/ChangeLog | 12 +++ libstdc++-v3/include/bits/stl_algo.h | 2 +- .../include/bits/streambuf_iterator.h | 26 +++++++ .../copy_n/istreambuf_iterator/1.cc | 73 +++++++++++++++++++ .../copy_n/istreambuf_iterator/1_neg.cc | 40 ++++++++++ .../copy_n/istreambuf_iterator/2_neg.cc | 38 ++++++++++ 6 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 libstdc++-v3/testsuite/25_algorithms/copy_n/istreambuf_iterator/1.cc create mode 100644 libstdc++-v3/testsuite/25_algorithms/copy_n/istreambuf_iterator/1_neg.cc create mode 100644 libstdc++-v3/testsuite/25_algorithms/copy_n/istreambuf_iterator/2_neg.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 40d9081a3c8..e0d3fd5f3a9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,17 @@ 2019-10-06 François Dumont + * include/bits/stl_algo.h + (__copy_n_a(_IIte, _Size, _OIte)): New. + (__copy_n_a(istreambuf_iterator<>, _Size, _CharT*)): New declaration. + (__copy_n(_IIte, _Size, _OIte, input_iterator_tag)): Adapt to use + latter. + * include/bits/streambuf_iterator.h (istreambuf_iterator<>): Declare + std::__copy_n_a friend. + (__copy_n_a(istreambuf_iterator<>, _Size, _CharT*)): New. + * testsuite/25_algorithms/copy_n/istreambuf_iterator/1.cc: New. + * testsuite/25_algorithms/copy_n/istreambuf_iterator/1_neg.cc: New. + * testsuite/25_algorithms/copy_n/istreambuf_iterator/2_neg.cc: New. + * include/bits/stl_iterator_base_types.h (__iterator_category_t): Define for C++11. (_RequireInputIte): Likewise and use __enable_if_t. diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index 6dd01e1943c..187c732d304 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -880,7 +880,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false); } -#endif +#endif // C++11 template _GLIBCXX20_CONSTEXPR diff --git a/libstdc++-v3/include/bits/streambuf_iterator.h b/libstdc++-v3/include/bits/streambuf_iterator.h index 2f4ff494a3a..e3e8736e768 100644 --- a/libstdc++-v3/include/bits/streambuf_iterator.h +++ b/libstdc++-v3/include/bits/streambuf_iterator.h @@ -80,6 +80,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __copy_move_a2(istreambuf_iterator<_CharT2>, istreambuf_iterator<_CharT2>, _CharT2*); +#if __cplusplus >= 201103L + template + friend __enable_if_t<__is_char<_CharT2>::__value, _CharT2*> + __copy_n_a(istreambuf_iterator<_CharT2>, _Size, _CharT2*); +#endif + template friend typename __gnu_cxx::__enable_if<__is_char<_CharT2>::__value, istreambuf_iterator<_CharT2> >::__type @@ -367,6 +373,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __result; } +#if __cplusplus >= 201103L + template + __enable_if_t<__is_char<_CharT>::__value, _CharT*> + __copy_n_a(istreambuf_iterator<_CharT> __it, _Size __n, _CharT* __result) + { + if (__n == 0) + return __result; + + __glibcxx_requires_cond(__it._M_sbuf, + _M_message(__gnu_debug::__msg_inc_istreambuf) + ._M_iterator(__it)); + _CharT* __beg = __result; + __result += __it._M_sbuf->sgetn(__beg, __n); + __glibcxx_requires_cond(__result - __beg == __n, + _M_message(__gnu_debug::__msg_inc_istreambuf) + ._M_iterator(__it)); + return __result; + } +#endif // C++11 + template typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, istreambuf_iterator<_CharT> >::__type diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_n/istreambuf_iterator/1.cc b/libstdc++-v3/testsuite/25_algorithms/copy_n/istreambuf_iterator/1.cc new file mode 100644 index 00000000000..87d37b6b9ca --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy_n/istreambuf_iterator/1.cc @@ -0,0 +1,73 @@ +// Copyright (C) 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 +// . + +// { dg-do run { target c++11 } } + +#include +#include +#include + +#include + +void test01() +{ + std::stringstream ss("12345"); + + std::string ostr(5, '0'); + typedef std::istreambuf_iterator istrb_ite; + auto res = std::copy_n(istrb_ite(ss), 0, ostr.begin()); + VERIFY( res == ostr.begin() ); + VERIFY( ostr.front() == '0' ); + + res = std::copy_n(istrb_ite(ss), 2, ostr.begin()); + VERIFY( res == ostr.begin() + 2 ); + VERIFY( ostr == "12000" ); + + res = std::copy_n(istrb_ite(ss), 3, ostr.begin() + 2); + VERIFY( res == ostr.begin() + 5 ); + VERIFY( ostr == "12345" ); +} + +void test02() +{ + std::stringstream ss("12345"); + + std::string ostr(5, '0'); + typedef std::istreambuf_iterator istrb_ite; + + istrb_ite ibfit(ss); + auto res = std::copy_n(ibfit, 3, std::copy_n(ibfit, 2, ostr.begin())); + VERIFY( res == ostr.begin() + 5 ); + VERIFY( ostr == "12345" ); +} + +void test03() +{ + std::string ostr(5, '0'); + typedef std::istreambuf_iterator istrb_ite; + + auto res = std::copy_n(istrb_ite(), 0, ostr.begin()); + VERIFY( res == ostr.begin() ); +} + +int main() +{ + test01(); + test02(); + test03(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_n/istreambuf_iterator/1_neg.cc b/libstdc++-v3/testsuite/25_algorithms/copy_n/istreambuf_iterator/1_neg.cc new file mode 100644 index 00000000000..42bc5b64306 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy_n/istreambuf_iterator/1_neg.cc @@ -0,0 +1,40 @@ +// Copyright (C) 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 +// . + +// { dg-do run { target c++11 xfail *-*-* } } +// { dg-require-debug-mode { } } + +#include +#include +#include + +#include + +void test01() +{ + std::stringstream ss("12345"); + + std::string ostr(10, '0'); + typedef std::istreambuf_iterator istrb_ite; + std::copy_n(istrb_ite(ss), 10, ostr.begin()); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_n/istreambuf_iterator/2_neg.cc b/libstdc++-v3/testsuite/25_algorithms/copy_n/istreambuf_iterator/2_neg.cc new file mode 100644 index 00000000000..cede27a248d --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy_n/istreambuf_iterator/2_neg.cc @@ -0,0 +1,38 @@ +// Copyright (C) 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 +// . + +// { dg-do run { target c++11 xfail *-*-* } } +// { dg-require-debug-mode { } } + +#include +#include +#include + +#include + +void test01() +{ + std::string ostr(10, '0'); + typedef std::istreambuf_iterator istrb_ite; + std::copy_n(istrb_ite(), 10, ostr.begin()); +} + +int main() +{ + test01(); + return 0; +} -- 2.30.2