Skip to content

Commit 3e02c8e

Browse files
committed
[libc++] [test] Add ranges_robust_against_copying_*.pass.cpp
This tests the same QoI issue as the existing STL Classic test, but for the Ranges algorithms. Also, do the same thing for all the algorithms that take projections. I found a few missing algorithms and added them to the existing test, too. `std::find_first_of` currently fails; I should look at why that is (and in particular, what is it doing weird that //makes// it inconsistent with the entire rest of libc++?). Reviewed By: ldionne, #libc Spies: libcxx-commits Differential Revision: https://reviews.llvm.org/D121265
1 parent ce3feeb commit 3e02c8e

File tree

3 files changed

+489
-1
lines changed

3 files changed

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

0 commit comments

Comments
 (0)