| 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 | |