1 | // -*- C++ -*- |
2 | //===-- reverse_copy.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 <iterator> |
15 | #include <execution> |
16 | #include <algorithm> |
17 | |
18 | #include "support/utils.h" |
19 | |
20 | using namespace TestUtils; |
21 | |
22 | template <typename T> |
23 | struct wrapper |
24 | { |
25 | T t; |
26 | wrapper() {} |
27 | explicit wrapper(T t_) : t(t_) {} |
28 | wrapper& |
29 | operator=(const T& t_) |
30 | { |
31 | t = t_; |
32 | return *this; |
33 | } |
34 | bool |
35 | operator==(const wrapper& t_) const |
36 | { |
37 | return t == t_.t; |
38 | } |
39 | }; |
40 | |
41 | template <typename T1, typename T2> |
42 | bool |
43 | eq(const wrapper<T1>& a, const wrapper<T2>& b) |
44 | { |
45 | return a.t == b.t; |
46 | } |
47 | |
48 | template <typename T1, typename T2> |
49 | bool |
50 | eq(const T1& a, const T2& b) |
51 | { |
52 | return a == b; |
53 | } |
54 | |
55 | // we need to save state here, because we need to test with different types of iterators |
56 | // due to the caller invoke_on_all_policies does forcing modification passed iterator type to cover additional usage cases. |
57 | template <typename Iterator> |
58 | struct test_one_policy |
59 | { |
60 | Iterator data_b; |
61 | Iterator data_e; |
62 | test_one_policy(Iterator b, Iterator e) : data_b(b), data_e(e) {} |
63 | |
64 | #if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \ |
65 | defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) // dummy specialization by policy type, in case of broken configuration |
66 | template <typename Iterator1> |
67 | typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type |
68 | operator()(pstl::execution::unsequenced_policy, Iterator1 actual_b, Iterator1 actual_e) |
69 | { |
70 | } |
71 | template <typename Iterator1> |
72 | typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type |
73 | operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 actual_b, Iterator1 actual_e) |
74 | { |
75 | } |
76 | #endif |
77 | |
78 | template <typename ExecutionPolicy, typename Iterator1> |
79 | void |
80 | operator()(ExecutionPolicy&& exec, Iterator1 actual_b, Iterator1 actual_e) |
81 | { |
82 | using namespace std; |
83 | using T = typename iterator_traits<Iterator1>::value_type; |
84 | |
85 | fill(actual_b, actual_e, T(-123)); |
86 | Iterator1 actual_return = reverse_copy(exec, data_b, data_e, actual_b); |
87 | |
88 | EXPECT_TRUE(actual_return == actual_e, "wrong result of reverse_copy" ); |
89 | |
90 | const auto n = std::distance(data_b, data_e); |
91 | Sequence<T> res(n); |
92 | std::copy(std::reverse_iterator<Iterator>(data_e), std::reverse_iterator<Iterator>(data_b), res.begin()); |
93 | |
94 | EXPECT_EQ_N(res.begin(), actual_b, n, "wrong effect of reverse_copy" ); |
95 | } |
96 | }; |
97 | |
98 | template <typename T1, typename T2> |
99 | void |
100 | test() |
101 | { |
102 | typedef typename Sequence<T1>::iterator iterator_type; |
103 | typedef typename Sequence<T1>::const_bidirectional_iterator cbi_iterator_type; |
104 | |
105 | const std::size_t max_len = 100000; |
106 | |
107 | Sequence<T2> actual(max_len); |
108 | |
109 | Sequence<T1> data(max_len, [](std::size_t i) { return T1(i); }); |
110 | |
111 | for (std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : std::size_t(3.1415 * len)) |
112 | { |
113 | invoke_on_all_policies(test_one_policy<iterator_type>(data.begin(), data.begin() + len), actual.begin(), |
114 | actual.begin() + len); |
115 | invoke_on_all_policies(test_one_policy<cbi_iterator_type>(data.cbibegin(), std::next(data.cbibegin(), len)), |
116 | actual.begin(), actual.begin() + len); |
117 | } |
118 | } |
119 | |
120 | int |
121 | main() |
122 | { |
123 | test<int16_t, int8_t>(); |
124 | test<uint16_t, float32_t>(); |
125 | test<float64_t, int64_t>(); |
126 | test<wrapper<float64_t>, wrapper<float64_t>>(); |
127 | |
128 | std::cout << done() << std::endl; |
129 | return 0; |
130 | } |
131 | |