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