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// <forward_list>
10
11// template <class Predicate> void remove_if(Predicate pred); // C++17 and before
12// template <class Predicate> size_type remove_if(Predicate pred); // C++20 and after
13
14#include <forward_list>
15#include <iterator>
16#include <cassert>
17#include <cstddef>
18#include <functional>
19
20#include "test_macros.h"
21#include "min_allocator.h"
22#include "counting_predicates.h"
23
24
25template <class L, class Predicate>
26void do_remove_if(L &l, Predicate pred, typename L::size_type expected)
27{
28 typename L::size_type old_size = std::distance(l.begin(), l.end());
29#if TEST_STD_VER > 17
30 ASSERT_SAME_TYPE(decltype(l.remove_if(pred)), typename L::size_type);
31 assert(l.remove_if(pred) == expected);
32#else
33 ASSERT_SAME_TYPE(decltype(l.remove_if(pred)), void);
34 l.remove_if(pred);
35#endif
36 assert(old_size - std::distance(l.begin(), l.end()) == expected);
37}
38
39bool g(int i)
40{
41 return i < 3;
42}
43
44struct PredLWG526 {
45 PredLWG526(int i) : i_(i) {}
46 ~PredLWG526() { i_ = -32767; }
47 bool operator()(const PredLWG526& p) const { return p.i_ == i_; }
48
49 bool operator==(int i) const { return i == i_; }
50 int i_;
51};
52
53int main(int, char**)
54{
55 {
56 typedef int T;
57 typedef unary_counting_predicate<bool(*)(T), T> Predicate;
58 typedef std::forward_list<T> C;
59 const T t1[] = {0, 5, 5, 0, 0, 0, 5};
60 const T t2[] = {5, 5, 5};
61 C c1(std::begin(arr: t1), std::end(arr: t1));
62 C c2(std::begin(arr: t2), std::end(arr: t2));
63 Predicate cp(g);
64 do_remove_if(l&: c1, pred: std::ref(t&: cp), expected: 4);
65 assert(c1 == c2);
66 assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
67 }
68 {
69 typedef int T;
70 typedef unary_counting_predicate<bool(*)(T), T> Predicate;
71 typedef std::forward_list<T> C;
72 const T t1[] = {0, 0, 0, 0};
73 C c1(std::begin(arr: t1), std::end(arr: t1));
74 C c2;
75 Predicate cp(g);
76 do_remove_if(l&: c1, pred: std::ref(t&: cp), expected: 4);
77 assert(c1 == c2);
78 assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
79 }
80 {
81 typedef int T;
82 typedef unary_counting_predicate<bool(*)(T), T> Predicate;
83 typedef std::forward_list<T> C;
84 const T t1[] = {5, 5, 5};
85 const T t2[] = {5, 5, 5};
86 C c1(std::begin(arr: t1), std::end(arr: t1));
87 C c2(std::begin(arr: t2), std::end(arr: t2));
88 Predicate cp(g);
89 do_remove_if(l&: c1, pred: std::ref(t&: cp), expected: 0);
90 assert(c1 == c2);
91 assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
92 }
93 {
94 typedef int T;
95 typedef unary_counting_predicate<bool(*)(T), T> Predicate;
96 typedef std::forward_list<T> C;
97 C c1;
98 C c2;
99 Predicate cp(g);
100 do_remove_if(l&: c1, pred: std::ref(t&: cp), expected: 0);
101 assert(c1 == c2);
102 assert(cp.count() == 0);
103 }
104 {
105 typedef int T;
106 typedef unary_counting_predicate<bool(*)(T), T> Predicate;
107 typedef std::forward_list<T> C;
108 const T t1[] = {5, 5, 5, 0};
109 const T t2[] = {5, 5, 5};
110 C c1(std::begin(arr: t1), std::end(arr: t1));
111 C c2(std::begin(arr: t2), std::end(arr: t2));
112 Predicate cp(g);
113 do_remove_if(l&: c1, pred: std::ref(t&: cp), expected: 1);
114 assert(c1 == c2);
115 assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
116 }
117
118 { // LWG issue #526
119 int a1[] = {1, 2, 1, 3, 5, 8, 11};
120 int a2[] = { 2, 3, 5, 8, 11};
121 std::forward_list<PredLWG526> c(a1, a1 + 7);
122 do_remove_if(l&: c, pred: std::ref(t&: c.front()), expected: 2);
123 for (std::size_t i = 0; i < 5; ++i)
124 {
125 assert(!c.empty());
126 assert(c.front() == a2[i]);
127 c.pop_front();
128 }
129 assert(c.empty());
130 }
131
132#if TEST_STD_VER >= 11
133 {
134 typedef int T;
135 typedef unary_counting_predicate<bool(*)(T), T> Predicate;
136 typedef std::forward_list<T, min_allocator<T>> C;
137 const T t1[] = {0, 5, 5, 0, 0, 0, 5};
138 const T t2[] = {5, 5, 5};
139 C c1(std::begin(t1), std::end(t1));
140 C c2(std::begin(t2), std::end(t2));
141 Predicate cp(g);
142 do_remove_if(c1, std::ref(cp), 4);
143 assert(c1 == c2);
144 assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
145 }
146 {
147 typedef int T;
148 typedef unary_counting_predicate<bool(*)(T), T> Predicate;
149 typedef std::forward_list<T, min_allocator<T>> C;
150 const T t1[] = {0, 0, 0, 0};
151 C c1(std::begin(t1), std::end(t1));
152 C c2;
153 Predicate cp(g);
154 do_remove_if(c1, std::ref(cp), 4);
155 assert(c1 == c2);
156 assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
157 }
158 {
159 typedef int T;
160 typedef unary_counting_predicate<bool(*)(T), T> Predicate;
161 typedef std::forward_list<T, min_allocator<T>> C;
162 const T t1[] = {5, 5, 5};
163 const T t2[] = {5, 5, 5};
164 C c1(std::begin(t1), std::end(t1));
165 C c2(std::begin(t2), std::end(t2));
166 Predicate cp(g);
167 do_remove_if(c1, std::ref(cp), 0);
168 assert(c1 == c2);
169 assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
170 }
171 {
172 typedef int T;
173 typedef unary_counting_predicate<bool(*)(T), T> Predicate;
174 typedef std::forward_list<T, min_allocator<T>> C;
175 C c1;
176 C c2;
177 Predicate cp(g);
178 do_remove_if(c1, std::ref(cp), 0);
179 assert(c1 == c2);
180 assert(cp.count() == 0);
181 }
182 {
183 typedef int T;
184 typedef unary_counting_predicate<bool(*)(T), T> Predicate;
185 typedef std::forward_list<T, min_allocator<T>> C;
186 const T t1[] = {5, 5, 5, 0};
187 const T t2[] = {5, 5, 5};
188 C c1(std::begin(t1), std::end(t1));
189 C c2(std::begin(t2), std::end(t2));
190 Predicate cp(g);
191 do_remove_if(c1, std::ref(cp), 1);
192 assert(c1 == c2);
193 assert(cp.count() == static_cast<std::size_t>(std::distance(std::begin(t1), std::end(t1))));
194 }
195#endif
196
197 return 0;
198}
199

source code of libcxx/test/std/containers/sequences/forwardlist/forwardlist.ops/remove_if.pass.cpp