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