1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // <algorithm> |
10 | |
11 | // template<ForwardIterator Iter, Predicate<auto, Iter::value_type> Pred> |
12 | // requires OutputIterator<Iter, RvalueOf<Iter::reference>::type> |
13 | // && CopyConstructible<Pred> |
14 | // constexpr Iter // constexpr after C++17 |
15 | // remove_if(Iter first, Iter last, Pred pred); |
16 | |
17 | #include <algorithm> |
18 | #include <functional> |
19 | #include <cassert> |
20 | #include <memory> |
21 | |
22 | #include "test_macros.h" |
23 | #include "test_iterators.h" |
24 | #include "counting_predicates.h" |
25 | |
26 | TEST_CONSTEXPR bool equal2 ( int i ) { return i == 2; } |
27 | |
28 | #if TEST_STD_VER > 17 |
29 | TEST_CONSTEXPR bool test_constexpr() { |
30 | int ia[] = {1, 3, 5, 2, 5, 6}; |
31 | |
32 | auto it = std::remove_if(std::begin(ia), std::end(ia), equal2); |
33 | |
34 | return (std::begin(ia) + std::size(ia) - 1) == it // we removed one element |
35 | && std::none_of(std::begin(ia), it, equal2) |
36 | ; |
37 | } |
38 | #endif |
39 | |
40 | template <class Iter> |
41 | void |
42 | test() |
43 | { |
44 | int ia[] = {0, 1, 2, 3, 4, 2, 3, 4, 2}; |
45 | const unsigned sa = sizeof(ia)/sizeof(ia[0]); |
46 | // int* r = std::remove_if(ia, ia+sa, std::bind2nd(std::equal_to<int>(), 2)); |
47 | unary_counting_predicate<bool(*)(int), int> cp(equal2); |
48 | int* r = std::remove_if(ia, ia+sa, std::ref(cp)); |
49 | assert(r == ia + sa-3); |
50 | assert(ia[0] == 0); |
51 | assert(ia[1] == 1); |
52 | assert(ia[2] == 3); |
53 | assert(ia[3] == 4); |
54 | assert(ia[4] == 3); |
55 | assert(ia[5] == 4); |
56 | assert(cp.count() == sa); |
57 | } |
58 | |
59 | #if TEST_STD_VER >= 11 |
60 | struct pred |
61 | { |
62 | bool operator()(const std::unique_ptr<int>& i) {return *i == 2;} |
63 | }; |
64 | |
65 | template <class Iter> |
66 | void |
67 | test1() |
68 | { |
69 | const unsigned sa = 9; |
70 | std::unique_ptr<int> ia[sa]; |
71 | ia[0].reset(new int(0)); |
72 | ia[1].reset(new int(1)); |
73 | ia[2].reset(new int(2)); |
74 | ia[3].reset(new int(3)); |
75 | ia[4].reset(new int(4)); |
76 | ia[5].reset(new int(2)); |
77 | ia[6].reset(new int(3)); |
78 | ia[7].reset(new int(4)); |
79 | ia[8].reset(new int(2)); |
80 | Iter r = std::remove_if(Iter(ia), Iter(ia+sa), pred()); |
81 | assert(base(r) == ia + sa-3); |
82 | assert(*ia[0] == 0); |
83 | assert(*ia[1] == 1); |
84 | assert(*ia[2] == 3); |
85 | assert(*ia[3] == 4); |
86 | assert(*ia[4] == 3); |
87 | assert(*ia[5] == 4); |
88 | } |
89 | #endif // TEST_STD_VER >= 11 |
90 | |
91 | int main(int, char**) |
92 | { |
93 | test<forward_iterator<int*> >(); |
94 | test<bidirectional_iterator<int*> >(); |
95 | test<random_access_iterator<int*> >(); |
96 | test<int*>(); |
97 | |
98 | #if TEST_STD_VER >= 11 |
99 | test1<forward_iterator<std::unique_ptr<int>*> >(); |
100 | test1<bidirectional_iterator<std::unique_ptr<int>*> >(); |
101 | test1<random_access_iterator<std::unique_ptr<int>*> >(); |
102 | test1<std::unique_ptr<int>*>(); |
103 | #endif // TEST_STD_VER >= 11 |
104 | |
105 | #if TEST_STD_VER > 17 |
106 | static_assert(test_constexpr()); |
107 | #endif |
108 | |
109 | return 0; |
110 | } |
111 | |