2 // { dg-options "-std=gnu++17 -ltbb" }
3 // { dg-do run { target c++17 } }
4 // { dg-require-effective-target tbb-backend }
6 //===-- unique_copy_equal.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 unique_copy
15 #include "pstl/pstl_test_config.h"
17 #ifdef PSTL_STANDALONE_TESTS
18 #include "pstl/execution"
19 #include "pstl/algorithm"
23 #endif // PSTL_STANDALONE_TESTS
25 #include "pstl/test_utils.h"
27 using namespace TestUtils
;
29 struct run_unique_copy
31 #if _PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN // dummy specializations to skip testing in case of broken configuration
32 template <typename InputIterator
, typename OutputIterator
, typename OutputIterator2
, typename Size
,
33 typename Predicate
, typename T
>
35 operator()(__pstl::execution::parallel_policy
, InputIterator first
, InputIterator last
, OutputIterator out_first
,
36 OutputIterator out_last
, OutputIterator2 expected_first
, OutputIterator2 expected_last
, Size n
,
37 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
= unique_copy(first
, last
, expected_first
);
64 auto k
= unique_copy(exec
, first
, last
, out_first
);
65 EXPECT_EQ_N(expected_first
, out_first
, n
, "wrong unique_copy effect");
66 for (size_t j
= 0; j
< GuardSize
; ++j
)
70 EXPECT_TRUE(out_last
== k
, "wrong return value from unique_copy");
73 std::fill_n(expected_first
, n
, trash
);
74 std::fill_n(out_first
, n
, trash
);
75 // Run unique_copy with predicate
76 i
= unique_copy(first
, last
, expected_first
, pred
);
77 k
= unique_copy(exec
, first
, last
, out_first
, pred
);
78 EXPECT_EQ_N(expected_first
, out_first
, n
, "wrong unique_copy with predicate effect");
79 for (size_t j
= 0; j
< GuardSize
; ++j
)
83 EXPECT_TRUE(out_last
== k
, "wrong return value from unique_copy with predicate");
87 template <typename T
, typename BinaryPredicate
, typename Convert
>
89 test(T trash
, BinaryPredicate 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 Sequence
<T
> in(n
, [&](size_t k
) -> T
{ return convert(k
^ n
); });
98 size_t count
= GuardSize
;
99 for (size_t k
= 0; k
< in
.size(); ++k
)
100 count
+= k
== 0 || !pred(in
[k
], in
[k
- 1]) ? 1 : 0;
101 Sequence
<T
> out(count
, [=](size_t) { return trash
; });
102 Sequence
<T
> expected(count
, [=](size_t) { return trash
; });
105 auto expected_result
= unique_copy(in
.begin(), in
.end(), expected
.begin(), pred
);
106 size_t m
= expected_result
- expected
.begin();
107 EXPECT_TRUE(n
/ (n
< 10000 ? 4 : 6) <= m
&& m
<= (3 * n
+ 1) / 4, "weak test for unique_copy");
109 invoke_on_all_policies(run_unique_copy(), in
.begin(), in
.end(), out
.begin(), out
.end(), expected
.begin(),
110 expected
.end(), count
, pred
, trash
);
114 template <typename T
>
115 struct test_non_const
117 template <typename Policy
, typename InputIterator
, typename OutputInterator
>
119 operator()(Policy
&& exec
, InputIterator input_iter
, OutputInterator out_iter
)
121 unique_copy(exec
, input_iter
, input_iter
, out_iter
, non_const(std::equal_to
<T
>()));
126 main(int32_t argc
, char* argv
[])
128 test
<Number
>(Number(42, OddTag()), std::equal_to
<Number
>(),
129 [](int32_t j
) { return Number(3 * j
/ 13 ^ (j
& 8), OddTag()); });
131 test
<float32_t
>(float32_t(42), std::equal_to
<float32_t
>(),
132 [](int32_t j
) { return float32_t(5 * j
/ 23 ^ (j
/ 7)); });
133 #if !_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN
134 test
<float32_t
>(float32_t(42), [](float32_t x
, float32_t y
) { return false; },
135 [](int32_t j
) { return float32_t(j
); }, false);
138 test_algo_basic_double
<int32_t>(run_for_rnd_fw
<test_non_const
<int32_t>>());
140 std::cout
<< done() << std::endl
;