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 | // REQUIRES: stdlib=libc++ |
11 | |
12 | // [algorithms.requirements]/2 |
13 | // [range.iter.ops.general]/2 |
14 | |
15 | #include <algorithm> |
16 | #include <concepts> |
17 | #include <iterator> |
18 | #include <memory> |
19 | #include <random> |
20 | #include <ranges> |
21 | #include <type_traits> |
22 | #include <utility> |
23 | #include "test_macros.h" |
24 | |
25 | // Niebloids, unlike CPOs, are *not* required to be semiregular or even to have |
26 | // a declared type at all; they are specified as "magic" overload sets whose |
27 | // names are not found by argument-dependent lookup and which inhibit |
28 | // argument-dependent lookup if they are found via a `using`-declaration. |
29 | // |
30 | // libc++ implements them using the same function-object technique we use for CPOs; |
31 | // therefore this file should stay in sync with ./cpo.compile.pass.cpp. |
32 | |
33 | template <class CPO, class... Args> |
34 | constexpr bool test(CPO& o, Args&&...) { |
35 | static_assert(std::is_const_v<CPO>); |
36 | static_assert(std::is_class_v<CPO>); |
37 | static_assert(std::is_trivial_v<CPO>); |
38 | |
39 | auto p = o; |
40 | using T = decltype(p); |
41 | |
42 | // The type of a customization point object, ignoring cv-qualifiers, shall model semiregular. |
43 | static_assert(std::semiregular<T>); |
44 | |
45 | // The type T of a customization point object, ignoring cv-qualifiers, shall model... |
46 | static_assert(std::invocable<T&, Args...>); |
47 | static_assert(std::invocable<const T&, Args...>); |
48 | static_assert(std::invocable<T, Args...>); |
49 | static_assert(std::invocable<const T, Args...>); |
50 | |
51 | return true; |
52 | } |
53 | |
54 | int *p; |
55 | int a[10]; |
56 | auto odd = [](int x) { return x % 2 != 0; }; |
57 | auto triple = [](int x) { return 3*x; }; |
58 | auto gen = [] { return 42; }; |
59 | std::mt19937 g; |
60 | |
61 | // [algorithm.syn] |
62 | |
63 | static_assert(test(std::ranges::adjacent_find, a)); |
64 | static_assert(test(std::ranges::all_of, a, odd)); |
65 | static_assert(test(std::ranges::any_of, a, odd)); |
66 | static_assert(test(std::ranges::binary_search, a, 42)); |
67 | static_assert(test(std::ranges::clamp, 42, 42, 42)); |
68 | #if TEST_STD_VER >= 23 |
69 | static_assert(test(std::ranges::contains, a, 42)); |
70 | static_assert(test(std::ranges::contains_subrange, a, a)); |
71 | #endif |
72 | static_assert(test(std::ranges::copy, a, a)); |
73 | static_assert(test(std::ranges::copy_backward, a, a)); |
74 | static_assert(test(std::ranges::copy_if, a, a, odd)); |
75 | static_assert(test(std::ranges::copy_n, a, 10, a)); |
76 | static_assert(test(std::ranges::count, a, 42)); |
77 | static_assert(test(std::ranges::count_if, a, odd)); |
78 | #if TEST_STD_VER >= 23 |
79 | static_assert(test(std::ranges::ends_with, a, a)); |
80 | #endif |
81 | static_assert(test(std::ranges::equal, a, a)); |
82 | static_assert(test(std::ranges::equal_range, a, 42)); |
83 | static_assert(test(std::ranges::fill, a, 42)); |
84 | static_assert(test(std::ranges::fill_n, a, 10, 42)); |
85 | static_assert(test(std::ranges::find, a, 42)); |
86 | static_assert(test(std::ranges::find_end, a, a)); |
87 | static_assert(test(std::ranges::find_first_of, a, a)); |
88 | static_assert(test(std::ranges::find_if, a, odd)); |
89 | static_assert(test(std::ranges::find_if_not, a, odd)); |
90 | #if TEST_STD_VER >= 23 |
91 | static_assert(test(std::ranges::fold_left, a, 0, std::plus())); |
92 | static_assert(test(std::ranges::fold_left_with_iter, a, 0, std::plus())); |
93 | #endif |
94 | static_assert(test(std::ranges::for_each, a, odd)); |
95 | static_assert(test(std::ranges::for_each_n, a, 10, odd)); |
96 | static_assert(test(std::ranges::generate, a, gen)); |
97 | static_assert(test(std::ranges::generate_n, a, 10, gen)); |
98 | static_assert(test(std::ranges::includes, a, a)); |
99 | static_assert(test(std::ranges::inplace_merge, a, a+5)); |
100 | static_assert(test(std::ranges::is_heap, a)); |
101 | static_assert(test(std::ranges::is_heap_until, a)); |
102 | static_assert(test(std::ranges::is_partitioned, a, odd)); |
103 | static_assert(test(std::ranges::is_permutation, a, a)); |
104 | static_assert(test(std::ranges::is_sorted, a)); |
105 | static_assert(test(std::ranges::is_sorted_until, a)); |
106 | static_assert(test(std::ranges::lexicographical_compare, a, a)); |
107 | static_assert(test(std::ranges::lower_bound, a, 42)); |
108 | static_assert(test(std::ranges::make_heap, a)); |
109 | static_assert(test(std::ranges::max, a)); |
110 | static_assert(test(std::ranges::max_element, a)); |
111 | static_assert(test(std::ranges::merge, a, a, a)); |
112 | static_assert(test(std::ranges::min, a)); |
113 | static_assert(test(std::ranges::min_element, a)); |
114 | static_assert(test(std::ranges::minmax, a)); |
115 | static_assert(test(std::ranges::minmax_element, a)); |
116 | static_assert(test(std::ranges::mismatch, a, a)); |
117 | static_assert(test(std::ranges::move, a, a)); |
118 | static_assert(test(std::ranges::move_backward, a, a)); |
119 | static_assert(test(std::ranges::next_permutation, a)); |
120 | static_assert(test(std::ranges::none_of, a, odd)); |
121 | static_assert(test(std::ranges::nth_element, a, a+5)); |
122 | static_assert(test(std::ranges::partial_sort, a, a+5)); |
123 | static_assert(test(std::ranges::partial_sort_copy, a, a)); |
124 | static_assert(test(std::ranges::partition, a, odd)); |
125 | static_assert(test(std::ranges::partition_copy, a, a, a, odd)); |
126 | static_assert(test(std::ranges::partition_point, a, odd)); |
127 | static_assert(test(std::ranges::pop_heap, a)); |
128 | static_assert(test(std::ranges::prev_permutation, a)); |
129 | static_assert(test(std::ranges::push_heap, a)); |
130 | static_assert(test(std::ranges::remove, a, 42)); |
131 | static_assert(test(std::ranges::remove_copy, a, a, 42)); |
132 | static_assert(test(std::ranges::remove_copy_if, a, a, odd)); |
133 | static_assert(test(std::ranges::remove_if, a, odd)); |
134 | static_assert(test(std::ranges::replace, a, 42, 43)); |
135 | static_assert(test(std::ranges::replace_copy, a, a, 42, 43)); |
136 | static_assert(test(std::ranges::replace_copy_if, a, a, odd, 43)); |
137 | static_assert(test(std::ranges::replace_if, a, odd, 43)); |
138 | static_assert(test(std::ranges::reverse, a)); |
139 | static_assert(test(std::ranges::reverse_copy, a, a)); |
140 | static_assert(test(std::ranges::rotate, a, a+5)); |
141 | static_assert(test(std::ranges::rotate_copy, a, a+5, a)); |
142 | static_assert(test(std::ranges::sample, a, a, 5, g)); |
143 | static_assert(test(std::ranges::search, a, a)); |
144 | static_assert(test(std::ranges::search_n, a, 10, 42)); |
145 | static_assert(test(std::ranges::set_difference, a, a, a)); |
146 | static_assert(test(std::ranges::set_intersection, a, a, a)); |
147 | static_assert(test(std::ranges::set_symmetric_difference, a, a, a)); |
148 | static_assert(test(std::ranges::set_union, a, a, a)); |
149 | static_assert(test(std::ranges::shuffle, a, g)); |
150 | static_assert(test(std::ranges::sort, a)); |
151 | static_assert(test(std::ranges::sort_heap, a)); |
152 | static_assert(test(std::ranges::stable_partition, a, odd)); |
153 | static_assert(test(std::ranges::stable_sort, a)); |
154 | #if TEST_STD_VER > 20 |
155 | static_assert(test(std::ranges::starts_with, a, a)); |
156 | #endif |
157 | static_assert(test(std::ranges::swap_ranges, a, a)); |
158 | static_assert(test(std::ranges::transform, a, a, triple)); |
159 | static_assert(test(std::ranges::unique, a)); |
160 | static_assert(test(std::ranges::unique_copy, a, a)); |
161 | static_assert(test(std::ranges::upper_bound, a, 42)); |
162 | |
163 | // [memory.syn] |
164 | |
165 | static_assert(test(std::ranges::construct_at, a, 42)); |
166 | static_assert(test(std::ranges::destroy, a)); |
167 | static_assert(test(std::ranges::destroy, a, a+10)); |
168 | static_assert(test(std::ranges::destroy_at, a)); |
169 | static_assert(test(std::ranges::destroy_n, a, 10)); |
170 | static_assert(test(std::ranges::uninitialized_copy, a, a)); |
171 | static_assert(test(std::ranges::uninitialized_copy, a, a+10, a, a+10)); |
172 | static_assert(test(std::ranges::uninitialized_copy_n, a, 10, a, a+10)); |
173 | static_assert(test(std::ranges::uninitialized_default_construct, a)); |
174 | static_assert(test(std::ranges::uninitialized_default_construct, a, a+10)); |
175 | static_assert(test(std::ranges::uninitialized_default_construct_n, a, 10)); |
176 | static_assert(test(std::ranges::uninitialized_fill, a, 42)); |
177 | static_assert(test(std::ranges::uninitialized_fill, a, a+10, 42)); |
178 | static_assert(test(std::ranges::uninitialized_fill_n, a, 10, 42)); |
179 | static_assert(test(std::ranges::uninitialized_move, a, a)); |
180 | static_assert(test(std::ranges::uninitialized_move, a, a+10, a, a+10)); |
181 | static_assert(test(std::ranges::uninitialized_move_n, a, 10, a, a+10)); |
182 | static_assert(test(std::ranges::uninitialized_value_construct, a)); |
183 | static_assert(test(std::ranges::uninitialized_value_construct, a, a+10)); |
184 | static_assert(test(std::ranges::uninitialized_value_construct_n, a, 10)); |
185 | |
186 | // [numeric.ops.overview] currently has no ranges algorithms. See P1813, P2214 |
187 | |
188 | // [range.iter.ops] |
189 | |
190 | static_assert(test(std::ranges::advance, p, 5)); |
191 | static_assert(test(std::ranges::advance, p, 5, a+10)); |
192 | static_assert(test(std::ranges::advance, p, a+10)); |
193 | static_assert(test(std::ranges::distance, a)); |
194 | static_assert(test(std::ranges::distance, a, a+10)); |
195 | static_assert(test(std::ranges::next, a)); |
196 | static_assert(test(std::ranges::next, a, 5)); |
197 | static_assert(test(std::ranges::next, a, 5, a+10)); |
198 | static_assert(test(std::ranges::next, a, a+10)); |
199 | static_assert(test(std::ranges::prev, a+10)); |
200 | static_assert(test(std::ranges::prev, a+10, 5)); |
201 | static_assert(test(std::ranges::prev, a+10, 5, a)); |
202 | |