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 | // this test checks that the projections in the ranges algorithms aren't copied/moved |
14 | |
15 | #include <algorithm> |
16 | #include <cassert> |
17 | #include <cstddef> |
18 | #include <deque> |
19 | |
20 | #include "test_macros.h" |
21 | |
22 | struct T {}; |
23 | |
24 | struct Proj { |
25 | int *copies_; |
26 | constexpr explicit Proj(int *copies) : copies_(copies) {} |
27 | constexpr Proj(const Proj& rhs) : copies_(rhs.copies_) { *copies_ += 1; } |
28 | constexpr Proj& operator=(const Proj&) = default; |
29 | constexpr void *operator()(T) const { return nullptr; } |
30 | }; |
31 | |
32 | struct Less { |
33 | constexpr bool operator()(void*, void*) const { return false; } |
34 | }; |
35 | |
36 | struct Equal { |
37 | constexpr bool operator()(void*, void*) const { return true; } |
38 | }; |
39 | |
40 | struct UnaryVoid { |
41 | constexpr void operator()(void*) const {} |
42 | }; |
43 | |
44 | struct UnaryTrue { |
45 | constexpr bool operator()(void*) const { return true; } |
46 | }; |
47 | |
48 | struct NullaryValue { |
49 | constexpr std::nullptr_t operator()() const { return nullptr; } |
50 | }; |
51 | |
52 | struct UnaryTransform { |
53 | constexpr T operator()(void*) const { return T(); } |
54 | }; |
55 | |
56 | struct BinaryTransform { |
57 | constexpr T operator()(void*, void*) const { return T(); } |
58 | }; |
59 | |
60 | constexpr bool all_the_algorithms() |
61 | { |
62 | T a[10] = {}; |
63 | T b[10] = {}; |
64 | T half[5] = {}; |
65 | T *first = a; |
66 | T *mid = a+5; |
67 | T *last = a+10; |
68 | T *first2 = b; |
69 | T *mid2 = b+5; |
70 | T *last2 = b+10; |
71 | void *value = nullptr; |
72 | int count = 1; |
73 | |
74 | int copies = 0; |
75 | (void)std::ranges::adjacent_find(first, last, Equal(), Proj(&copies)); assert(copies == 0); |
76 | (void)std::ranges::adjacent_find(a, Equal(), Proj(&copies)); assert(copies == 0); |
77 | (void)std::ranges::all_of(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
78 | (void)std::ranges::all_of(a, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
79 | (void)std::ranges::any_of(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
80 | (void)std::ranges::any_of(a, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
81 | (void)std::ranges::binary_search(first, last, value, Less(), Proj(&copies)); assert(copies == 0); |
82 | (void)std::ranges::binary_search(a, value, Less(), Proj(&copies)); assert(copies == 0); |
83 | (void)std::ranges::clamp(T(), T(), T(), Less(), Proj(&copies)); assert(copies == 0); |
84 | #if TEST_STD_VER >= 23 |
85 | (void)std::ranges::contains(first, last, value, Proj(&copies)); |
86 | assert(copies == 0); |
87 | (void)std::ranges::contains(a, value, Proj(&copies)); |
88 | assert(copies == 0); |
89 | (void)std::ranges::contains_subrange(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); |
90 | assert(copies == 0); |
91 | (void)std::ranges::contains_subrange(a, b, Equal(), Proj(&copies), Proj(&copies)); |
92 | assert(copies == 0); |
93 | #endif |
94 | (void)std::ranges::count(first, last, value, Proj(&copies)); assert(copies == 0); |
95 | (void)std::ranges::count(a, value, Proj(&copies)); assert(copies == 0); |
96 | (void)std::ranges::count_if(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
97 | (void)std::ranges::count_if(a, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
98 | (void)std::ranges::copy_if(first, last, first2, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
99 | (void)std::ranges::copy_if(a, first2, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
100 | #if TEST_STD_VER >= 23 |
101 | (void)std::ranges::ends_with(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
102 | (void)std::ranges::ends_with(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
103 | #endif |
104 | (void)std::ranges::equal(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
105 | (void)std::ranges::equal(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
106 | (void)std::ranges::equal_range(first, last, value, Less(), Proj(&copies)); assert(copies == 0); |
107 | (void)std::ranges::equal_range(a, value, Less(), Proj(&copies)); assert(copies == 0); |
108 | (void)std::ranges::find(first, last, value, Proj(&copies)); assert(copies == 0); |
109 | (void)std::ranges::find(a, value, Proj(&copies)); assert(copies == 0); |
110 | (void)std::ranges::find_end(first, last, first2, mid2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
111 | (void)std::ranges::find_end(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
112 | (void)std::ranges::find_first_of(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
113 | (void)std::ranges::find_first_of(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
114 | (void)std::ranges::find_if(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
115 | (void)std::ranges::find_if(a, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
116 | (void)std::ranges::find_if_not(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
117 | (void)std::ranges::find_if_not(a, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
118 | (void)std::ranges::for_each(first, last, UnaryVoid(), Proj(&copies)); assert(copies == 0); |
119 | (void)std::ranges::for_each(a, UnaryVoid(), Proj(&copies)); assert(copies == 0); |
120 | (void)std::ranges::for_each_n(first, count, UnaryVoid(), Proj(&copies)); assert(copies == 0); |
121 | (void)std::ranges::includes(first, last, first2, last2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
122 | (void)std::ranges::includes(a, b, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
123 | (void)std::ranges::is_heap(first, last, Less(), Proj(&copies)); assert(copies == 0); |
124 | (void)std::ranges::is_heap(a, Less(), Proj(&copies)); assert(copies == 0); |
125 | (void)std::ranges::is_heap_until(first, last, Less(), Proj(&copies)); assert(copies == 0); |
126 | (void)std::ranges::is_heap_until(a, Less(), Proj(&copies)); assert(copies == 0); |
127 | (void)std::ranges::is_partitioned(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
128 | (void)std::ranges::is_partitioned(a, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
129 | (void)std::ranges::is_permutation(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
130 | (void)std::ranges::is_permutation(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
131 | (void)std::ranges::is_sorted(first, last, Less(), Proj(&copies)); assert(copies == 0); |
132 | (void)std::ranges::is_sorted(a, Less(), Proj(&copies)); assert(copies == 0); |
133 | (void)std::ranges::is_sorted_until(first, last, Less(), Proj(&copies)); assert(copies == 0); |
134 | (void)std::ranges::is_sorted_until(a, Less(), Proj(&copies)); assert(copies == 0); |
135 | if (!std::is_constant_evaluated()) { (void)std::ranges::inplace_merge(first, mid, last, Less(), Proj(&copies)); assert(copies == 0); } |
136 | if (!std::is_constant_evaluated()) { (void)std::ranges::inplace_merge(a, mid, Less(), Proj(&copies)); assert(copies == 0); } |
137 | (void)std::ranges::lexicographical_compare(first, last, first2, last2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
138 | (void)std::ranges::lexicographical_compare(a, b, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
139 | (void)std::ranges::lower_bound(first, last, value, Less(), Proj(&copies)); assert(copies == 0); |
140 | (void)std::ranges::lower_bound(a, value, Less(), Proj(&copies)); assert(copies == 0); |
141 | (void)std::ranges::make_heap(first, last, Less(), Proj(&copies)); assert(copies == 0); |
142 | (void)std::ranges::make_heap(a, Less(), Proj(&copies)); assert(copies == 0); |
143 | (void)std::ranges::max(T(), T(), Less(), Proj(&copies)); assert(copies == 0); |
144 | (void)std::ranges::max({ T(), T() }, Less(), Proj(&copies)); assert(copies == 0); |
145 | (void)std::ranges::max(a, Less(), Proj(&copies)); assert(copies == 0); |
146 | (void)std::ranges::max_element(first, last, Less(), Proj(&copies)); assert(copies == 0); |
147 | (void)std::ranges::max_element(a, Less(), Proj(&copies)); assert(copies == 0); |
148 | (void)std::ranges::merge(first, mid, mid, last, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
149 | (void)std::ranges::merge(half, half, b, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
150 | (void)std::ranges::min(T(), T(), Less(), Proj(&copies)); assert(copies == 0); |
151 | (void)std::ranges::min({ T(), T() }, Less(), Proj(&copies)); assert(copies == 0); |
152 | (void)std::ranges::min(a, Less(), Proj(&copies)); assert(copies == 0); |
153 | (void)std::ranges::min_element(first, last, Less(), Proj(&copies)); assert(copies == 0); |
154 | (void)std::ranges::min_element(a, Less(), Proj(&copies)); assert(copies == 0); |
155 | (void)std::ranges::minmax(T(), T(), Less(), Proj(&copies)); assert(copies == 0); |
156 | (void)std::ranges::minmax({ T(), T() }, Less(), Proj(&copies)); assert(copies == 0); |
157 | (void)std::ranges::minmax(a, Less(), Proj(&copies)); assert(copies == 0); |
158 | (void)std::ranges::minmax_element(first, last, Less(), Proj(&copies)); assert(copies == 0); |
159 | (void)std::ranges::minmax_element(a, Less(), Proj(&copies)); assert(copies == 0); |
160 | (void)std::ranges::mismatch(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
161 | (void)std::ranges::mismatch(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
162 | (void)std::ranges::next_permutation(first, last, Less(), Proj(&copies)); assert(copies == 0); |
163 | (void)std::ranges::next_permutation(a, Less(), Proj(&copies)); assert(copies == 0); |
164 | (void)std::ranges::none_of(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
165 | (void)std::ranges::none_of(a, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
166 | (void)std::ranges::nth_element(first, mid, last, Less(), Proj(&copies)); assert(copies == 0); |
167 | (void)std::ranges::nth_element(a, mid, Less(), Proj(&copies)); assert(copies == 0); |
168 | (void)std::ranges::partial_sort(first, mid, last, Less(), Proj(&copies)); assert(copies == 0); |
169 | (void)std::ranges::partial_sort(a, mid, Less(), Proj(&copies)); assert(copies == 0); |
170 | (void)std::ranges::partial_sort_copy(first, last, first2, mid2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
171 | (void)std::ranges::partial_sort_copy(a, b, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
172 | (void)std::ranges::partition(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
173 | (void)std::ranges::partition(a, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
174 | (void)std::ranges::partition_copy(first, last, first2, last2, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
175 | (void)std::ranges::partition_copy(a, first2, last2, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
176 | (void)std::ranges::partition_point(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
177 | (void)std::ranges::partition_point(a, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
178 | (void)std::ranges::pop_heap(first, last, Less(), Proj(&copies)); assert(copies == 0); |
179 | (void)std::ranges::pop_heap(a, Less(), Proj(&copies)); assert(copies == 0); |
180 | (void)std::ranges::prev_permutation(first, last, Less(), Proj(&copies)); assert(copies == 0); |
181 | (void)std::ranges::prev_permutation(a, Less(), Proj(&copies)); assert(copies == 0); |
182 | (void)std::ranges::push_heap(first, last, Less(), Proj(&copies)); assert(copies == 0); |
183 | (void)std::ranges::push_heap(a, Less(), Proj(&copies)); assert(copies == 0); |
184 | (void)std::ranges::remove_copy(first, last, first2, value, Proj(&copies)); assert(copies == 0); |
185 | (void)std::ranges::remove_copy(a, first2, value, Proj(&copies)); assert(copies == 0); |
186 | (void)std::ranges::remove_copy_if(first, last, first2, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
187 | (void)std::ranges::remove_copy_if(a, first2, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
188 | (void)std::ranges::remove(first, last, value, Proj(&copies)); assert(copies == 0); |
189 | (void)std::ranges::remove(a, value, Proj(&copies)); assert(copies == 0); |
190 | (void)std::ranges::remove_if(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
191 | (void)std::ranges::remove_if(a, UnaryTrue(), Proj(&copies)); assert(copies == 0); |
192 | (void)std::ranges::replace_copy(first, last, first2, value, T(), Proj(&copies)); assert(copies == 0); |
193 | (void)std::ranges::replace_copy(a, first2, value, T(), Proj(&copies)); assert(copies == 0); |
194 | (void)std::ranges::replace_copy_if(first, last, first2, UnaryTrue(), T(), Proj(&copies)); assert(copies == 0); |
195 | (void)std::ranges::replace_copy_if(a, first2, UnaryTrue(), T(), Proj(&copies)); assert(copies == 0); |
196 | (void)std::ranges::replace(first, last, value, T(), Proj(&copies)); assert(copies == 0); |
197 | (void)std::ranges::replace(a, value, T(), Proj(&copies)); assert(copies == 0); |
198 | (void)std::ranges::replace_if(first, last, UnaryTrue(), T(), Proj(&copies)); assert(copies == 0); |
199 | (void)std::ranges::replace_if(a, UnaryTrue(), T(), Proj(&copies)); assert(copies == 0); |
200 | (void)std::ranges::search(first, last, first2, mid2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
201 | (void)std::ranges::search(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
202 | (void)std::ranges::search_n(first, last, count, value, Equal(), Proj(&copies)); assert(copies == 0); |
203 | (void)std::ranges::search_n(a, count, value, Equal(), Proj(&copies)); assert(copies == 0); |
204 | (void)std::ranges::set_difference(first, mid, mid, last, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
205 | (void)std::ranges::set_difference(a, b, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
206 | (void)std::ranges::set_intersection(first, mid, mid, last, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
207 | (void)std::ranges::set_intersection(a, b, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
208 | (void)std::ranges::set_symmetric_difference(first, mid, mid, last, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
209 | (void)std::ranges::set_symmetric_difference(a, b, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
210 | (void)std::ranges::set_union(first, mid, mid, last, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
211 | (void)std::ranges::set_union(a, b, first2, Less(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
212 | (void)std::ranges::sort(first, last, Less(), Proj(&copies)); assert(copies == 0); |
213 | (void)std::ranges::sort(a, Less(), Proj(&copies)); assert(copies == 0); |
214 | (void)std::ranges::sort_heap(first, last, Less(), Proj(&copies)); assert(copies == 0); |
215 | (void)std::ranges::sort_heap(a, Less(), Proj(&copies)); assert(copies == 0); |
216 | if (!std::is_constant_evaluated()) { (void)std::ranges::stable_partition(first, last, UnaryTrue(), Proj(&copies)); assert(copies == 0); } |
217 | if (!std::is_constant_evaluated()) { (void)std::ranges::stable_partition(a, UnaryTrue(), Proj(&copies)); assert(copies == 0); } |
218 | if (!std::is_constant_evaluated()) { (void)std::ranges::stable_sort(first, last, Less(), Proj(&copies)); assert(copies == 0); } |
219 | if (!std::is_constant_evaluated()) { (void)std::ranges::stable_sort(a, Less(), Proj(&copies)); assert(copies == 0); } |
220 | #if TEST_STD_VER > 20 |
221 | (void)std::ranges::starts_with(first, last, first2, last2, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
222 | (void)std::ranges::starts_with(a, b, Equal(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
223 | #endif |
224 | (void)std::ranges::transform(first, last, first2, UnaryTransform(), Proj(&copies)); assert(copies == 0); |
225 | (void)std::ranges::transform(a, first2, UnaryTransform(), Proj(&copies)); assert(copies == 0); |
226 | (void)std::ranges::transform(first, mid, mid, last, first2, BinaryTransform(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
227 | (void)std::ranges::transform(a, b, first2, BinaryTransform(), Proj(&copies), Proj(&copies)); assert(copies == 0); |
228 | (void)std::ranges::unique(first, last, Equal(), Proj(&copies)); assert(copies == 0); |
229 | (void)std::ranges::unique(a, Equal(), Proj(&copies)); assert(copies == 0); |
230 | (void)std::ranges::unique_copy(first, last, first2, Equal(), Proj(&copies)); assert(copies == 0); |
231 | (void)std::ranges::unique_copy(a, first2, Equal(), Proj(&copies)); assert(copies == 0); |
232 | (void)std::ranges::upper_bound(first, last, value, Less(), Proj(&copies)); assert(copies == 0); |
233 | (void)std::ranges::upper_bound(a, value, Less(), Proj(&copies)); assert(copies == 0); |
234 | |
235 | return true; |
236 | } |
237 | |
238 | void test_deque() { |
239 | std::deque<T> d; |
240 | int copies = 0; |
241 | void* value = nullptr; |
242 | |
243 | (void)std::ranges::find(d, value, Proj(&copies)); |
244 | assert(copies == 0); |
245 | } |
246 | |
247 | int main(int, char**) { |
248 | test_deque(); |
249 | all_the_algorithms(); |
250 | static_assert(all_the_algorithms()); |
251 | |
252 | return 0; |
253 | } |
254 | |