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