2 // { dg-options "-std=gnu++17 -ltbb" }
3 // { dg-do run { target c++17 } }
4 // { dg-require-effective-target tbb-backend }
6 //===-- partial_sort_copy.pass.cpp ----------------------------------------===//
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
12 //===----------------------------------------------------------------------===//
14 // Tests for partial_sort_copy
17 #include "pstl/pstl_test_config.h"
19 #ifdef PSTL_STANDALONE_TESTS
20 #include "pstl/execution"
21 #include "pstl/algorithm"
25 #endif // PSTL_STANDALONE_TESTS
27 #include "pstl/test_utils.h"
29 using namespace TestUtils
;
38 Num(const Num
<T
>& v
) : val(v
.val
) {}
39 Num(Num
<T
>&& v
) : val(v
.val
) {}
41 operator=(const Num
<T
>& v
)
46 operator T() const { return val
; }
48 operator<(const Num
<T
>& v
) const
54 template <typename RandomAccessIterator
>
55 struct test_one_policy
57 RandomAccessIterator d_first
;
58 RandomAccessIterator d_last
;
59 RandomAccessIterator exp_first
;
60 RandomAccessIterator exp_last
;
61 // This ctor is needed because output shouldn't be transformed to any iterator type (only random access iterators are allowed)
62 test_one_policy(RandomAccessIterator b1
, RandomAccessIterator e1
, RandomAccessIterator b2
, RandomAccessIterator e2
)
63 : d_first(b1
), d_last(e1
), exp_first(b2
), exp_last(e2
)
66 #if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
67 _PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specialization by policy type, in case of broken configuration
68 template <typename InputIterator
, typename Size
, typename T
, typename Compare
>
70 operator()(pstl::execution::unsequenced_policy
, InputIterator first
, InputIterator last
, Size n1
, Size n2
,
71 const T
& trash
, Compare compare
)
75 template <typename InputIterator
, typename Size
, typename T
, typename Compare
>
77 operator()(pstl::execution::parallel_unsequenced_policy
, InputIterator first
, InputIterator last
, Size n1
, Size n2
,
78 const T
& trash
, Compare compare
)
82 template <typename InputIterator
, typename Size
, typename T
>
84 operator()(pstl::execution::unsequenced_policy
, InputIterator first
, InputIterator last
, Size n1
, Size n2
,
89 template <typename InputIterator
, typename Size
, typename T
>
91 operator()(pstl::execution::parallel_unsequenced_policy
, InputIterator first
, InputIterator last
, Size n1
, Size n2
,
97 template <typename Policy
, typename InputIterator
, typename Size
, typename T
, typename Compare
>
99 operator()(Policy
&& exec
, InputIterator first
, InputIterator last
, Size n1
, Size n2
, const T
& trash
,
102 prepare_data(first
, last
, n1
, trash
);
103 RandomAccessIterator exp
= std::partial_sort_copy(first
, last
, exp_first
, exp_last
, compare
);
104 RandomAccessIterator res
= std::partial_sort_copy(exec
, first
, last
, d_first
, d_last
, compare
);
106 EXPECT_TRUE((exp
- exp_first
) == (res
- d_first
), "wrong result from partial_sort_copy with predicate");
107 EXPECT_EQ_N(exp_first
, d_first
, n2
, "wrong effect from partial_sort_copy with predicate");
110 template <typename Policy
, typename InputIterator
, typename Size
, typename T
>
112 operator()(Policy
&& exec
, InputIterator first
, InputIterator last
, Size n1
, Size n2
, const T
& trash
)
114 prepare_data(first
, last
, n1
, trash
);
115 RandomAccessIterator exp
= std::partial_sort_copy(first
, last
, exp_first
, exp_last
);
116 RandomAccessIterator res
= std::partial_sort_copy(exec
, first
, last
, d_first
, d_last
);
118 EXPECT_TRUE((exp
- exp_first
) == (res
- d_first
), "wrong result from partial_sort_copy without predicate");
119 EXPECT_EQ_N(exp_first
, d_first
, n2
, "wrong effect from partial_sort_copy without predicate");
123 template <typename InputIterator
, typename Size
, typename T
>
125 prepare_data(InputIterator first
, InputIterator last
, Size n1
, const T
& trash
)
127 // The rand()%(2*n+1) encourages generation of some duplicates.
129 std::generate(first
, last
, [n1
]() { return T(rand() % (2 * n1
+ 1)); });
131 std::fill(exp_first
, exp_last
, trash
);
132 std::fill(d_first
, d_last
, trash
);
136 template <typename T
, typename Compare
>
138 test_partial_sort_copy(Compare compare
)
141 typedef typename Sequence
<T
>::iterator iterator_type
;
142 const std::size_t n_max
= 100000;
143 Sequence
<T
> in(n_max
);
144 Sequence
<T
> out(2 * n_max
);
145 Sequence
<T
> exp(2 * n_max
);
149 for (; n1
< n_max
; n1
= n1
<= 16 ? n1
+ 1 : size_t(3.1415 * n1
))
151 // If both sequences are equal
153 invoke_on_all_policies(
154 test_one_policy
<iterator_type
>(out
.begin(), out
.begin() + n2
, exp
.begin(), exp
.begin() + n2
), in
.begin(),
155 in
.begin() + n1
, n1
, n2
, trash
, compare
);
157 // If first sequence is greater than second
159 invoke_on_all_policies(
160 test_one_policy
<iterator_type
>(out
.begin(), out
.begin() + n2
, exp
.begin(), exp
.begin() + n2
), in
.begin(),
161 in
.begin() + n1
, n1
, n2
, trash
, compare
);
163 // If first sequence is less than second
165 invoke_on_all_policies(
166 test_one_policy
<iterator_type
>(out
.begin(), out
.begin() + n2
, exp
.begin(), exp
.begin() + n2
), in
.begin(),
167 in
.begin() + n1
, n1
, n2
, trash
, compare
);
169 // Test partial_sort_copy without predicate
172 invoke_on_all_policies(test_one_policy
<iterator_type
>(out
.begin(), out
.begin() + n2
, exp
.begin(), exp
.begin() + n2
),
173 in
.begin(), in
.begin() + n1
, n1
, n2
, trash
);
176 template <typename T
>
177 struct test_non_const
179 template <typename Policy
, typename InputIterator
, typename OutputInterator
>
181 operator()(Policy
&& exec
, InputIterator input_iter
, OutputInterator out_iter
)
183 invoke_if(exec
, [&]() {
184 partial_sort_copy(exec
, input_iter
, input_iter
, out_iter
, out_iter
, non_const(std::less
<T
>()));
192 test_partial_sort_copy
<Num
<float32_t
>>([](Num
<float32_t
> x
, Num
<float32_t
> y
) { return x
< y
; });
193 test_partial_sort_copy
<int32_t>([](int32_t x
, int32_t y
) { return x
> y
; });
195 test_algo_basic_double
<int32_t>(run_for_rnd
<test_non_const
<int32_t>>());
197 std::cout
<< done() << std::endl
;