228293ff7b3166705f11011c99251ae9c6dd1577
[gcc.git] / libstdc++-v3 / testsuite / 25_algorithms / pstl / alg_modifying_operations / rotate.cc
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 //===-- rotate.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 <iterator>
18
19 #include "pstl/execution"
20 #include "pstl/algorithm"
21 #else
22 #include <execution>
23 #include <algorithm>
24 #endif // PSTL_STANDALONE_TESTS
25
26 #include "pstl/test_utils.h"
27
28 using namespace TestUtils;
29
30 template <typename T>
31 struct wrapper
32 {
33 T t;
34 int move_count;
35 explicit wrapper(T t_) : t(t_), move_count(0) {}
36 wrapper&
37 operator=(const T& t_)
38 {
39 t = t_;
40 return *this;
41 }
42
43 wrapper(const wrapper<T>& a) : move_count(0) { t = a.t; }
44
45 wrapper<T>&
46 operator=(wrapper<T>& a)
47 {
48 t = a.t;
49 return *this;
50 }
51
52 wrapper<T>&
53 operator=(wrapper<T>&& a)
54 {
55 t = a.t;
56 move_count += 1;
57 return *this;
58 }
59 };
60
61 template <typename T>
62 struct compare
63 {
64 bool
65 operator()(const T& a, const T& b)
66 {
67 return a == b;
68 }
69 };
70
71 template <typename T>
72 struct compare<wrapper<T>>
73 {
74 bool
75 operator()(const wrapper<T>& a, const wrapper<T>& b)
76 {
77 return a.t == b.t;
78 }
79 };
80 #include <typeinfo>
81
82 struct test_one_policy
83 {
84
85 #if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
86 _PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specializations to skip testing in case of broken configuration
87 template <typename Iterator, typename Size>
88 void
89 operator()(__pstl::execution::unsequenced_policy, Iterator data_b, Iterator data_e, Iterator actual_b,
90 Iterator actual_e, Size shift)
91 {
92 }
93 template <typename Iterator, typename Size>
94 void
95 operator()(__pstl::execution::parallel_unsequenced_policy, Iterator data_b, Iterator data_e, Iterator actual_b,
96 Iterator actual_e, Size shift)
97 {
98 }
99 #endif
100
101 template <typename ExecutionPolicy, typename Iterator, typename Size>
102 void
103 operator()(ExecutionPolicy&& exec, Iterator data_b, Iterator data_e, Iterator actual_b, Iterator actual_e,
104 Size shift)
105 {
106 using namespace std;
107 using T = typename iterator_traits<Iterator>::value_type;
108 Iterator actual_m = std::next(actual_b, shift);
109
110 copy(data_b, data_e, actual_b);
111 Iterator actual_return = rotate(exec, actual_b, actual_m, actual_e);
112
113 EXPECT_TRUE(actual_return == std::next(actual_b, std::distance(actual_m, actual_e)), "wrong result of rotate");
114 auto comparator = compare<T>();
115 bool check = std::equal(actual_return, actual_e, data_b, comparator);
116 check = check && std::equal(actual_b, actual_return, std::next(data_b, shift), comparator);
117
118 EXPECT_TRUE(check, "wrong effect of rotate");
119 EXPECT_TRUE(check_move(exec, actual_b, actual_e, shift), "wrong move test of rotate");
120 }
121
122 template <typename ExecutionPolicy, typename Iterator, typename Size>
123 typename std::enable_if<
124 is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value &&
125 !std::is_same<ExecutionPolicy, __pstl::execution::sequenced_policy>::value &&
126 std::is_same<typename std::iterator_traits<Iterator>::value_type, wrapper<float32_t>>::value,
127 bool>::type
128 check_move(ExecutionPolicy&& exec, Iterator b, Iterator e, Size shift)
129 {
130 bool result = all_of(b, e, [](wrapper<float32_t>& a) {
131 bool temp = a.move_count > 0;
132 a.move_count = 0;
133 return temp;
134 });
135 return shift == 0 || result;
136 }
137
138 template <typename ExecutionPolicy, typename Iterator, typename Size>
139 typename std::enable_if<
140 !(is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value &&
141 !std::is_same<ExecutionPolicy, __pstl::execution::sequenced_policy>::value &&
142 std::is_same<typename std::iterator_traits<Iterator>::value_type, wrapper<float32_t>>::value),
143 bool>::type
144 check_move(ExecutionPolicy&& exec, Iterator b, Iterator e, Size shift)
145 {
146 return true;
147 }
148 };
149
150 template <typename T>
151 void
152 test()
153 {
154 const int32_t max_len = 100000;
155
156 Sequence<T> actual(max_len, [](std::size_t i) { return T(i); });
157 Sequence<T> data(max_len, [](std::size_t i) { return T(i); });
158
159 for (int32_t len = 0; len < max_len; len = len <= 16 ? len + 1 : int32_t(3.1415 * len))
160 {
161 int32_t shifts[] = {0, 1, 2, len / 3, (2 * len) / 3, len - 1};
162 for (auto shift : shifts)
163 {
164 if (shift >= 0 && shift < len)
165 {
166 invoke_on_all_policies(test_one_policy(), data.begin(), data.begin() + len, actual.begin(),
167 actual.begin() + len, shift);
168 }
169 }
170 }
171 }
172
173 int32_t
174 main()
175 {
176 test<int32_t>();
177 test<wrapper<float64_t>>();
178
179 std::cout << done() << std::endl;
180 return 0;
181 }