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 //===-- copy_if.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 copy_if and remove_copy_if
16 #include "pstl/pstl_test_config.h"
18 #ifdef PSTL_STANDALONE_TESTS
19 #include "pstl/execution"
20 #include "pstl/algorithm"
24 #endif // PSTL_STANDALONE_TESTS
26 #include "pstl/test_utils.h"
28 using namespace TestUtils
;
32 #if _PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN // dummy specializations to skip testing in case of broken configuration
33 template <typename InputIterator
, typename OutputIterator
, typename OutputIterator2
, typename Size
,
34 typename Predicate
, typename T
>
36 operator()(__pstl::execution::parallel_policy
, InputIterator first
, InputIterator last
, OutputIterator out_first
,
37 OutputIterator out_last
, OutputIterator2 expected_first
, OutputIterator2 expected_last
, Size n
,
38 Predicate pred
, T trash
)
41 template <typename InputIterator
, typename OutputIterator
, typename OutputIterator2
, typename Size
,
42 typename Predicate
, typename T
>
44 operator()(__pstl::execution::parallel_unsequenced_policy
, InputIterator first
, InputIterator last
,
45 OutputIterator out_first
, OutputIterator out_last
, OutputIterator2 expected_first
,
46 OutputIterator2 expected_last
, Size n
, Predicate pred
, T trash
)
51 template <typename Policy
, typename InputIterator
, typename OutputIterator
, typename OutputIterator2
, typename Size
,
52 typename Predicate
, typename T
>
54 operator()(Policy
&& exec
, InputIterator first
, InputIterator last
, OutputIterator out_first
,
55 OutputIterator out_last
, OutputIterator2 expected_first
, OutputIterator2 expected_last
, Size n
,
56 Predicate pred
, T trash
)
59 std::fill_n(expected_first
, n
, trash
);
60 std::fill_n(out_first
, n
, trash
);
63 auto i
= copy_if(first
, last
, expected_first
, pred
);
64 auto k
= copy_if(exec
, first
, last
, out_first
, pred
);
65 EXPECT_EQ_N(expected_first
, out_first
, n
, "wrong copy_if effect");
66 for (size_t j
= 0; j
< GuardSize
; ++j
)
70 EXPECT_TRUE(out_last
== k
, "wrong return value from copy_if");
73 std::fill_n(expected_first
, n
, trash
);
74 std::fill_n(out_first
, n
, trash
);
76 i
= remove_copy_if(first
, last
, expected_first
, [=](const T
& x
) { return !pred(x
); });
77 k
= remove_copy_if(exec
, first
, last
, out_first
, [=](const T
& x
) { return !pred(x
); });
78 EXPECT_EQ_N(expected_first
, out_first
, n
, "wrong remove_copy_if effect");
79 for (size_t j
= 0; j
< GuardSize
; ++j
)
83 EXPECT_TRUE(out_last
== k
, "wrong return value from remove_copy_if");
87 template <typename T
, typename Predicate
, typename Convert
>
89 test(T trash
, Predicate pred
, Convert convert
, bool check_weakness
= true)
91 // Try sequences of various lengths.
92 for (size_t n
= 0; n
<= 100000; n
= n
<= 16 ? n
+ 1 : size_t(3.1415 * n
))
94 // count is number of output elements, plus a handful
95 // more for sake of detecting buffer overruns.
96 size_t count
= GuardSize
;
97 Sequence
<T
> in(n
, [&](size_t k
) -> T
{
98 T val
= convert(n
^ k
);
99 count
+= pred(val
) ? 1 : 0;
103 Sequence
<T
> out(count
, [=](size_t) { return trash
; });
104 Sequence
<T
> expected(count
, [=](size_t) { return trash
; });
107 auto expected_result
= copy_if(in
.cfbegin(), in
.cfend(), expected
.begin(), pred
);
108 size_t m
= expected_result
- expected
.begin();
109 EXPECT_TRUE(n
/ 4 <= m
&& m
<= 3 * (n
+ 1) / 4, "weak test for copy_if");
111 invoke_on_all_policies(run_copy_if(), in
.begin(), in
.end(), out
.begin(), out
.end(), expected
.begin(),
112 expected
.end(), count
, pred
, trash
);
113 invoke_on_all_policies(run_copy_if(), in
.cbegin(), in
.cend(), out
.begin(), out
.end(), expected
.begin(),
114 expected
.end(), count
, pred
, trash
);
118 struct test_non_const
120 template <typename Policy
, typename InputIterator
, typename OutputInterator
>
122 operator()(Policy
&& exec
, InputIterator input_iter
, OutputInterator out_iter
)
124 auto is_even
= [&](float64_t v
) {
125 uint32_t i
= (uint32_t)v
;
128 copy_if(exec
, input_iter
, input_iter
, out_iter
, non_const(is_even
));
130 invoke_if(exec
, [&]() { remove_copy_if(exec
, input_iter
, input_iter
, out_iter
, non_const(is_even
)); });
137 test
<float64_t
>(-666.0, [](const float64_t
& x
) { return x
* x
<= 1024; },
138 [](size_t j
) { return ((j
+ 1) % 7 & 2) != 0 ? float64_t(j
% 32) : float64_t(j
% 33 + 34); });
140 test
<int32_t>(-666, [](const int32_t& x
) { return x
!= 42; },
141 [](size_t j
) { return ((j
+ 1) % 5 & 2) != 0 ? int32_t(j
+ 1) : 42; });
143 #if !_PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN
144 test
<Number
>(Number(42, OddTag()), IsMultiple(3, OddTag()), [](int32_t j
) { return Number(j
, OddTag()); });
147 #if !_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN
148 test
<int32_t>(-666, [](const int32_t& x
) { return true; }, [](size_t j
) { return j
; }, false);
151 test_algo_basic_double
<int32_t>(run_for_rnd_fw
<test_non_const
>());
153 std::cout
<< done() << std::endl
;