PR libstdc++/91748 fix std::for_each_n for random access iterators
diff mbox series

Message ID 20190912111904.GA29478@redhat.com
State New
Headers show
Series
  • PR libstdc++/91748 fix std::for_each_n for random access iterators
Related show

Commit Message

Jonathan Wakely Sept. 12, 2019, 11:19 a.m. UTC
This fixes two silly mistakes I made, which weren't caught by the
existing tests.

	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.

Tested powerpc64le-linux, committed to trunk and gcc-9-branch.
commit c3ae6f9b28e496d03e5c1a8eafd2a1169ef6ab65
Author: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Thu Sep 12 10:51:39 2019 +0000

    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.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@275683 138bc75d-0d04-0410-961f-82ee72b054a4

Patch
diff mbox series

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<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 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<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();
 }