[gcc/devel/omp/gcc-9] PR libstdc++/91748 fix std::for_each_n for random access iterators

Tobias Burnus burnus@gcc.gnu.org
Thu Mar 5 14:02:00 GMT 2020


https://gcc.gnu.org/g:506bcbef00a872f844aad894d6ea991d6dba771a

commit 506bcbef00a872f844aad894d6ea991d6dba771a
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Sep 12 11:51:58 2019 +0100

    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:
---
 libstdc++-v3/ChangeLog                             |  8 ++++++
 libstdc++-v3/include/bits/stl_algo.h               |  6 +++-
 .../testsuite/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 a6253ad..33e56ea 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,11 @@
+2019-09-12  Jonathan Wakely  <jwakely@redhat.com>
+
+	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  <jwakely@redhat.com>
 
 	* 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 2d187b9..4746d91 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<random_access_iterator_tag, _Cat>)
-	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 57c2bbe..016ff57 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<int, random_access_iterator_wrapper> 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();
 }



More information about the Libstdc++-cvs mailing list