2 //===-- unique.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
13 #include "support/pstl_test_config.h"
18 #include "support/utils.h"
20 using namespace TestUtils
;
24 #if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
25 defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) //dummy specialization by policy type, in case of broken configuration
26 template <typename ForwardIt
, typename Generator
>
28 operator()(pstl::execution::unsequenced_policy
, ForwardIt first1
, ForwardIt last1
, ForwardIt first2
,
29 ForwardIt last2
, Generator generator
)
33 template <typename ForwardIt
, typename Generator
>
35 operator()(pstl::execution::parallel_unsequenced_policy
, ForwardIt first1
, ForwardIt last1
, ForwardIt first2
,
36 ForwardIt last2
, Generator generator
)
40 template <typename ForwardIt
, typename BinaryPred
, typename Generator
>
42 operator()(pstl::execution::unsequenced_policy
, ForwardIt first1
, ForwardIt last1
, ForwardIt first2
,
43 ForwardIt last2
, BinaryPred pred
, Generator generator
)
47 template <typename ForwardIt
, typename BinaryPred
, typename Generator
>
49 operator()(pstl::execution::parallel_unsequenced_policy
, ForwardIt first1
, ForwardIt last1
, ForwardIt first2
,
50 ForwardIt last2
, BinaryPred pred
, Generator generator
)
55 template <typename Policy
, typename ForwardIt
, typename Generator
>
57 operator()(Policy
&& exec
, ForwardIt first1
, ForwardIt last1
, ForwardIt first2
, ForwardIt last2
, Generator generator
)
62 fill_data(first1
, last1
, generator
);
63 fill_data(first2
, last2
, generator
);
65 ForwardIt i
= unique(first1
, last1
);
66 ForwardIt k
= unique(exec
, first2
, last2
);
68 auto n
= std::distance(first1
, i
);
69 EXPECT_TRUE(std::distance(first2
, k
) == n
, "wrong return value from unique without predicate");
70 EXPECT_EQ_N(first1
, first2
, n
, "wrong effect from unique without predicate");
73 template <typename Policy
, typename ForwardIt
, typename BinaryPred
, typename Generator
>
75 operator()(Policy
&& exec
, ForwardIt first1
, ForwardIt last1
, ForwardIt first2
, ForwardIt last2
, BinaryPred pred
,
81 fill_data(first1
, last1
, generator
);
82 fill_data(first2
, last2
, generator
);
84 ForwardIt i
= unique(first1
, last1
, pred
);
85 ForwardIt k
= unique(exec
, first2
, last2
, pred
);
87 auto n
= std::distance(first1
, i
);
88 EXPECT_TRUE(std::distance(first2
, k
) == n
, "wrong return value from unique with predicate");
89 EXPECT_EQ_N(first1
, first2
, n
, "wrong effect from unique with predicate");
93 template <typename T
, typename Generator
, typename Predicate
>
95 test(Generator generator
, Predicate pred
)
97 const std::size_t max_size
= 1000000;
98 Sequence
<T
> in(max_size
, [](size_t v
) { return T(v
); });
99 Sequence
<T
> exp(max_size
, [](size_t v
) { return T(v
); });
101 for (size_t n
= 0; n
<= max_size
; n
= n
<= 16 ? n
+ 1 : size_t(3.1415 * n
))
103 invoke_on_all_policies(run_unique(), exp
.begin(), exp
.begin() + n
, in
.begin(), in
.begin() + n
, generator
);
104 invoke_on_all_policies(run_unique(), exp
.begin(), exp
.begin() + n
, in
.begin(), in
.begin() + n
, pred
, generator
);
108 template <typename T
>
113 explicit LocalWrapper(T k
) : my_val(k
) {}
114 LocalWrapper(LocalWrapper
&& input
) : my_val(std::move(input
.my_val
)) {}
116 operator=(LocalWrapper
&& input
)
118 my_val
= std::move(input
.my_val
);
122 operator==(const LocalWrapper
<T
>& x
, const LocalWrapper
<T
>& y
)
124 return x
.my_val
== y
.my_val
;
128 template <typename T
>
129 struct test_non_const
131 template <typename Policy
, typename Iterator
>
133 operator()(Policy
&& exec
, Iterator iter
)
135 invoke_if(exec
, [&]() { unique(exec
, iter
, iter
, non_const(std::equal_to
<T
>())); });
142 #if !defined(_PSTL_ICC_16_17_18_TEST_UNIQUE_MASK_RELEASE_BROKEN)
143 test
<int32_t>([](size_t j
) { return j
/ 3; },
144 [](const int32_t& val1
, const int32_t& val2
) { return val1
* val1
== val2
* val2
; });
145 test
<float64_t
>([](size_t) { return float64_t(1); },
146 [](const float64_t
& val1
, const float64_t
& val2
) { return val1
!= val2
; });
148 test
<LocalWrapper
<uint32_t>>([](size_t j
) { return LocalWrapper
<uint32_t>(j
); },
149 [](const LocalWrapper
<uint32_t>& val1
, const LocalWrapper
<uint32_t>& val2
) {
150 return val1
.my_val
!= val2
.my_val
;
153 test_algo_basic_single
<int32_t>(run_for_rnd_fw
<test_non_const
<int32_t>>());
156 [](std::size_t idx
){ return MemoryChecker
{std::int32_t(idx
/ 3)}; },
157 [](const MemoryChecker
& val1
, const MemoryChecker
& val2
){ return val1
.value() == val2
.value(); });
158 EXPECT_FALSE(MemoryChecker::alive_objects() < 0, "wrong effect from unique: number of ctors calls < num of dtors calls");
159 EXPECT_FALSE(MemoryChecker::alive_objects() > 0, "wrong effect from unique: number of ctors calls > num of dtors calls");
161 std::cout
<< done() << std::endl
;