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
19template <class Sub, class Iterator>
20struct 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
67template <typename It>
68struct Cpp20HostileIterator
69 : IteratorAdaptorBase<Cpp20HostileIterator<It>, It> {
70 Cpp20HostileIterator() {}
71 Cpp20HostileIterator(It) {}
72};
73
74struct Pred {
75 bool operator()(int, int) { return false; }
76 bool operator()(int) { return false; }
77 int operator()() { return 0; }
78};
79
80void 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

source code of libcxx/test/libcxx/algorithms/robust_against_cpp20_hostile_iterators.compile.pass.cpp