aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-09-12 11:51:39 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2019-09-12 11:51:39 +0100
commit52f6afe06dd86a25b41688ad12dd124b23f27833 (patch)
tree571e610703702655d902c08dad36f7aa176b4df9
parent58cc98767aa1d8136d36467b892dc4adaf427acc (diff)
downloadgcc-52f6afe06dd86a25b41688ad12dd124b23f27833.zip
gcc-52f6afe06dd86a25b41688ad12dd124b23f27833.tar.gz
gcc-52f6afe06dd86a25b41688ad12dd124b23f27833.tar.bz2
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
-rw-r--r--libstdc++-v3/ChangeLog8
-rw-r--r--libstdc++-v3/include/bits/stl_algo.h6
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/for_each/for_each_n.cc33
3 files changed, 45 insertions, 2 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 1d01e8c..3984e99 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 bece933..7fe1d8a 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 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();
}