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