2 // { dg-options "-std=gnu++17 -ltbb" }
3 // { dg-do run { target c++17 } }
4 // { dg-timeout-factor 3 }
5 // { dg-require-effective-target tbb-backend }
7 //===-- partial_sort_copy.pass.cpp ----------------------------------------===//
9 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
10 // See https://llvm.org/LICENSE.txt for license information.
11 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
13 //===----------------------------------------------------------------------===//
15 // Tests for partial_sort_copy
18 #include "pstl/pstl_test_config.h"
20 #ifdef PSTL_STANDALONE_TESTS
21 #include "pstl/execution"
22 #include "pstl/algorithm"
26 #endif // PSTL_STANDALONE_TESTS
28 #include "pstl/test_utils.h"
30 using namespace TestUtils
;
39 Num(const Num
<T
>& v
) : val(v
.val
) {}
40 Num(Num
<T
>&& v
) : val(v
.val
) {}
42 operator=(const Num
<T
>& v
)
47 operator T() const { return val
; }
49 operator<(const Num
<T
>& v
) const
55 template <typename RandomAccessIterator
>
56 struct test_one_policy
58 RandomAccessIterator d_first
;
59 RandomAccessIterator d_last
;
60 RandomAccessIterator exp_first
;
61 RandomAccessIterator exp_last
;
62 // This ctor is needed because output shouldn't be transformed to any iterator type (only random access iterators are allowed)
63 test_one_policy(RandomAccessIterator b1
, RandomAccessIterator e1
, RandomAccessIterator b2
, RandomAccessIterator e2
)
64 : d_first(b1
), d_last(e1
), exp_first(b2
), exp_last(e2
)
67 #if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
68 _PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specialization by policy type, in case of broken configuration
69 template <typename InputIterator
, typename Size
, typename T
, typename Compare
>
71 operator()(pstl::execution::unsequenced_policy
, InputIterator first
, InputIterator last
, Size n1
, Size n2
,
72 const T
& trash
, Compare compare
)
76 template <typename InputIterator
, typename Size
, typename T
, typename Compare
>
78 operator()(pstl::execution::parallel_unsequenced_policy
, InputIterator first
, InputIterator last
, Size n1
, Size n2
,
79 const T
& trash
, Compare compare
)
83 template <typename InputIterator
, typename Size
, typename T
>
85 operator()(pstl::execution::unsequenced_policy
, InputIterator first
, InputIterator last
, Size n1
, Size n2
,
90 template <typename InputIterator
, typename Size
, typename T
>
92 operator()(pstl::execution::parallel_unsequenced_policy
, InputIterator first
, InputIterator last
, Size n1
, Size n2
,
98 template <typename Policy
, typename InputIterator
, typename Size
, typename T
, typename Compare
>
100 operator()(Policy
&& exec
, InputIterator first
, InputIterator last
, Size n1
, Size n2
, const T
& trash
,
103 prepare_data(first
, last
, n1
, trash
);
104 RandomAccessIterator exp
= std::partial_sort_copy(first
, last
, exp_first
, exp_last
, compare
);
105 RandomAccessIterator res
= std::partial_sort_copy(exec
, first
, last
, d_first
, d_last
, compare
);
107 EXPECT_TRUE((exp
- exp_first
) == (res
- d_first
), "wrong result from partial_sort_copy with predicate");
108 EXPECT_EQ_N(exp_first
, d_first
, n2
, "wrong effect from partial_sort_copy with predicate");
111 template <typename Policy
, typename InputIterator
, typename Size
, typename T
>
113 operator()(Policy
&& exec
, InputIterator first
, InputIterator last
, Size n1
, Size n2
, const T
& trash
)
115 prepare_data(first
, last
, n1
, trash
);
116 RandomAccessIterator exp
= std::partial_sort_copy(first
, last
, exp_first
, exp_last
);
117 RandomAccessIterator res
= std::partial_sort_copy(exec
, first
, last
, d_first
, d_last
);
119 EXPECT_TRUE((exp
- exp_first
) == (res
- d_first
), "wrong result from partial_sort_copy without predicate");
120 EXPECT_EQ_N(exp_first
, d_first
, n2
, "wrong effect from partial_sort_copy without predicate");
124 template <typename InputIterator
, typename Size
, typename T
>
126 prepare_data(InputIterator first
, InputIterator last
, Size n1
, const T
& trash
)
128 // The rand()%(2*n+1) encourages generation of some duplicates.
130 std::generate(first
, last
, [n1
]() { return T(rand() % (2 * n1
+ 1)); });
132 std::fill(exp_first
, exp_last
, trash
);
133 std::fill(d_first
, d_last
, trash
);
137 template <typename T
, typename Compare
>
139 test_partial_sort_copy(Compare compare
)
142 typedef typename Sequence
<T
>::iterator iterator_type
;
143 const std::size_t n_max
= 100000;
144 Sequence
<T
> in(n_max
);
145 Sequence
<T
> out(2 * n_max
);
146 Sequence
<T
> exp(2 * n_max
);
150 for (; n1
< n_max
; n1
= n1
<= 16 ? n1
+ 1 : size_t(3.1415 * n1
))
152 // If both sequences are equal
154 invoke_on_all_policies(
155 test_one_policy
<iterator_type
>(out
.begin(), out
.begin() + n2
, exp
.begin(), exp
.begin() + n2
), in
.begin(),
156 in
.begin() + n1
, n1
, n2
, trash
, compare
);
158 // If first sequence is greater than second
160 invoke_on_all_policies(
161 test_one_policy
<iterator_type
>(out
.begin(), out
.begin() + n2
, exp
.begin(), exp
.begin() + n2
), in
.begin(),
162 in
.begin() + n1
, n1
, n2
, trash
, compare
);
164 // If first sequence is less than second
166 invoke_on_all_policies(
167 test_one_policy
<iterator_type
>(out
.begin(), out
.begin() + n2
, exp
.begin(), exp
.begin() + n2
), in
.begin(),
168 in
.begin() + n1
, n1
, n2
, trash
, compare
);
170 // Test partial_sort_copy without predicate
173 invoke_on_all_policies(test_one_policy
<iterator_type
>(out
.begin(), out
.begin() + n2
, exp
.begin(), exp
.begin() + n2
),
174 in
.begin(), in
.begin() + n1
, n1
, n2
, trash
);
177 template <typename T
>
178 struct test_non_const
180 template <typename Policy
, typename InputIterator
, typename OutputInterator
>
182 operator()(Policy
&& exec
, InputIterator input_iter
, OutputInterator out_iter
)
184 invoke_if(exec
, [&]() {
185 partial_sort_copy(exec
, input_iter
, input_iter
, out_iter
, out_iter
, non_const(std::less
<T
>()));
193 test_partial_sort_copy
<Num
<float32_t
>>([](Num
<float32_t
> x
, Num
<float32_t
> y
) { return x
< y
; });
194 test_partial_sort_copy
<int32_t>([](int32_t x
, int32_t y
) { return x
> y
; });
196 test_algo_basic_double
<int32_t>(run_for_rnd
<test_non_const
<int32_t>>());
198 std::cout
<< done() << std::endl
;