2 //===-- rotate.pass.cpp ---------------------------------------------------===//
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
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: c++03, c++11, c++14
12 #include "support/pstl_test_config.h"
18 #include "support/utils.h"
20 using namespace TestUtils
;
27 explicit wrapper(T t_
) : t(t_
), move_count(0) {}
29 operator=(const T
& t_
)
35 wrapper(const wrapper
<T
>& a
) : move_count(0) { t
= a
.t
; }
38 operator=(wrapper
<T
>& a
)
45 operator=(wrapper
<T
>&& a
)
57 operator()(const T
& a
, const T
& b
)
64 struct compare
<wrapper
<T
>>
67 operator()(const wrapper
<T
>& a
, const wrapper
<T
>& b
)
74 struct test_one_policy
77 #if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
78 defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) // dummy specializations to skip testing in case of broken configuration
79 template <typename Iterator
, typename Size
>
81 operator()(pstl::execution::unsequenced_policy
, Iterator data_b
, Iterator data_e
, Iterator actual_b
,
82 Iterator actual_e
, Size shift
)
85 template <typename Iterator
, typename Size
>
87 operator()(pstl::execution::parallel_unsequenced_policy
, Iterator data_b
, Iterator data_e
, Iterator actual_b
,
88 Iterator actual_e
, Size shift
)
93 template <typename ExecutionPolicy
, typename Iterator
, typename Size
>
95 operator()(ExecutionPolicy
&& exec
, Iterator data_b
, Iterator data_e
, Iterator actual_b
, Iterator actual_e
,
99 using T
= typename iterator_traits
<Iterator
>::value_type
;
100 Iterator actual_m
= std::next(actual_b
, shift
);
102 copy(data_b
, data_e
, actual_b
);
103 Iterator actual_return
= rotate(exec
, actual_b
, actual_m
, actual_e
);
105 EXPECT_TRUE(actual_return
== std::next(actual_b
, std::distance(actual_m
, actual_e
)), "wrong result of rotate");
106 auto comparator
= compare
<T
>();
107 bool check
= std::equal(actual_return
, actual_e
, data_b
, comparator
);
108 check
= check
&& std::equal(actual_b
, actual_return
, std::next(data_b
, shift
), comparator
);
110 EXPECT_TRUE(check
, "wrong effect of rotate");
111 EXPECT_TRUE(check_move(exec
, actual_b
, actual_e
, shift
), "wrong move test of rotate");
114 template <typename ExecutionPolicy
, typename Iterator
, typename Size
>
115 typename
std::enable_if
<
116 is_same_iterator_category
<Iterator
, std::random_access_iterator_tag
>::value
&&
117 !std::is_same
<ExecutionPolicy
, std::execution::sequenced_policy
>::value
&&
118 std::is_same
<typename
std::iterator_traits
<Iterator
>::value_type
, wrapper
<float32_t
>>::value
,
120 check_move(ExecutionPolicy
&&, Iterator b
, Iterator e
, Size shift
)
122 bool result
= all_of(b
, e
, [](wrapper
<float32_t
>& a
) {
123 bool temp
= a
.move_count
> 0;
127 return shift
== 0 || result
;
130 template <typename ExecutionPolicy
, typename Iterator
, typename Size
>
131 typename
std::enable_if
<
132 !(is_same_iterator_category
<Iterator
, std::random_access_iterator_tag
>::value
&&
133 !std::is_same
<ExecutionPolicy
, std::execution::sequenced_policy
>::value
&&
134 std::is_same
<typename
std::iterator_traits
<Iterator
>::value_type
, wrapper
<float32_t
>>::value
),
136 check_move(ExecutionPolicy
&&, Iterator
, Iterator
, Size
)
142 template <typename T
>
146 const int32_t max_len
= 100000;
148 Sequence
<T
> actual(max_len
, [](std::size_t i
) { return T(i
); });
149 Sequence
<T
> data(max_len
, [](std::size_t i
) { return T(i
); });
151 for (int32_t len
= 0; len
< max_len
; len
= len
<= 16 ? len
+ 1 : int32_t(3.1415 * len
))
153 int32_t shifts
[] = {0, 1, 2, len
/ 3, (2 * len
) / 3, len
- 1};
154 for (auto shift
: shifts
)
156 if (shift
>= 0 && shift
< len
)
158 invoke_on_all_policies(test_one_policy(), data
.begin(), data
.begin() + len
, actual
.begin(),
159 actual
.begin() + len
, shift
);
169 test
<wrapper
<float64_t
>>();
170 test
<MemoryChecker
>();
171 EXPECT_FALSE(MemoryChecker::alive_objects() < 0, "wrong effect from rotate: number of ctors calls < num of dtors calls");
172 EXPECT_FALSE(MemoryChecker::alive_objects() > 0, "wrong effect from rotate: number of ctors calls > num of dtors calls");
174 std::cout
<< done() << std::endl
;