From: Jonathan Wakely Date: Thu, 12 Sep 2019 10:51:58 +0000 (+0100) Subject: PR libstdc++/91748 fix std::for_each_n for random access iterators X-Git-Tag: releases/gcc-9.3.0~629 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=506bcbef00a872f844aad894d6ea991d6dba771a;p=thirdparty%2Fgcc.git 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: r275684 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index a6253ad59aab..33e56ea9c8f7 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 2d187b9eb9f4..4746d91c217b 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -3897,7 +3897,11 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO typename iterator_traits<_InputIterator>::difference_type __n2 = __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 57c2bbe6d363..016ff57cb287 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(); }