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 | // Check that all STL classic algorithms can be instantiated with a C++20-hostile iterator |
10 | |
11 | // ADDITIONAL_COMPILE_FLAGS: -Wno-ambiguous-reversed-operator |
12 | |
13 | #include <algorithm> |
14 | #include <functional> |
15 | #include <random> |
16 | |
17 | #include "test_macros.h" |
18 | |
19 | template <class Sub, class Iterator> |
20 | struct IteratorAdaptorBase { |
21 | using OutTraits = std::iterator_traits<Iterator>; |
22 | using iterator_category = typename OutTraits::iterator_category; |
23 | using value_type = typename OutTraits::value_type; |
24 | using pointer = typename OutTraits::pointer; |
25 | using reference = typename OutTraits::reference; |
26 | using difference_type = typename OutTraits::difference_type; |
27 | |
28 | IteratorAdaptorBase() {} |
29 | IteratorAdaptorBase(Iterator) {} |
30 | |
31 | Sub& sub() { return static_cast<Sub&>(*this); } |
32 | const Sub& sub() const { return static_cast<Sub&>(*this); } |
33 | |
34 | const Iterator& base() const { return it_; } |
35 | |
36 | reference get() const { return *it_; } |
37 | reference operator*() const { return *it_; } |
38 | pointer operator->() const { return it_; } |
39 | reference operator[](difference_type) const { return *it_; } |
40 | |
41 | Sub& operator++() { return static_cast<Sub&>(*this); } |
42 | Sub& operator--() { return static_cast<Sub&>(*this); } |
43 | Sub operator++(int) { return static_cast<Sub&>(*this); } |
44 | Sub operator--(int) { return static_cast<Sub&>(*this); } |
45 | |
46 | Sub& operator+=(difference_type) { return static_cast<Sub&>(*this); } |
47 | Sub& operator-=(difference_type) { return static_cast<Sub&>(*this); } |
48 | bool operator==(Sub) const { return false; } |
49 | bool operator!=(Sub) const { return false; } |
50 | bool operator==(Iterator b) const { return *this == Sub(b); } |
51 | bool operator!=(Iterator b) const { return *this != Sub(b); } |
52 | |
53 | friend Sub operator+(Sub, difference_type) { return Sub(); } |
54 | friend Sub operator+(difference_type, Sub) { return Sub(); } |
55 | friend Sub operator-(Sub, difference_type) { return Sub(); } |
56 | friend difference_type operator-(Sub, Sub) { return 0; } |
57 | |
58 | friend bool operator<(Sub, Sub) { return false; } |
59 | friend bool operator>(Sub, Sub) { return false; } |
60 | friend bool operator<=(Sub, Sub) { return false; } |
61 | friend bool operator>=(Sub, Sub) { return false; } |
62 | |
63 | private: |
64 | Iterator it_; |
65 | }; |
66 | |
67 | template <typename It> |
68 | struct Cpp20HostileIterator |
69 | : IteratorAdaptorBase<Cpp20HostileIterator<It>, It> { |
70 | Cpp20HostileIterator() {} |
71 | Cpp20HostileIterator(It) {} |
72 | }; |
73 | |
74 | struct Pred { |
75 | bool operator()(int, int) { return false; } |
76 | bool operator()(int) { return false; } |
77 | int operator()() { return 0; } |
78 | }; |
79 | |
80 | void test() { |
81 | Cpp20HostileIterator<int*> it; |
82 | Pred pred; |
83 | std::mt19937_64 rng; |
84 | |
85 | (void) std::adjacent_find(first: it, last: it); |
86 | (void) std::adjacent_find(first: it, last: it, binary_pred: pred); |
87 | (void) std::all_of(first: it, last: it, pred: pred); |
88 | (void) std::any_of(first: it, last: it, pred: pred); |
89 | (void) std::binary_search(first: it, last: it, val: 0); |
90 | (void) std::binary_search(first: it, last: it, val: 0, comp: pred); |
91 | (void) std::copy_backward(first: it, last: it, result: it); |
92 | (void) std::copy_if(first: it, last: it, result: it, pred: pred); |
93 | (void) std::copy_n(first: it, n: 0, result: it); |
94 | (void) std::copy(first: it, last: it, result: it); |
95 | (void) std::count_if(first: it, last: it, pred: pred); |
96 | (void) std::count(first: it, last: it, value: 0); |
97 | (void) std::equal_range(first: it, last: it, val: 0); |
98 | (void) std::equal_range(first: it, last: it, val: 0, comp: pred); |
99 | (void) std::equal(first1: it, last1: it, first2: it); |
100 | (void) std::equal(first1: it, last1: it, first2: it, binary_pred: pred); |
101 | #if TEST_STD_VER > 11 |
102 | (void) std::equal(it, it, it, it); |
103 | (void) std::equal(it, it, it, it, pred); |
104 | #endif |
105 | (void) std::fill_n(first: it, n: 0, value: 0); |
106 | (void) std::fill(first: it, last: it, value: 0); |
107 | (void) std::find_end(first1: it, last1: it, first2: it, last2: it); |
108 | (void) std::find_end(first1: it, last1: it, first2: it, last2: it, comp: pred); |
109 | (void) std::find_first_of(first1: it, last1: it, first2: it, last2: it); |
110 | (void) std::find_first_of(first1: it, last1: it, first2: it, last2: it, comp: pred); |
111 | (void) std::find_if_not(first: it, last: it, pred: pred); |
112 | (void) std::find_if(first: it, last: it, pred: pred); |
113 | (void) std::find(first: it, last: it, val: 0); |
114 | #if TEST_STD_VER > 14 |
115 | (void) std::for_each_n(it, 0, pred); |
116 | #endif |
117 | (void) std::for_each(first: it, last: it, f: pred); |
118 | (void) std::generate_n(first: it, n: 0, gen: pred); |
119 | (void) std::generate(first: it, last: it, gen: pred); |
120 | (void) std::includes(first1: it, last1: it, first2: it, last2: it); |
121 | (void) std::includes(first1: it, last1: it, first2: it, last2: it, comp: pred); |
122 | (void) std::inplace_merge(first: it, middle: it, last: it); |
123 | (void) std::inplace_merge(first: it, middle: it, last: it, comp: pred); |
124 | (void) std::is_heap_until(first: it, last: it); |
125 | (void) std::is_heap_until(first: it, last: it, comp: pred); |
126 | (void) std::is_heap(first: it, last: it); |
127 | (void) std::is_heap(first: it, last: it, comp: pred); |
128 | (void) std::is_partitioned(first: it, last: it, pred: pred); |
129 | (void) std::is_permutation(first1: it, last1: it, first2: it); |
130 | (void) std::is_permutation(first1: it, last1: it, first2: it, pred: pred); |
131 | #if TEST_STD_VER > 11 |
132 | (void) std::is_permutation(it, it, it, it); |
133 | (void) std::is_permutation(it, it, it, it, pred); |
134 | #endif |
135 | (void) std::is_sorted_until(first: it, last: it); |
136 | (void) std::is_sorted_until(first: it, last: it, comp: pred); |
137 | (void) std::is_sorted(first: it, last: it); |
138 | (void) std::is_sorted(first: it, last: it, comp: pred); |
139 | (void) std::lexicographical_compare(first1: it, last1: it, first2: it, last2: it); |
140 | (void) std::lexicographical_compare(first1: it, last1: it, first2: it, last2: it, comp: pred); |
141 | #if TEST_STD_VER > 17 |
142 | (void)std::lexicographical_compare_three_way(it, it, it, it); |
143 | (void)std::lexicographical_compare_three_way(it, it, it, it, std::compare_three_way()); |
144 | #endif |
145 | (void) std::lower_bound(first: it, last: it, val: 0); |
146 | (void) std::lower_bound(first: it, last: it, val: 0, comp: pred); |
147 | (void) std::make_heap(first: it, last: it); |
148 | (void) std::make_heap(first: it, last: it, comp: pred); |
149 | (void) std::max_element(first: it, last: it); |
150 | (void) std::max_element(first: it, last: it, comp: pred); |
151 | (void) std::merge(first1: it, last1: it, first2: it, last2: it, result: it); |
152 | (void) std::merge(first1: it, last1: it, first2: it, last2: it, result: it, comp: pred); |
153 | (void) std::min_element(first: it, last: it); |
154 | (void) std::min_element(first: it, last: it, comp: pred); |
155 | (void) std::minmax_element(first: it, last: it); |
156 | (void) std::minmax_element(first: it, last: it, comp: pred); |
157 | (void) std::mismatch(first1: it, last1: it, first2: it); |
158 | (void) std::mismatch(first1: it, last1: it, first2: it, binary_pred: pred); |
159 | (void) std::move_backward(first: it, last: it, result: it); |
160 | (void) std::move(first: it, last: it, result: it); |
161 | (void) std::next_permutation(first: it, last: it); |
162 | (void) std::next_permutation(first: it, last: it, comp: pred); |
163 | (void) std::none_of(first: it, last: it, pred: pred); |
164 | (void) std::nth_element(first: it, nth: it, last: it); |
165 | (void) std::nth_element(first: it, nth: it, last: it, comp: pred); |
166 | (void) std::partial_sort_copy(first: it, last: it, result_first: it, result_last: it); |
167 | (void) std::partial_sort_copy(first: it, last: it, result_first: it, result_last: it, comp: pred); |
168 | (void) std::partial_sort(first: it, middle: it, last: it); |
169 | (void) std::partial_sort(first: it, middle: it, last: it, comp: pred); |
170 | (void) std::partition_copy(first: it, last: it, out_true: it, out_false: it, pred: pred); |
171 | (void) std::partition_point(first: it, last: it, pred: pred); |
172 | (void) std::partition(first: it, last: it, pred: pred); |
173 | (void) std::pop_heap(first: it, last: it); |
174 | (void) std::pop_heap(first: it, last: it, comp: pred); |
175 | (void) std::prev_permutation(first: it, last: it); |
176 | (void) std::prev_permutation(first: it, last: it, comp: pred); |
177 | (void) std::push_heap(first: it, last: it); |
178 | (void) std::push_heap(first: it, last: it, comp: pred); |
179 | (void) std::remove_copy_if(first: it, last: it, result: it, pred: pred); |
180 | (void) std::remove_copy(first: it, last: it, result: it, value: 0); |
181 | (void) std::remove_if(first: it, last: it, pred: pred); |
182 | (void) std::remove(first: it, last: it, value: 0); |
183 | (void) std::replace_copy_if(first: it, last: it, result: it, pred: pred, new_value: 0); |
184 | (void) std::replace_copy(first: it, last: it, result: it, old_value: 0, new_value: 0); |
185 | (void) std::replace_if(first: it, last: it, pred: pred, new_value: 0); |
186 | (void) std::replace(first: it, last: it, old_value: 0, new_value: 0); |
187 | (void) std::reverse_copy(first: it, last: it, result: it); |
188 | (void) std::reverse(first: it, last: it); |
189 | (void) std::rotate_copy(first: it, middle: it, last: it, result: it); |
190 | (void) std::rotate(first: it, middle: it, last: it); |
191 | #if TEST_STD_VER > 14 |
192 | (void) std::sample(it, it, it, 0, rng); |
193 | #endif |
194 | (void) std::search(first1: it, last1: it, first2: it, last2: it); |
195 | (void) std::search(first1: it, last1: it, first2: it, last2: it, predicate: pred); |
196 | #if TEST_STD_VER > 14 |
197 | (void) std::search(it, it, std::default_searcher<Cpp20HostileIterator<int*>>(it, it)); |
198 | #endif |
199 | (void) std::set_difference(first1: it, last1: it, first2: it, last2: it, result: it); |
200 | (void) std::set_difference(first1: it, last1: it, first2: it, last2: it, result: it, comp: pred); |
201 | (void) std::set_intersection(first1: it, last1: it, first2: it, last2: it, result: it); |
202 | (void) std::set_intersection(first1: it, last1: it, first2: it, last2: it, result: it, comp: pred); |
203 | (void) std::set_symmetric_difference(first1: it, last1: it, first2: it, last2: it, result: it); |
204 | (void) std::set_symmetric_difference(first1: it, last1: it, first2: it, last2: it, result: it, comp: pred); |
205 | (void) std::set_union(first1: it, last1: it, first2: it, last2: it, result: it); |
206 | (void) std::set_union(first1: it, last1: it, first2: it, last2: it, result: it, comp: pred); |
207 | #if TEST_STD_VER > 17 |
208 | (void) std::shift_left(it, it, 0); |
209 | (void) std::shift_right(it, it, 0); |
210 | #endif |
211 | (void) std::shuffle(first: it, last: it, g&: rng); |
212 | (void) std::sort_heap(first: it, last: it); |
213 | (void) std::sort_heap(first: it, last: it, comp: pred); |
214 | (void) std::sort(first: it, last: it); |
215 | (void) std::sort(first: it, last: it, comp: pred); |
216 | (void) std::stable_partition(first: it, last: it, pred: pred); |
217 | (void) std::stable_sort(first: it, last: it); |
218 | (void) std::swap_ranges(first1: it, last1: it, first2: it); |
219 | (void) std::transform(first: it, last: it, result: it, unary_op: pred); |
220 | (void) std::transform(first1: it, last1: it, first2: it, result: it, binary_op: pred); |
221 | (void) std::unique_copy(first: it, last: it, result: it); |
222 | (void) std::unique(first: it, last: it); |
223 | (void) std::upper_bound(first: it, last: it, val: 0); |
224 | } |
225 | |