2 //===-- unique_copy_equal.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
12 // Tests for unique_copy
13 #include "support/pstl_test_config.h"
18 #include "support/utils.h"
20 using namespace TestUtils
;
22 struct run_unique_copy
24 #if defined(_PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN) // dummy specializations to skip testing in case of broken configuration
25 template <typename InputIterator
, typename OutputIterator
, typename OutputIterator2
, typename Size
,
26 typename Predicate
, typename T
>
28 operator()(pstl::execution::parallel_policy
, InputIterator first
, InputIterator last
, OutputIterator out_first
,
29 OutputIterator out_last
, OutputIterator2 expected_first
, OutputIterator2 expected_last
, Size n
,
30 Predicate pred
, T trash
)
34 template <typename InputIterator
, typename OutputIterator
, typename OutputIterator2
, typename Size
,
35 typename Predicate
, typename T
>
37 operator()(pstl::execution::parallel_unsequenced_policy
, InputIterator first
, InputIterator last
,
38 OutputIterator out_first
, OutputIterator out_last
, OutputIterator2 expected_first
,
39 OutputIterator2 expected_last
, Size n
, Predicate pred
, T trash
)
44 template <typename Policy
, typename InputIterator
, typename OutputIterator
, typename OutputIterator2
, typename Size
,
45 typename Predicate
, typename T
>
47 operator()(Policy
&& exec
, InputIterator first
, InputIterator last
, OutputIterator out_first
,
48 OutputIterator out_last
, OutputIterator2 expected_first
, OutputIterator2
, Size n
, Predicate pred
,
52 std::fill_n(expected_first
, n
, trash
);
53 std::fill_n(out_first
, n
, trash
);
56 auto i
= unique_copy(first
, last
, expected_first
);
57 auto k
= unique_copy(exec
, first
, last
, out_first
);
58 EXPECT_EQ_N(expected_first
, out_first
, n
, "wrong unique_copy effect");
59 for (size_t j
= 0; j
< GuardSize
; ++j
)
63 EXPECT_TRUE(out_last
== k
, "wrong return value from unique_copy");
66 std::fill_n(expected_first
, n
, trash
);
67 std::fill_n(out_first
, n
, trash
);
68 // Run unique_copy with predicate
69 i
= unique_copy(first
, last
, expected_first
, pred
);
70 k
= unique_copy(exec
, first
, last
, out_first
, pred
);
71 EXPECT_EQ_N(expected_first
, out_first
, n
, "wrong unique_copy with predicate effect");
72 for (size_t j
= 0; j
< GuardSize
; ++j
)
76 EXPECT_TRUE(out_last
== k
, "wrong return value from unique_copy with predicate");
80 template <typename T
, typename BinaryPredicate
, typename Convert
>
82 test(T trash
, BinaryPredicate pred
, Convert convert
, bool check_weakness
= true)
84 // Try sequences of various lengths.
85 for (size_t n
= 0; n
<= 100000; n
= n
<= 16 ? n
+ 1 : size_t(3.1415 * n
))
87 // count is number of output elements, plus a handful
88 // more for sake of detecting buffer overruns.
89 Sequence
<T
> in(n
, [&](size_t k
) -> T
{ return convert(k
^ n
); });
91 size_t count
= GuardSize
;
92 for (size_t k
= 0; k
< in
.size(); ++k
)
93 count
+= k
== 0 || !pred(in
[k
], in
[k
- 1]) ? 1 : 0;
94 Sequence
<T
> out(count
, [=](size_t) { return trash
; });
95 Sequence
<T
> expected(count
, [=](size_t) { return trash
; });
98 auto expected_result
= unique_copy(in
.begin(), in
.end(), expected
.begin(), pred
);
99 size_t m
= expected_result
- expected
.begin();
100 EXPECT_TRUE(n
/ (n
< 10000 ? 4 : 6) <= m
&& m
<= (3 * n
+ 1) / 4, "weak test for unique_copy");
102 invoke_on_all_policies(run_unique_copy(), in
.begin(), in
.end(), out
.begin(), out
.end(), expected
.begin(),
103 expected
.end(), count
, pred
, trash
);
107 template <typename T
>
108 struct test_non_const
110 template <typename Policy
, typename InputIterator
, typename OutputInterator
>
112 operator()(Policy
&& exec
, InputIterator input_iter
, OutputInterator out_iter
)
114 unique_copy(exec
, input_iter
, input_iter
, out_iter
, non_const(std::equal_to
<T
>()));
121 test
<Number
>(Number(42, OddTag()), std::equal_to
<Number
>(),
122 [](int32_t j
) { return Number(3 * j
/ 13 ^ (j
& 8), OddTag()); });
124 test
<float32_t
>(float32_t(42), std::equal_to
<float32_t
>(),
125 [](int32_t j
) { return float32_t(5 * j
/ 23 ^ (j
/ 7)); });
126 #if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN)
127 test
<float32_t
>(float32_t(42), [](float32_t
, float32_t
) { return false; }, [](int32_t j
) { return float32_t(j
); },
131 test_algo_basic_double
<int32_t>(run_for_rnd_fw
<test_non_const
<int32_t>>());
133 std::cout
<< done() << std::endl
;