PR libstdc++/91748 fix std::for_each_n for random access iterators
authorJonathan Wakely <jwakely@redhat.com>
Thu, 12 Sep 2019 10:51:39 +0000 (11:51 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 12 Sep 2019 10:51:39 +0000 (11:51 +0100)
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
libstdc++-v3/include/bits/stl_algo.h
libstdc++-v3/testsuite/25_algorithms/for_each/for_each_n.cc

index 1d01e8c467dda713992cee73687b8e16876b12ac..3984e9968f6942eb55facc1e63ee5e377fcb0b12 100644 (file)
@@ -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__):
index bece93379de2071994782ec09db2b16a2dca156f..7fe1d8a57340f1aae6e13c5026aeaf2d4e063f1a 100644 (file)
@@ -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)
index 57c2bbe6d3639f965b7c7703b14c16c6802dbe1c..016ff57cb2874dbc0d3a8e82a96564fc68f7372f 100644 (file)
@@ -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();
 }