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 | // UNSUPPORTED: c++03, c++11, c++14, c++17 |
10 | |
11 | // <algorithm> |
12 | // |
13 | // Range algorithms that take predicates should support predicates that return a non-boolean value as long as the |
14 | // returned type is implicitly convertible to bool. |
15 | |
16 | #include <algorithm> |
17 | |
18 | #include <initializer_list> |
19 | #include <ranges> |
20 | |
21 | #include "boolean_testable.h" |
22 | #include "test_macros.h" |
23 | |
24 | using Value = StrictComparable<int>; |
25 | using Iterator = StrictBooleanIterator<Value*>; |
26 | using Range = std::ranges::subrange<Iterator>; |
27 | auto pred1 = StrictUnaryPredicate; |
28 | auto pred2 = StrictBinaryPredicate; |
29 | auto projection = [](Value const& val) -> Value { return val; }; |
30 | |
31 | void f(Iterator it, Range in, Iterator out, std::size_t n, Value const& val, std::initializer_list<Value> ilist) { |
32 | // Functions of the form (in, pred) |
33 | auto in_pred = [&](auto func, auto pred) { |
34 | (void)func(it, it, pred); |
35 | (void)func(in, pred); |
36 | (void)func(it, it, pred, projection); |
37 | (void)func(in, pred, projection); |
38 | }; |
39 | |
40 | // Functions of the form (in, in, pred) |
41 | auto in_in_pred = [&](auto func, auto pred) { |
42 | (void)func(it, it, it, it, pred); |
43 | (void)func(in, in, pred); |
44 | (void)func(it, it, it, it, pred, projection); |
45 | (void)func(in, in, pred, projection); |
46 | }; |
47 | |
48 | in_pred(std::ranges::any_of, pred1); |
49 | in_pred(std::ranges::all_of, pred1); |
50 | #if TEST_STD_VER >= 23 |
51 | in_in_pred(std::ranges::ends_with, pred2); |
52 | #endif |
53 | in_pred(std::ranges::none_of, pred1); |
54 | in_pred(std::ranges::find_if, pred1); |
55 | in_pred(std::ranges::find_if_not, pred1); |
56 | #if TEST_STD_VER >= 23 |
57 | in_pred(std::ranges::find_last_if, pred1); |
58 | in_pred(std::ranges::find_last_if_not, pred1); |
59 | #endif |
60 | in_in_pred(std::ranges::find_first_of, pred2); |
61 | in_pred(std::ranges::adjacent_find, pred2); |
62 | in_in_pred(std::ranges::mismatch, pred2); |
63 | in_in_pred(std::ranges::equal, pred2); |
64 | in_in_pred(std::ranges::lexicographical_compare, pred2); |
65 | in_pred(std::ranges::partition_point, pred1); |
66 | // lower_bound |
67 | { |
68 | (void)std::ranges::lower_bound(it, it, val, pred2); |
69 | (void)std::ranges::lower_bound(in, val, pred2); |
70 | (void)std::ranges::lower_bound(it, it, val, pred2, projection); |
71 | (void)std::ranges::lower_bound(in, val, pred2, projection); |
72 | } |
73 | // upper_bound |
74 | { |
75 | (void)std::ranges::upper_bound(it, it, val, pred2); |
76 | (void)std::ranges::upper_bound(in, val, pred2); |
77 | (void)std::ranges::upper_bound(it, it, val, pred2, projection); |
78 | (void)std::ranges::upper_bound(in, val, pred2, projection); |
79 | } |
80 | // equal_range |
81 | { |
82 | (void)std::ranges::equal_range(it, it, val, pred2); |
83 | (void)std::ranges::equal_range(in, val, pred2); |
84 | (void)std::ranges::equal_range(it, it, val, pred2, projection); |
85 | (void)std::ranges::equal_range(in, val, pred2, projection); |
86 | } |
87 | // binary_search |
88 | { |
89 | (void)std::ranges::binary_search(it, it, val, pred2); |
90 | (void)std::ranges::binary_search(in, val, pred2); |
91 | (void)std::ranges::binary_search(it, it, val, pred2, projection); |
92 | (void)std::ranges::binary_search(in, val, pred2, projection); |
93 | } |
94 | // min |
95 | { |
96 | (void)std::ranges::min(val, val, pred2); |
97 | (void)std::ranges::min(val, val, pred2, projection); |
98 | (void)std::ranges::min(ilist, pred2); |
99 | (void)std::ranges::min(ilist, pred2, projection); |
100 | (void)std::ranges::min(in, pred2); |
101 | (void)std::ranges::min(in, pred2, projection); |
102 | } |
103 | // max |
104 | { |
105 | (void)std::ranges::max(val, val, pred2); |
106 | (void)std::ranges::max(val, val, pred2, projection); |
107 | (void)std::ranges::max(ilist, pred2); |
108 | (void)std::ranges::max(ilist, pred2, projection); |
109 | (void)std::ranges::max(in, pred2); |
110 | (void)std::ranges::max(in, pred2, projection); |
111 | } |
112 | // minmax |
113 | { |
114 | (void)std::ranges::minmax(val, val, pred2); |
115 | (void)std::ranges::minmax(val, val, pred2, projection); |
116 | (void)std::ranges::minmax(ilist, pred2); |
117 | (void)std::ranges::minmax(ilist, pred2, projection); |
118 | (void)std::ranges::minmax(in, pred2); |
119 | (void)std::ranges::minmax(in, pred2, projection); |
120 | } |
121 | |
122 | in_pred(std::ranges::min_element, pred2); |
123 | in_pred(std::ranges::max_element, pred2); |
124 | in_pred(std::ranges::minmax_element, pred2); |
125 | in_pred(std::ranges::count_if, pred1); |
126 | in_in_pred(std::ranges::search, pred2); |
127 | // search_n |
128 | { |
129 | (void)std::ranges::search_n(it, it, n, val, pred2); |
130 | (void)std::ranges::search_n(in, n, val, pred2); |
131 | (void)std::ranges::search_n(it, it, n, val, pred2, projection); |
132 | (void)std::ranges::search_n(in, n, val, pred2, projection); |
133 | } |
134 | in_in_pred(std::ranges::find_end, pred2); |
135 | in_pred(std::ranges::is_partitioned, pred1); |
136 | in_pred(std::ranges::is_sorted, pred2); |
137 | in_pred(std::ranges::is_sorted_until, pred2); |
138 | in_in_pred(std::ranges::includes, pred2); |
139 | in_pred(std::ranges::is_heap, pred2); |
140 | in_pred(std::ranges::is_heap_until, pred2); |
141 | // clamp |
142 | { |
143 | (void)std::ranges::clamp(val, val, val); |
144 | (void)std::ranges::clamp(val, val, val, pred2); |
145 | (void)std::ranges::clamp(val, val, val, pred2, projection); |
146 | } |
147 | in_in_pred(std::ranges::is_permutation, pred2); |
148 | // copy_if |
149 | { |
150 | (void)std::ranges::copy_if(it, it, out, pred1); |
151 | (void)std::ranges::copy_if(in, out, pred1); |
152 | (void)std::ranges::copy_if(it, it, out, pred1, projection); |
153 | (void)std::ranges::copy_if(in, out, pred1, projection); |
154 | } |
155 | { |
156 | (void)std::ranges::remove_copy_if(it, it, out, pred1); |
157 | (void)std::ranges::remove_copy_if(in, out, pred1); |
158 | (void)std::ranges::remove_copy_if(it, it, out, pred1, projection); |
159 | (void)std::ranges::remove_copy_if(in, out, pred1, projection); |
160 | } |
161 | // remove_copy |
162 | { |
163 | (void)std::ranges::remove_copy(it, it, out, val); |
164 | (void)std::ranges::remove_copy(in, out, val); |
165 | (void)std::ranges::remove_copy(it, it, out, val, projection); |
166 | (void)std::ranges::remove_copy(in, out, val, projection); |
167 | } |
168 | // replace |
169 | { |
170 | (void)std::ranges::replace(it, it, val, val); |
171 | (void)std::ranges::replace(in, val, val); |
172 | (void)std::ranges::replace(it, it, val, val, projection); |
173 | (void)std::ranges::replace(in, val, val, projection); |
174 | } |
175 | // replace_if |
176 | { |
177 | (void)std::ranges::replace_if(it, it, pred1, val); |
178 | (void)std::ranges::replace_if(in, pred1, val); |
179 | (void)std::ranges::replace_if(it, it, pred1, val, projection); |
180 | (void)std::ranges::replace_if(in, pred1, val, projection); |
181 | } |
182 | // replace_copy_if |
183 | { |
184 | (void)std::ranges::replace_copy_if(it, it, out, pred1, val); |
185 | (void)std::ranges::replace_copy_if(in, out, pred1, val); |
186 | (void)std::ranges::replace_copy_if(it, it, out, pred1, val, projection); |
187 | (void)std::ranges::replace_copy_if(in, out, pred1, val, projection); |
188 | } |
189 | // replace_copy |
190 | { |
191 | (void)std::ranges::replace_copy(it, it, out, val, val); |
192 | (void)std::ranges::replace_copy(in, out, val, val); |
193 | (void)std::ranges::replace_copy(it, it, out, val, val, projection); |
194 | (void)std::ranges::replace_copy(in, out, val, val, projection); |
195 | } |
196 | // unique_copy |
197 | { |
198 | (void)std::ranges::unique_copy(it, it, out, pred2); |
199 | (void)std::ranges::unique_copy(in, out, pred2); |
200 | (void)std::ranges::unique_copy(it, it, out, pred2, projection); |
201 | (void)std::ranges::unique_copy(in, out, pred2, projection); |
202 | } |
203 | // partition_copy |
204 | { |
205 | (void)std::ranges::partition_copy(it, it, out, out, pred1); |
206 | (void)std::ranges::partition_copy(in, out, out, pred1); |
207 | (void)std::ranges::partition_copy(it, it, out, out, pred1, projection); |
208 | (void)std::ranges::partition_copy(in, out, out, pred1, projection); |
209 | } |
210 | in_in_pred(std::ranges::partial_sort_copy, pred2); |
211 | #if TEST_STD_VER > 20 |
212 | in_in_pred(std::ranges::starts_with, pred2); |
213 | #endif |
214 | // merge |
215 | { |
216 | (void)std::ranges::merge(it, it, it, it, out, pred2); |
217 | (void)std::ranges::merge(in, in, out, pred2); |
218 | (void)std::ranges::merge(it, it, it, it, out, pred2, projection, projection); |
219 | (void)std::ranges::merge(in, in, out, pred2, projection, projection); |
220 | } |
221 | // set_difference |
222 | { |
223 | (void)std::ranges::set_difference(it, it, it, it, out, pred2); |
224 | (void)std::ranges::set_difference(in, in, out, pred2); |
225 | (void)std::ranges::set_difference(it, it, it, it, out, pred2, projection, projection); |
226 | (void)std::ranges::set_difference(in, in, out, pred2, projection, projection); |
227 | } |
228 | // set_intersection |
229 | { |
230 | (void)std::ranges::set_intersection(it, it, it, it, out, pred2); |
231 | (void)std::ranges::set_intersection(in, in, out, pred2); |
232 | (void)std::ranges::set_intersection(it, it, it, it, out, pred2, projection, projection); |
233 | (void)std::ranges::set_intersection(in, in, out, pred2, projection, projection); |
234 | } |
235 | // set_symmetric_difference |
236 | { |
237 | (void)std::ranges::set_symmetric_difference(it, it, it, it, out, pred2); |
238 | (void)std::ranges::set_symmetric_difference(in, in, out, pred2); |
239 | (void)std::ranges::set_symmetric_difference(it, it, it, it, out, pred2, projection, projection); |
240 | (void)std::ranges::set_symmetric_difference(in, in, out, pred2, projection, projection); |
241 | } |
242 | // set_union |
243 | { |
244 | (void)std::ranges::set_union(it, it, it, it, out, pred2); |
245 | (void)std::ranges::set_union(in, in, out, pred2); |
246 | (void)std::ranges::set_union(it, it, it, it, out, pred2, projection, projection); |
247 | (void)std::ranges::set_union(in, in, out, pred2, projection, projection); |
248 | } |
249 | in_pred(std::ranges::remove_if, pred1); |
250 | // remove |
251 | { |
252 | (void)std::ranges::remove(it, it, val); |
253 | (void)std::ranges::remove(it, it, val, projection); |
254 | (void)std::ranges::remove(in, val); |
255 | (void)std::ranges::remove(in, val, projection); |
256 | } |
257 | in_pred(std::ranges::unique, pred2); |
258 | in_pred(std::ranges::partition, pred1); |
259 | in_pred(std::ranges::stable_partition, pred1); |
260 | in_pred(std::ranges::sort, pred2); |
261 | in_pred(std::ranges::stable_sort, pred2); |
262 | // partial_sort |
263 | { |
264 | (void)std::ranges::partial_sort(it, it, it, pred2); |
265 | (void)std::ranges::partial_sort(in, it, pred2); |
266 | (void)std::ranges::partial_sort(it, it, it, pred2, projection); |
267 | (void)std::ranges::partial_sort(in, it, pred2, projection); |
268 | } |
269 | // nth_element |
270 | { |
271 | (void)std::ranges::nth_element(it, it, it, pred2); |
272 | (void)std::ranges::nth_element(in, it, pred2); |
273 | (void)std::ranges::nth_element(it, it, it, pred2, projection); |
274 | (void)std::ranges::nth_element(in, it, pred2, projection); |
275 | } |
276 | // inplace_merge |
277 | { |
278 | (void)std::ranges::inplace_merge(it, it, it, pred2); |
279 | (void)std::ranges::inplace_merge(in, it, pred2); |
280 | (void)std::ranges::inplace_merge(it, it, it, pred2, projection); |
281 | (void)std::ranges::inplace_merge(in, it, pred2, projection); |
282 | } |
283 | in_pred(std::ranges::make_heap, pred2); |
284 | in_pred(std::ranges::push_heap, pred2); |
285 | in_pred(std::ranges::pop_heap, pred2); |
286 | in_pred(std::ranges::sort_heap, pred2); |
287 | in_pred(std::ranges::prev_permutation, pred2); |
288 | in_pred(std::ranges::next_permutation, pred2); |
289 | } |
290 | |