From 52f6afe06dd86a25b41688ad12dd124b23f27833 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 12 Sep 2019 11:51:39 +0100 Subject: [PATCH] PR libstdc++/91748 fix std::for_each_n for random access iterators PR libstdc++/91748 * include/bits/stl_algo.h (for_each_n): Fix random access iterator case. * testsuite/25_algorithms/for_each/for_each_n.cc: Test with random access iterators. From-SVN: r275683 --- libstdc++-v3/ChangeLog | 8 +++++ libstdc++-v3/include/bits/stl_algo.h | 6 +++- .../25_algorithms/for_each/for_each_n.cc | 33 ++++++++++++++++++- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1d01e8c467d..3984e9968f6 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2019-09-12 Jonathan Wakely + + PR libstdc++/91748 + * include/bits/stl_algo.h (for_each_n): Fix random access iterator + case. + * testsuite/25_algorithms/for_each/for_each_n.cc: Test with random + access iterators. + 2019-09-11 Jonathan Wakely * python/libstdcxx/v6/xmethods.py (SharedPtrUseCountWorker.__call__): diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index bece93379de..7fe1d8a5734 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -3993,7 +3993,11 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO auto __n2 = std::__size_to_integer(__n); using _Cat = typename iterator_traits<_InputIterator>::iterator_category; if constexpr (is_base_of_v) - return std::for_each(__first, __first + __n2, __f); + { + auto __last = __first + __n2; + std::for_each(__first, __last, std::move(__f)); + return __last; + } else { while (__n2-->0) diff --git a/libstdc++-v3/testsuite/25_algorithms/for_each/for_each_n.cc b/libstdc++-v3/testsuite/25_algorithms/for_each/for_each_n.cc index 57c2bbe6d36..016ff57cb28 100644 --- a/libstdc++-v3/testsuite/25_algorithms/for_each/for_each_n.cc +++ b/libstdc++-v3/testsuite/25_algorithms/for_each/for_each_n.cc @@ -47,11 +47,42 @@ void test01() }; auto res = std::for_each_n(con.begin(), Size(con.size()), Func(sum)); - VERIFY( res.ptr == con.end().ptr ); + VERIFY( res == con.end() ); VERIFY( sum == 15 ); } +void +test02() +{ + using __gnu_test::test_container; + using __gnu_test::random_access_iterator_wrapper; + int array[5] = { 2, 4, 6, 8, 10 }; + test_container con(array); + + int prod = 1; + struct Func + { + Func(int& i) : i(i) { } + Func(Func&&) = default; + Func& operator=(Func&&) = delete; + void operator()(int n) const { i *= n; } + int& i; + }; + + struct Size + { + Size(short v) : val(v) { } + operator short() const { return val; } + short val; + }; + auto res = std::for_each_n(con.begin(), Size(con.size()), Func(prod)); + + VERIFY( res == con.end() ); + VERIFY( prod == 3840 ); +} + int main() { test01(); + test02(); } -- 2.30.2