2 //===-- remove_copy.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 #include "support/pstl_test_config.h"
17 #include "support/utils.h"
19 using namespace TestUtils
;
21 struct run_remove_copy
23 template <typename Policy
, typename InputIterator
, typename OutputIterator
, typename OutputIterator2
, typename Size
,
26 operator()(Policy
&& exec
, InputIterator first
, InputIterator last
, OutputIterator out_first
,
27 OutputIterator out_last
, OutputIterator2 expected_first
, OutputIterator2
, Size n
, const T
& value
,
31 std::fill_n(expected_first
, n
, trash
);
32 std::fill_n(out_first
, n
, trash
);
35 auto i
= std::remove_copy(first
, last
, expected_first
, value
);
37 auto k
= std::remove_copy(exec
, first
, last
, out_first
, value
);
38 EXPECT_EQ_N(expected_first
, out_first
, n
, "wrong remove_copy effect");
39 for (size_t j
= 0; j
< GuardSize
; ++j
)
43 EXPECT_TRUE(out_last
== k
, "wrong return value from remove_copy");
47 template <typename T
, typename Convert
>
49 test(T trash
, const T
& value
, Convert convert
, bool check_weakness
= true)
51 // Try sequences of various lengths.
52 for (size_t n
= 0; n
<= 100000; n
= n
<= 16 ? n
+ 1 : size_t(3.1415 * n
))
54 // count is number of output elements, plus a handful
55 // more for sake of detecting buffer overruns.
56 size_t count
= GuardSize
;
57 Sequence
<T
> in(n
, [&](size_t k
) -> T
{
59 count
+= !(x
== value
) ? 1 : 0;
64 Sequence
<T
> out(count
, [=](size_t) { return trash
; });
65 Sequence
<T
> expected(count
, [=](size_t) { return trash
; });
68 auto expected_result
= remove_copy(in
.cfbegin(), in
.cfend(), expected
.begin(), value
);
69 size_t m
= expected_result
- expected
.begin();
70 EXPECT_TRUE(n
/ 4 <= m
&& m
<= 3 * (n
+ 1) / 4, "weak test for remove_copy");
72 invoke_on_all_policies(run_remove_copy(), in
.begin(), in
.end(), out
.begin(), out
.end(), expected
.begin(),
73 expected
.end(), count
, value
, trash
);
74 invoke_on_all_policies(run_remove_copy(), in
.cbegin(), in
.cend(), out
.begin(), out
.end(), expected
.begin(),
75 expected
.end(), count
, value
, trash
);
83 test
<float64_t
>(-666.0, 8.5, [](size_t j
) { return ((j
+ 1) % 7 & 2) != 0 ? 8.5 : float64_t(j
% 32 + j
); });
85 test
<int32_t>(-666, 42, [](size_t j
) { return ((j
+ 1) % 5 & 2) != 0 ? 42 : -1 - int32_t(j
); });
87 test
<Number
>(Number(42, OddTag()), Number(2001, OddTag()),
88 [](int32_t j
) { return ((j
+ 1) % 3 & 2) != 0 ? Number(2001, OddTag()) : Number(j
, OddTag()); });
89 std::cout
<< done() << std::endl
;