xref: /llvm-project/libcxx/test/std/algorithms/alg.nonmodifying/alg.search/ranges.search.pass.cpp (revision c000f754bfb9fb3a7a0a1f9b0485f36ae70534b7)
1101d1e9bSNikolas Klauser //===----------------------------------------------------------------------===//
2101d1e9bSNikolas Klauser //
3101d1e9bSNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4101d1e9bSNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
5101d1e9bSNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6101d1e9bSNikolas Klauser //
7101d1e9bSNikolas Klauser //===----------------------------------------------------------------------===//
8101d1e9bSNikolas Klauser 
9101d1e9bSNikolas Klauser // <algorithm>
10101d1e9bSNikolas Klauser 
11101d1e9bSNikolas Klauser // UNSUPPORTED: c++03, c++11, c++14, c++17
12101d1e9bSNikolas Klauser 
13101d1e9bSNikolas Klauser // template<forward_iterator I1, sentinel_for<I1> S1, forward_iterator I2,
14101d1e9bSNikolas Klauser //          sentinel_for<I2> S2, class Pred = ranges::equal_to,
15101d1e9bSNikolas Klauser //          class Proj1 = identity, class Proj2 = identity>
16101d1e9bSNikolas Klauser //   requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
17101d1e9bSNikolas Klauser //   constexpr subrange<I1>
18101d1e9bSNikolas Klauser //     ranges::search(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred = {},
19101d1e9bSNikolas Klauser //                    Proj1 proj1 = {}, Proj2 proj2 = {});
20101d1e9bSNikolas Klauser // template<forward_range R1, forward_range R2, class Pred = ranges::equal_to,
21101d1e9bSNikolas Klauser //          class Proj1 = identity, class Proj2 = identity>
22101d1e9bSNikolas Klauser //   requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
23101d1e9bSNikolas Klauser //   constexpr borrowed_subrange_t<R1>
24101d1e9bSNikolas Klauser //     ranges::search(R1&& r1, R2&& r2, Pred pred = {},
25101d1e9bSNikolas Klauser //                    Proj1 proj1 = {}, Proj2 proj2 = {});
26101d1e9bSNikolas Klauser 
27101d1e9bSNikolas Klauser #include <algorithm>
28101d1e9bSNikolas Klauser #include <array>
29101d1e9bSNikolas Klauser #include <ranges>
30101d1e9bSNikolas Klauser 
31101d1e9bSNikolas Klauser #include "almost_satisfies_types.h"
32101d1e9bSNikolas Klauser #include "test_iterators.h"
33101d1e9bSNikolas Klauser 
34101d1e9bSNikolas Klauser template <class Iter1, class Sent1 = Iter1, class Iter2 = int*, class Sent2 = Iter2>
35101d1e9bSNikolas Klauser concept HasSearchIt = requires (Iter1 first1, Sent1 last1, Iter2 first2, Sent2 last2) {
36101d1e9bSNikolas Klauser   std::ranges::search(first1, last1, first2, last2);
37101d1e9bSNikolas Klauser };
38101d1e9bSNikolas Klauser 
39101d1e9bSNikolas Klauser static_assert(HasSearchIt<int*>);
40101d1e9bSNikolas Klauser static_assert(!HasSearchIt<ForwardIteratorNotDerivedFrom>);
41101d1e9bSNikolas Klauser static_assert(!HasSearchIt<ForwardIteratorNotIncrementable>);
42101d1e9bSNikolas Klauser static_assert(!HasSearchIt<int*, SentinelForNotSemiregular>);
43101d1e9bSNikolas Klauser static_assert(!HasSearchIt<int*, int*, int**>); // not indirectly comparable
44101d1e9bSNikolas Klauser static_assert(!HasSearchIt<int*, SentinelForNotWeaklyEqualityComparableWith>);
45101d1e9bSNikolas Klauser static_assert(!HasSearchIt<int*, int*, ForwardIteratorNotDerivedFrom>);
46101d1e9bSNikolas Klauser static_assert(!HasSearchIt<int*, int*, ForwardIteratorNotIncrementable>);
47101d1e9bSNikolas Klauser static_assert(!HasSearchIt<int*, int*, int*, SentinelForNotSemiregular>);
48101d1e9bSNikolas Klauser static_assert(!HasSearchIt<int*, int*, int*, SentinelForNotWeaklyEqualityComparableWith>);
49101d1e9bSNikolas Klauser 
50101d1e9bSNikolas Klauser template <class Range1, class Range2 = UncheckedRange<int*>>
51101d1e9bSNikolas Klauser concept HasSearchR = requires (Range1 range1, Range2 range2) {
52101d1e9bSNikolas Klauser   std::ranges::search(range1, range2);
53101d1e9bSNikolas Klauser };
54101d1e9bSNikolas Klauser 
55101d1e9bSNikolas Klauser static_assert(HasSearchR<UncheckedRange<int*>>);
56101d1e9bSNikolas Klauser static_assert(!HasSearchR<ForwardRangeNotDerivedFrom>);
57101d1e9bSNikolas Klauser static_assert(!HasSearchR<ForwardIteratorNotIncrementable>);
58101d1e9bSNikolas Klauser static_assert(!HasSearchR<ForwardRangeNotSentinelSemiregular>);
59101d1e9bSNikolas Klauser static_assert(!HasSearchR<ForwardRangeNotSentinelEqualityComparableWith>);
60101d1e9bSNikolas Klauser static_assert(!HasSearchR<UncheckedRange<int*>, UncheckedRange<int**>>); // not indirectly comparable
61101d1e9bSNikolas Klauser static_assert(!HasSearchR<UncheckedRange<int*>, ForwardRangeNotDerivedFrom>);
62101d1e9bSNikolas Klauser static_assert(!HasSearchR<UncheckedRange<int*>, ForwardRangeNotIncrementable>);
63101d1e9bSNikolas Klauser static_assert(!HasSearchR<UncheckedRange<int*>, ForwardRangeNotSentinelSemiregular>);
64101d1e9bSNikolas Klauser static_assert(!HasSearchR<UncheckedRange<int*>, ForwardRangeNotSentinelEqualityComparableWith>);
65101d1e9bSNikolas Klauser 
66101d1e9bSNikolas Klauser template <class Iter1, class Sent1, class Iter2, class Sent2 = Iter2>
test_iterators()67101d1e9bSNikolas Klauser constexpr void test_iterators() {
68101d1e9bSNikolas Klauser   { // simple test
69101d1e9bSNikolas Klauser     {
70101d1e9bSNikolas Klauser       int a[] = {1, 2, 3, 4, 5, 6};
71101d1e9bSNikolas Klauser       int p[] = {3, 4};
72101d1e9bSNikolas Klauser       std::same_as<std::ranges::subrange<Iter1, Iter1>> decltype(auto) ret =
73101d1e9bSNikolas Klauser           std::ranges::search(Iter1(a), Sent1(Iter1(a + 6)), Iter2(p), Sent2(Iter2(p + 2)));
74101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a + 2);
75101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 4);
76101d1e9bSNikolas Klauser     }
77101d1e9bSNikolas Klauser     {
78101d1e9bSNikolas Klauser       int a[] = {1, 2, 3, 4, 5, 6};
79101d1e9bSNikolas Klauser       int p[] = {3, 4};
80101d1e9bSNikolas Klauser       auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6)));
81101d1e9bSNikolas Klauser       auto range2 = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 2)));
82101d1e9bSNikolas Klauser       std::same_as<std::ranges::subrange<Iter1, Iter1>> decltype(auto) ret = std::ranges::search(range1, range2);
83101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a + 2);
84101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 4);
85101d1e9bSNikolas Klauser     }
86101d1e9bSNikolas Klauser   }
87101d1e9bSNikolas Klauser 
88101d1e9bSNikolas Klauser   { // matching part begins at the front
89101d1e9bSNikolas Klauser     {
90101d1e9bSNikolas Klauser       int a[] = {7, 5, 3, 7, 3, 6};
91101d1e9bSNikolas Klauser       int p[] = {7, 5, 3};
92101d1e9bSNikolas Klauser       auto ret = std::ranges::search(Iter1(a), Sent1(Iter1(a + 6)), Iter2(p), Sent2(Iter2(p + 3)));
93101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a);
94101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 3);
95101d1e9bSNikolas Klauser     }
96101d1e9bSNikolas Klauser     {
97101d1e9bSNikolas Klauser       int a[] = {7, 5, 3, 7, 3, 6};
98101d1e9bSNikolas Klauser       int p[] = {7, 5, 3};
99101d1e9bSNikolas Klauser       auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6)));
100101d1e9bSNikolas Klauser       auto range2 = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 3)));
101101d1e9bSNikolas Klauser       auto ret = std::ranges::search(range1, range2);
102101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a);
103101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 3);
104101d1e9bSNikolas Klauser     }
105101d1e9bSNikolas Klauser   }
106101d1e9bSNikolas Klauser 
107101d1e9bSNikolas Klauser   { // matching part ends at the back
108101d1e9bSNikolas Klauser     {
109101d1e9bSNikolas Klauser       int a[] = {9, 3, 6, 4, 8};
110101d1e9bSNikolas Klauser       int p[] = {4, 8};
111101d1e9bSNikolas Klauser       auto ret = std::ranges::search(Iter1(a), Sent1(Iter1(a + 5)), Iter2(p), Sent2(Iter2(p + 2)));
112101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a + 3);
113101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 5);
114101d1e9bSNikolas Klauser     }
115101d1e9bSNikolas Klauser     {
116101d1e9bSNikolas Klauser       int a[] = {9, 3, 6, 4, 8};
117101d1e9bSNikolas Klauser       int p[] = {4, 8};
118101d1e9bSNikolas Klauser       auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 5)));
119101d1e9bSNikolas Klauser       auto range2 = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 2)));
120101d1e9bSNikolas Klauser       auto ret = std::ranges::search(range1, range2);
121101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a + 3);
122101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 5);
123101d1e9bSNikolas Klauser     }
124101d1e9bSNikolas Klauser   }
125101d1e9bSNikolas Klauser 
126101d1e9bSNikolas Klauser   { // pattern does not match
127101d1e9bSNikolas Klauser     {
128101d1e9bSNikolas Klauser       int a[] = {9, 3, 6, 4, 8};
129101d1e9bSNikolas Klauser       int p[] = {1};
130101d1e9bSNikolas Klauser       auto ret = std::ranges::search(Iter1(a), Sent1(Iter1(a + 5)), Iter2(p), Sent2(Iter2(p + 1)));
131101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a + 5);
132101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 5);
133101d1e9bSNikolas Klauser     }
134101d1e9bSNikolas Klauser     {
135101d1e9bSNikolas Klauser       int a[] = {9, 3, 6, 4, 8};
136101d1e9bSNikolas Klauser       int p[] = {1};
137101d1e9bSNikolas Klauser       auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 5)));
138101d1e9bSNikolas Klauser       auto range2 = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 1)));
139101d1e9bSNikolas Klauser       auto ret = std::ranges::search(range1, range2);
140101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a + 5);
141101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 5);
142101d1e9bSNikolas Klauser     }
143101d1e9bSNikolas Klauser   }
144101d1e9bSNikolas Klauser 
145101d1e9bSNikolas Klauser   { // range and pattern are identical
146101d1e9bSNikolas Klauser     {
147101d1e9bSNikolas Klauser       int a[] = {6, 7, 8, 9};
148101d1e9bSNikolas Klauser       int p[] = {6, 7, 8, 9};
149101d1e9bSNikolas Klauser       auto ret = std::ranges::search(Iter1(a), Sent1(Iter1(a + 4)), Iter2(p), Sent2(Iter2(p + 4)));
150101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a);
151101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 4);
152101d1e9bSNikolas Klauser     }
153101d1e9bSNikolas Klauser     {
154101d1e9bSNikolas Klauser       int a[] = {6, 7, 8, 9};
155101d1e9bSNikolas Klauser       int p[] = {6, 7, 8, 9};
156101d1e9bSNikolas Klauser       auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 4)));
157101d1e9bSNikolas Klauser       auto range2 = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 4)));
158101d1e9bSNikolas Klauser       auto ret = std::ranges::search(range1, range2);
159101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a);
160101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 4);
161101d1e9bSNikolas Klauser     }
162101d1e9bSNikolas Klauser   }
163101d1e9bSNikolas Klauser 
164101d1e9bSNikolas Klauser   { // pattern is longer than range
165101d1e9bSNikolas Klauser     {
166101d1e9bSNikolas Klauser       int a[] = {6, 7, 8};
167101d1e9bSNikolas Klauser       int p[] = {6, 7, 8, 9};
168101d1e9bSNikolas Klauser       auto ret = std::ranges::search(Iter1(a), Sent1(Iter1(a + 3)), Iter2(p), Sent2(Iter2(p + 4)));
169101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a + 3);
170101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 3);
171101d1e9bSNikolas Klauser     }
172101d1e9bSNikolas Klauser     {
173101d1e9bSNikolas Klauser       int a[] = {6, 7, 8};
174101d1e9bSNikolas Klauser       int p[] = {6, 7, 8, 9};
175101d1e9bSNikolas Klauser       auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 3)));
176101d1e9bSNikolas Klauser       auto range2 = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 4)));
177101d1e9bSNikolas Klauser       auto ret = std::ranges::search(range1, range2);
178101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a + 3);
179101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 3);
180101d1e9bSNikolas Klauser     }
181101d1e9bSNikolas Klauser   }
182101d1e9bSNikolas Klauser 
183101d1e9bSNikolas Klauser   { // pattern has zero length
184101d1e9bSNikolas Klauser     {
185101d1e9bSNikolas Klauser       int a[] = {6, 7, 8};
186*c000f754SStephan T. Lavavej       std::array<int, 0> p = {};
187*c000f754SStephan T. Lavavej       auto ret = std::ranges::search(Iter1(a), Sent1(Iter1(a + 3)), Iter2(p.data()), Sent2(Iter2(p.data())));
188101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a);
189101d1e9bSNikolas Klauser       assert(base(ret.end()) == a);
190101d1e9bSNikolas Klauser     }
191101d1e9bSNikolas Klauser     {
192101d1e9bSNikolas Klauser       int a[] = {6, 7, 8};
193*c000f754SStephan T. Lavavej       std::array<int, 0> p = {};
194101d1e9bSNikolas Klauser       auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 3)));
195*c000f754SStephan T. Lavavej       auto range2          = std::ranges::subrange(Iter2(p.data()), Sent2(Iter2(p.data())));
196101d1e9bSNikolas Klauser       auto ret = std::ranges::search(range1, range2);
197101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a);
198101d1e9bSNikolas Klauser       assert(base(ret.end()) == a);
199101d1e9bSNikolas Klauser     }
200101d1e9bSNikolas Klauser   }
201101d1e9bSNikolas Klauser 
202101d1e9bSNikolas Klauser   { // range has zero length
203101d1e9bSNikolas Klauser     {
204*c000f754SStephan T. Lavavej       std::array<int, 0> a = {};
205101d1e9bSNikolas Klauser       int p[] = {6, 7, 8};
206*c000f754SStephan T. Lavavej       auto ret = std::ranges::search(Iter1(a.data()), Sent1(Iter1(a.data())), Iter2(p), Sent2(Iter2(p + 3)));
207*c000f754SStephan T. Lavavej       assert(base(ret.begin()) == a.data());
208*c000f754SStephan T. Lavavej       assert(base(ret.end()) == a.data());
209101d1e9bSNikolas Klauser     }
210101d1e9bSNikolas Klauser     {
211*c000f754SStephan T. Lavavej       std::array<int, 0> a = {};
212101d1e9bSNikolas Klauser       int p[] = {6, 7, 8};
213*c000f754SStephan T. Lavavej       auto range1          = std::ranges::subrange(Iter1(a.data()), Sent1(Iter1(a.data())));
214101d1e9bSNikolas Klauser       auto range2 = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 3)));
215101d1e9bSNikolas Klauser       auto ret = std::ranges::search(range1, range2);
216*c000f754SStephan T. Lavavej       assert(base(ret.begin()) == a.data());
217*c000f754SStephan T. Lavavej       assert(base(ret.end()) == a.data());
218101d1e9bSNikolas Klauser     }
219101d1e9bSNikolas Klauser   }
220101d1e9bSNikolas Klauser 
221101d1e9bSNikolas Klauser   { // check that the first match is returned
222101d1e9bSNikolas Klauser     {
223101d1e9bSNikolas Klauser       int a[] = {6, 7, 8, 6, 7, 8, 6, 7, 8};
224101d1e9bSNikolas Klauser       int p[] = {6, 7, 8};
225101d1e9bSNikolas Klauser       auto ret = std::ranges::search(Iter1(a), Sent1(Iter1(a + 9)), Iter2(p), Sent2(Iter2(p + 3)));
226101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a);
227101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 3);
228101d1e9bSNikolas Klauser     }
229101d1e9bSNikolas Klauser     {
230101d1e9bSNikolas Klauser       int a[] = {6, 7, 8, 6, 7, 8, 6, 7, 8};
231101d1e9bSNikolas Klauser       int p[] = {6, 7, 8};
232101d1e9bSNikolas Klauser       auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 9)));
233101d1e9bSNikolas Klauser       auto range2 = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 3)));
234101d1e9bSNikolas Klauser       auto ret = std::ranges::search(range1, range2);
235101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a);
236101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 3);
237101d1e9bSNikolas Klauser     }
238101d1e9bSNikolas Klauser   }
239101d1e9bSNikolas Klauser 
240101d1e9bSNikolas Klauser   { // check that the predicate is used
241101d1e9bSNikolas Klauser     {
242101d1e9bSNikolas Klauser       int a[] = {1, 2, 8, 1, 5, 6};
243101d1e9bSNikolas Klauser       int p[] = {7, 0, 4};
244101d1e9bSNikolas Klauser       auto ret = std::ranges::search(Iter1(a), Sent1(Iter1(a + 6)),
245101d1e9bSNikolas Klauser                                      Iter2(p), Sent2(Iter2(p + 3)),
246101d1e9bSNikolas Klauser                                      [](int l, int r) { return l > r; });
247101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a + 2);
248101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 5);
249101d1e9bSNikolas Klauser     }
250101d1e9bSNikolas Klauser     {
251101d1e9bSNikolas Klauser       int a[] = {1, 2, 8, 1, 5, 6};
252101d1e9bSNikolas Klauser       int p[] = {7, 0, 4};
253101d1e9bSNikolas Klauser       auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6)));
254101d1e9bSNikolas Klauser       auto range2 = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 3)));
255101d1e9bSNikolas Klauser       auto ret = std::ranges::search(range1, range2, [](int l, int r) { return l > r; });
256101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a + 2);
257101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 5);
258101d1e9bSNikolas Klauser     }
259101d1e9bSNikolas Klauser   }
260101d1e9bSNikolas Klauser 
261101d1e9bSNikolas Klauser   { // check that the projections are used
262101d1e9bSNikolas Klauser     {
263101d1e9bSNikolas Klauser       int a[] = {1, 3, 5, 1, 5, 6};
264101d1e9bSNikolas Klauser       int p[] = {2, 3, 4};
265101d1e9bSNikolas Klauser       auto ret = std::ranges::search(Iter1(a), Sent1(Iter1(a + 6)),
266101d1e9bSNikolas Klauser                                      Iter2(p), Sent2(Iter2(p + 3)),
267101d1e9bSNikolas Klauser                                      {},
268101d1e9bSNikolas Klauser                                      [](int i) { return i + 3; },
269101d1e9bSNikolas Klauser                                      [](int i) { return i * 2; });
270101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a);
271101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 3);
272101d1e9bSNikolas Klauser     }
273101d1e9bSNikolas Klauser     {
274101d1e9bSNikolas Klauser       int a[] = {1, 3, 5, 1, 5, 6};
275101d1e9bSNikolas Klauser       int p[] = {2, 3, 4};
276101d1e9bSNikolas Klauser       auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 6)));
277101d1e9bSNikolas Klauser       auto range2 = std::ranges::subrange(Iter2(p), Sent2(Iter2(p + 3)));
278101d1e9bSNikolas Klauser       auto ret = std::ranges::search(range1,
279101d1e9bSNikolas Klauser                                      range2,
280101d1e9bSNikolas Klauser                                      {},
281101d1e9bSNikolas Klauser                                      [](int i) { return i + 3; },
282101d1e9bSNikolas Klauser                                      [](int i) { return i * 2; });
283101d1e9bSNikolas Klauser       assert(base(ret.begin()) == a);
284101d1e9bSNikolas Klauser       assert(base(ret.end()) == a + 3);
285101d1e9bSNikolas Klauser     }
286101d1e9bSNikolas Klauser   }
287101d1e9bSNikolas Klauser }
288101d1e9bSNikolas Klauser 
289101d1e9bSNikolas Klauser template <class Iter1, class Sent1 = Iter1>
test_iterators2()290101d1e9bSNikolas Klauser constexpr void test_iterators2() {
291101d1e9bSNikolas Klauser   test_iterators<Iter1, Sent1, forward_iterator<int*>>();
292101d1e9bSNikolas Klauser   test_iterators<Iter1, Sent1, forward_iterator<int*>, sized_sentinel<forward_iterator<int*>>>();
293101d1e9bSNikolas Klauser   test_iterators<Iter1, Sent1, bidirectional_iterator<int*>>();
294101d1e9bSNikolas Klauser   test_iterators<Iter1, Sent1, bidirectional_iterator<int*>, sized_sentinel<bidirectional_iterator<int*>>>();
295101d1e9bSNikolas Klauser   test_iterators<Iter1, Sent1, random_access_iterator<int*>>();
296101d1e9bSNikolas Klauser   test_iterators<Iter1, Sent1, random_access_iterator<int*>, sized_sentinel<random_access_iterator<int*>>>();
297101d1e9bSNikolas Klauser   test_iterators<Iter1, Sent1, contiguous_iterator<int*>>();
298101d1e9bSNikolas Klauser   test_iterators<Iter1, Sent1, contiguous_iterator<int*>, sized_sentinel<contiguous_iterator<int*>>>();
299101d1e9bSNikolas Klauser   test_iterators<Iter1, Sent1, int*>();
300101d1e9bSNikolas Klauser }
301101d1e9bSNikolas Klauser 
test()302101d1e9bSNikolas Klauser constexpr bool test() {
303101d1e9bSNikolas Klauser   test_iterators2<forward_iterator<int*>>();
304101d1e9bSNikolas Klauser   test_iterators2<forward_iterator<int*>, sized_sentinel<forward_iterator<int*>>>();
305101d1e9bSNikolas Klauser   test_iterators2<bidirectional_iterator<int*>>();
306101d1e9bSNikolas Klauser   test_iterators2<bidirectional_iterator<int*>, sized_sentinel<bidirectional_iterator<int*>>>();
307101d1e9bSNikolas Klauser   test_iterators2<random_access_iterator<int*>>();
308101d1e9bSNikolas Klauser   test_iterators2<random_access_iterator<int*>, sized_sentinel<random_access_iterator<int*>>>();
309101d1e9bSNikolas Klauser   test_iterators2<contiguous_iterator<int*>>();
310101d1e9bSNikolas Klauser   test_iterators2<contiguous_iterator<int*>, sized_sentinel<contiguous_iterator<int*>>>();
311101d1e9bSNikolas Klauser   test_iterators2<int*>();
312101d1e9bSNikolas Klauser 
313101d1e9bSNikolas Klauser   { // check that std::invoke is used
314101d1e9bSNikolas Klauser     struct S {
315101d1e9bSNikolas Klauser       int i;
316101d1e9bSNikolas Klauser 
317101d1e9bSNikolas Klauser       constexpr S identity() {
318101d1e9bSNikolas Klauser         return *this;
319101d1e9bSNikolas Klauser       }
320101d1e9bSNikolas Klauser 
321101d1e9bSNikolas Klauser       constexpr bool compare(const S& s) {
322101d1e9bSNikolas Klauser         return i == s.i;
323101d1e9bSNikolas Klauser       }
324101d1e9bSNikolas Klauser     };
325101d1e9bSNikolas Klauser     {
326101d1e9bSNikolas Klauser       S a[] = {{1}, {2}, {3}, {4}};
327101d1e9bSNikolas Klauser       S p[] = {{2}, {3}};
328101d1e9bSNikolas Klauser       auto ret = std::ranges::search(a, a + 4, p, p + 2, &S::compare, &S::identity, &S::identity);
329101d1e9bSNikolas Klauser       assert(ret.begin() == a + 1);
330101d1e9bSNikolas Klauser       assert(ret.end() == a + 3);
331101d1e9bSNikolas Klauser     }
332101d1e9bSNikolas Klauser     {
333101d1e9bSNikolas Klauser       S a[] = {{1}, {2}, {3}, {4}};
334101d1e9bSNikolas Klauser       S p[] = {{2}, {3}};
335101d1e9bSNikolas Klauser       auto ret = std::ranges::search(a, p, &S::compare, &S::identity, &S::identity);
336101d1e9bSNikolas Klauser       assert(ret.begin() == a + 1);
337101d1e9bSNikolas Klauser       assert(ret.end() == a + 3);
338101d1e9bSNikolas Klauser     }
339101d1e9bSNikolas Klauser   }
340101d1e9bSNikolas Klauser 
341101d1e9bSNikolas Klauser   { // check that std::ranges::dangling is returned
342101d1e9bSNikolas Klauser     [[maybe_unused]] std::same_as<std::ranges::dangling> decltype(auto) ret =
343101d1e9bSNikolas Klauser         std::ranges::search(std::array {1, 2, 3, 4}, std::array {2, 3});
344101d1e9bSNikolas Klauser   }
345101d1e9bSNikolas Klauser 
346101d1e9bSNikolas Klauser   return true;
347101d1e9bSNikolas Klauser }
348101d1e9bSNikolas Klauser 
main(int,char **)349101d1e9bSNikolas Klauser int main(int, char**) {
350101d1e9bSNikolas Klauser   test();
351101d1e9bSNikolas Klauser   static_assert(test());
352101d1e9bSNikolas Klauser 
353101d1e9bSNikolas Klauser   return 0;
354101d1e9bSNikolas Klauser }
355