1 | // -*- C++ -*- |
2 | //===-- transform_unary.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 InputIterator, typename OutputIterator> |
22 | void |
23 | check_and_reset(InputIterator first, InputIterator last, OutputIterator out_first) |
24 | { |
25 | typedef typename std::iterator_traits<OutputIterator>::value_type Out; |
26 | typename std::iterator_traits<OutputIterator>::difference_type k = 0; |
27 | for (; first != last; ++first, ++out_first, ++k) |
28 | { |
29 | // check |
30 | Out expected = 1 - *first; |
31 | Out actual = *out_first; |
32 | EXPECT_EQ(expected, actual, "wrong value in output sequence" ); |
33 | // reset |
34 | *out_first = k % 7 != 4 ? 7 * k - 5 : 0; |
35 | } |
36 | } |
37 | |
38 | struct test_one_policy |
39 | { |
40 | template <typename Policy, typename InputIterator, typename OutputIterator, typename UnaryOp> |
41 | void |
42 | operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first, |
43 | OutputIterator out_last, UnaryOp op) |
44 | { |
45 | auto orr = std::transform(exec, first, last, out_first, op); |
46 | EXPECT_TRUE(out_last == orr, "transform returned wrong iterator" ); |
47 | check_and_reset(first, last, out_first); |
48 | } |
49 | }; |
50 | |
51 | template <typename Tin, typename Tout> |
52 | void |
53 | test() |
54 | { |
55 | for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n)) |
56 | { |
57 | Sequence<Tin> in(n, [](int32_t k) { return k % 5 != 1 ? 3 * k - 7 : 0; }); |
58 | |
59 | Sequence<Tout> out(n); |
60 | |
61 | const auto flip = Complement<Tin, Tout>(1); |
62 | invoke_on_all_policies(test_one_policy(), in.begin(), in.end(), out.begin(), out.end(), flip); |
63 | invoke_on_all_policies(test_one_policy(), in.cbegin(), in.cend(), out.begin(), out.end(), flip); |
64 | } |
65 | } |
66 | |
67 | template <typename T> |
68 | struct test_non_const |
69 | { |
70 | template <typename Policy, typename InputIterator, typename OutputInterator> |
71 | void |
72 | operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter) |
73 | { |
74 | invoke_if(exec, [&]() { transform(exec, input_iter, input_iter, out_iter, non_const(std::negate<T>())); }); |
75 | } |
76 | }; |
77 | |
78 | int |
79 | main() |
80 | { |
81 | test<int32_t, int32_t>(); |
82 | test<int32_t, float32_t>(); |
83 | test<uint16_t, float32_t>(); |
84 | test<float32_t, float64_t>(); |
85 | test<float64_t, float64_t>(); |
86 | |
87 | test_algo_basic_double<int32_t>(f: run_for_rnd_fw<test_non_const<int32_t>>()); |
88 | |
89 | std::cout << done() << std::endl; |
90 | return 0; |
91 | } |
92 | |