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