1 // -*- C++ -*-
2 // { dg-options "-std=gnu++17 -ltbb" }
3 // { dg-do run { target c++17 } }
4 // { dg-require-effective-target tbb-backend }
5
6 //===-- for_each.pass.cpp -------------------------------------------------===//
7 //
8 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
9 // See https://llvm.org/LICENSE.txt for license information.
10 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "pstl/pstl_test_config.h"
15
16 #ifdef PSTL_STANDALONE_TESTS
17 #include "pstl/execution"
18 #include "pstl/algorithm"
19 #else
20 #include <execution>
21 #include <algorithm>
22 #endif // PSTL_STANDALONE_TESTS
23
24 #include "pstl/test_utils.h"
25
26 using namespace TestUtils;
27
28 template <typename Type>
29 struct Gen
30 {
31 Type
operator ()Gen32 operator()(std::size_t k)
33 {
34 return Type(k % 5 != 1 ? 3 * k - 7 : 0);
35 };
36 };
37
38 template <typename T>
39 struct Flip
40 {
41 int32_t val;
FlipFlip42 Flip(int32_t y) : val(y) {}
43 T
operator ()Flip44 operator()(T& x) const
45 {
46 return x = val - x;
47 }
48 };
49
50 struct test_one_policy
51 {
52 template <typename Policy, typename Iterator, typename Size>
53 void
operator ()test_one_policy54 operator()(Policy&& exec, Iterator first, Iterator last, Iterator expected_first, Iterator expected_last, Size n)
55 {
56 typedef typename std::iterator_traits<Iterator>::value_type T;
57
58 // Try for_each
59 std::for_each(expected_first, expected_last, Flip<T>(1));
60 for_each(exec, first, last, Flip<T>(1));
61 EXPECT_EQ_N(expected_first, first, n, "wrong effect from for_each");
62
63 // Try for_each_n
64 std::for_each_n(__pstl::execution::seq, expected_first, n, Flip<T>(1));
65 for_each_n(exec, first, n, Flip<T>(1));
66 EXPECT_EQ_N(expected_first, first, n, "wrong effect from for_each_n");
67 }
68 };
69
70 template <typename T>
71 void
test()72 test()
73 {
74 for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
75 {
76 Sequence<T> inout(n, Gen<T>());
77 Sequence<T> expected(n, Gen<T>());
78 invoke_on_all_policies(test_one_policy(), inout.begin(), inout.end(), expected.begin(), expected.end(),
79 inout.size());
80 }
81 }
82
83 struct test_non_const
84 {
85 template <typename Policy, typename Iterator>
86 void
operator ()test_non_const87 operator()(Policy&& exec, Iterator iter)
88 {
89 invoke_if(exec, [&]() {
90 auto f = [](typename std::iterator_traits<Iterator>::reference x) { x = x + 1; };
91
92 for_each(exec, iter, iter, non_const(f));
93 for_each_n(exec, iter, 0, non_const(f));
94 });
95 }
96 };
97
98 int32_t
main()99 main()
100 {
101 test<int32_t>();
102 test<uint16_t>();
103 test<float64_t>();
104
105 test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const>());
106
107 std::cout << done() << std::endl;
108 return 0;
109 }
110