1*569d6630SNikolas Klauser //===----------------------------------------------------------------------===//
2*569d6630SNikolas Klauser //
3*569d6630SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*569d6630SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information.
5*569d6630SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*569d6630SNikolas Klauser //
7*569d6630SNikolas Klauser //===----------------------------------------------------------------------===//
8*569d6630SNikolas Klauser
9*569d6630SNikolas Klauser // <algorithm>
10*569d6630SNikolas Klauser
11*569d6630SNikolas Klauser // UNSUPPORTED: c++03, c++11, c++14, c++17
12*569d6630SNikolas Klauser // UNSUPPORTED: libcpp-has-no-incomplete-ranges
13*569d6630SNikolas Klauser
14*569d6630SNikolas Klauser // template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2,
15*569d6630SNikolas Klauser // class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
16*569d6630SNikolas Klauser // requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
17*569d6630SNikolas Klauser // constexpr bool ranges::equal(I1 first1, S1 last1, I2 first2, S2 last2,
18*569d6630SNikolas Klauser // Pred pred = {},
19*569d6630SNikolas Klauser // Proj1 proj1 = {}, Proj2 proj2 = {});
20*569d6630SNikolas Klauser // template<input_range R1, input_range R2, class Pred = ranges::equal_to,
21*569d6630SNikolas Klauser // class Proj1 = identity, class Proj2 = identity>
22*569d6630SNikolas Klauser // requires indirectly_comparable<iterator_t<R1>, iterator_t<R2>, Pred, Proj1, Proj2>
23*569d6630SNikolas Klauser // constexpr bool ranges::equal(R1&& r1, R2&& r2, Pred pred = {},
24*569d6630SNikolas Klauser // Proj1 proj1 = {}, Proj2 proj2 = {});
25*569d6630SNikolas Klauser
26*569d6630SNikolas Klauser #include <algorithm>
27*569d6630SNikolas Klauser #include <cassert>
28*569d6630SNikolas Klauser #include <concepts>
29*569d6630SNikolas Klauser #include <functional>
30*569d6630SNikolas Klauser #include <ranges>
31*569d6630SNikolas Klauser
32*569d6630SNikolas Klauser #include "almost_satisfies_types.h"
33*569d6630SNikolas Klauser #include "test_iterators.h"
34*569d6630SNikolas Klauser
35*569d6630SNikolas Klauser template <class Iter1, class Sent1 = sentinel_wrapper<Iter1>,
36*569d6630SNikolas Klauser class Iter2 = Iter1, class Sent2 = sentinel_wrapper<Iter2>>
37*569d6630SNikolas Klauser concept HasEqualIt = requires (Iter1 first1, Sent1 last1, Iter2 first2, Sent2 last2) {
38*569d6630SNikolas Klauser std::ranges::equal(first1, last1, first2, last2);
39*569d6630SNikolas Klauser };
40*569d6630SNikolas Klauser
41*569d6630SNikolas Klauser static_assert(HasEqualIt<int*>);
42*569d6630SNikolas Klauser static_assert(!HasEqualIt<InputIteratorNotDerivedFrom>);
43*569d6630SNikolas Klauser static_assert(!HasEqualIt<InputIteratorNotIndirectlyReadable>);
44*569d6630SNikolas Klauser static_assert(!HasEqualIt<InputIteratorNotInputOrOutputIterator>);
45*569d6630SNikolas Klauser static_assert(!HasEqualIt<int*, int*, InputIteratorNotDerivedFrom>);
46*569d6630SNikolas Klauser static_assert(!HasEqualIt<int*, int*, InputIteratorNotIndirectlyReadable>);
47*569d6630SNikolas Klauser static_assert(!HasEqualIt<int*, int*, InputIteratorNotInputOrOutputIterator>);
48*569d6630SNikolas Klauser static_assert(!HasEqualIt<int*, SentinelForNotSemiregular>);
49*569d6630SNikolas Klauser static_assert(!HasEqualIt<int*, SentinelForNotWeaklyEqualityComparableWith>);
50*569d6630SNikolas Klauser static_assert(!HasEqualIt<int*, int*, int*, SentinelForNotSemiregular>);
51*569d6630SNikolas Klauser static_assert(!HasEqualIt<int*, int*, int*, SentinelForNotWeaklyEqualityComparableWith>);
52*569d6630SNikolas Klauser static_assert(!HasEqualIt<int*, int*, int**>);
53*569d6630SNikolas Klauser
54*569d6630SNikolas Klauser template <class Range1, class Range2>
55*569d6630SNikolas Klauser concept HasEqualR = requires (Range1 range1, Range2 range2) {
56*569d6630SNikolas Klauser std::ranges::equal(range1, range2);
57*569d6630SNikolas Klauser };
58*569d6630SNikolas Klauser
59*569d6630SNikolas Klauser static_assert(HasEqualR<UncheckedRange<int*>, UncheckedRange<int*>>);
60*569d6630SNikolas Klauser static_assert(!HasEqualR<InputRangeNotDerivedFrom, UncheckedRange<int*>>);
61*569d6630SNikolas Klauser static_assert(!HasEqualR<InputRangeNotIndirectlyReadable, UncheckedRange<int*>>);
62*569d6630SNikolas Klauser static_assert(!HasEqualR<InputRangeNotInputOrOutputIterator, UncheckedRange<int*>>);
63*569d6630SNikolas Klauser static_assert(!HasEqualR<InputRangeNotSentinelSemiregular, UncheckedRange<int*>>);
64*569d6630SNikolas Klauser static_assert(!HasEqualR<InputRangeNotSentinelEqualityComparableWith, UncheckedRange<int*>>);
65*569d6630SNikolas Klauser static_assert(!HasEqualR<UncheckedRange<int*>, InputRangeNotDerivedFrom>);
66*569d6630SNikolas Klauser static_assert(!HasEqualR<UncheckedRange<int*>, InputRangeNotIndirectlyReadable>);
67*569d6630SNikolas Klauser static_assert(!HasEqualR<UncheckedRange<int*>, InputRangeNotInputOrOutputIterator>);
68*569d6630SNikolas Klauser static_assert(!HasEqualR<UncheckedRange<int*>, InputRangeNotSentinelSemiregular>);
69*569d6630SNikolas Klauser static_assert(!HasEqualR<UncheckedRange<int*>, InputRangeNotSentinelEqualityComparableWith>);
70*569d6630SNikolas Klauser static_assert(!HasEqualR<UncheckedRange<int*>, UncheckedRange<int**>>);
71*569d6630SNikolas Klauser
72*569d6630SNikolas Klauser template <class Iter1, class Sent1, class Iter2, class Sent2 = Iter2>
test_iterators()73*569d6630SNikolas Klauser constexpr void test_iterators() {
74*569d6630SNikolas Klauser { // simple test
75*569d6630SNikolas Klauser {
76*569d6630SNikolas Klauser int a[] = {1, 2, 3, 4};
77*569d6630SNikolas Klauser int b[] = {1, 2, 3, 4};
78*569d6630SNikolas Klauser std::same_as<bool> decltype(auto) ret = std::ranges::equal(Iter1(a), Sent1(Iter1(a + 4)),
79*569d6630SNikolas Klauser Iter2(b), Sent2(Iter2(b + 4)));
80*569d6630SNikolas Klauser assert(ret);
81*569d6630SNikolas Klauser }
82*569d6630SNikolas Klauser {
83*569d6630SNikolas Klauser int a[] = {1, 2, 3, 4};
84*569d6630SNikolas Klauser int b[] = {1, 2, 3, 4};
85*569d6630SNikolas Klauser auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 4)));
86*569d6630SNikolas Klauser auto range2 = std::ranges::subrange(Iter2(b), Sent2(Iter2(b + 4)));
87*569d6630SNikolas Klauser std::same_as<bool> decltype(auto) ret = std::ranges::equal(range1, range2);
88*569d6630SNikolas Klauser assert(ret);
89*569d6630SNikolas Klauser }
90*569d6630SNikolas Klauser }
91*569d6630SNikolas Klauser
92*569d6630SNikolas Klauser { // check that the predicate is used (return true)
93*569d6630SNikolas Klauser {
94*569d6630SNikolas Klauser int a[] = {1, 2, 3, 4};
95*569d6630SNikolas Klauser int b[] = {2, 3, 4, 5};
96*569d6630SNikolas Klauser auto ret = std::ranges::equal(Iter1(a), Sent1(Iter1(a + 4)), Iter2(b), Sent2(Iter2(b + 4)),
97*569d6630SNikolas Klauser [](int l, int r) { return l != r; });
98*569d6630SNikolas Klauser assert(ret);
99*569d6630SNikolas Klauser }
100*569d6630SNikolas Klauser {
101*569d6630SNikolas Klauser int a[] = {1, 2, 3, 4};
102*569d6630SNikolas Klauser int b[] = {2, 3, 4, 5};
103*569d6630SNikolas Klauser auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 4)));
104*569d6630SNikolas Klauser auto range2 = std::ranges::subrange(Iter2(b), Sent2(Iter2(b + 4)));
105*569d6630SNikolas Klauser auto ret = std::ranges::equal(range1, range2, [](int l, int r) { return l != r; });
106*569d6630SNikolas Klauser assert(ret);
107*569d6630SNikolas Klauser }
108*569d6630SNikolas Klauser }
109*569d6630SNikolas Klauser
110*569d6630SNikolas Klauser { // check that the predicate is used (return false)
111*569d6630SNikolas Klauser {
112*569d6630SNikolas Klauser int a[] = {1, 2, 3, 4};
113*569d6630SNikolas Klauser int b[] = {2, 3, 3, 5};
114*569d6630SNikolas Klauser auto ret = std::ranges::equal(Iter1(a), Sent1(Iter1(a + 4)), Iter2(b), Sent2(Iter2(b + 4)),
115*569d6630SNikolas Klauser [](int l, int r) { return l != r; });
116*569d6630SNikolas Klauser assert(!ret);
117*569d6630SNikolas Klauser }
118*569d6630SNikolas Klauser {
119*569d6630SNikolas Klauser int a[] = {1, 2, 3, 4};
120*569d6630SNikolas Klauser int b[] = {2, 3, 3, 5};
121*569d6630SNikolas Klauser auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 4)));
122*569d6630SNikolas Klauser auto range2 = std::ranges::subrange(Iter2(b), Sent2(Iter2(b + 4)));
123*569d6630SNikolas Klauser auto ret = std::ranges::equal(range1, range2, [](int l, int r) { return l != r; });
124*569d6630SNikolas Klauser assert(!ret);
125*569d6630SNikolas Klauser }
126*569d6630SNikolas Klauser }
127*569d6630SNikolas Klauser
128*569d6630SNikolas Klauser { // check that the projections are used
129*569d6630SNikolas Klauser {
130*569d6630SNikolas Klauser int a[] = {1, 2, 3, 4, 5};
131*569d6630SNikolas Klauser int b[] = {6, 10, 14, 18, 22};
132*569d6630SNikolas Klauser auto ret = std::ranges::equal(Iter1(a), Sent1(Iter1(a + 5)),
133*569d6630SNikolas Klauser Iter2(b), Sent2(Iter2(b + 5)),
134*569d6630SNikolas Klauser {},
135*569d6630SNikolas Klauser [](int i) { return i * 4; },
136*569d6630SNikolas Klauser [](int i) { return i - 2; });
137*569d6630SNikolas Klauser assert(ret);
138*569d6630SNikolas Klauser }
139*569d6630SNikolas Klauser {
140*569d6630SNikolas Klauser int a[] = {1, 2, 3, 4, 5};
141*569d6630SNikolas Klauser int b[] = {6, 10, 14, 18, 22};
142*569d6630SNikolas Klauser auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 5)));
143*569d6630SNikolas Klauser auto range2 = std::ranges::subrange(Iter2(b), Sent2(Iter2(b + 5)));
144*569d6630SNikolas Klauser auto ret = std::ranges::equal(range1,
145*569d6630SNikolas Klauser range2,
146*569d6630SNikolas Klauser {},
147*569d6630SNikolas Klauser [](int i) { return i * 4; },
148*569d6630SNikolas Klauser [](int i) { return i - 2; });
149*569d6630SNikolas Klauser assert(ret);
150*569d6630SNikolas Klauser }
151*569d6630SNikolas Klauser }
152*569d6630SNikolas Klauser
153*569d6630SNikolas Klauser { // check that different sized ranges work
154*569d6630SNikolas Klauser {
155*569d6630SNikolas Klauser int a[] = {4, 3, 2, 1};
156*569d6630SNikolas Klauser int b[] = {4, 3, 2, 1, 5, 6, 7};
157*569d6630SNikolas Klauser auto ret = std::ranges::equal(Iter1(a), Sent1(Iter1(a + 4)), Iter2(b), Sent2(Iter2(b + 7)));
158*569d6630SNikolas Klauser assert(!ret);
159*569d6630SNikolas Klauser }
160*569d6630SNikolas Klauser {
161*569d6630SNikolas Klauser int a[] = {4, 3, 2, 1};
162*569d6630SNikolas Klauser int b[] = {4, 3, 2, 1, 5, 6, 7};
163*569d6630SNikolas Klauser auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 4)));
164*569d6630SNikolas Klauser auto range2 = std::ranges::subrange(Iter2(b), Sent2(Iter2(b + 7)));
165*569d6630SNikolas Klauser auto ret = std::ranges::equal(range1, range2);
166*569d6630SNikolas Klauser assert(!ret);
167*569d6630SNikolas Klauser }
168*569d6630SNikolas Klauser }
169*569d6630SNikolas Klauser
170*569d6630SNikolas Klauser { // check that two ranges with the same size but different values are different
171*569d6630SNikolas Klauser {
172*569d6630SNikolas Klauser int a[] = {4, 6, 34, 76, 5};
173*569d6630SNikolas Klauser int b[] = {4, 6, 34, 67, 5};
174*569d6630SNikolas Klauser auto ret = std::ranges::equal(Iter1(a), Sent1(Iter1(a + 5)), Iter2(b), Sent2(Iter2(b + 5)));
175*569d6630SNikolas Klauser assert(!ret);
176*569d6630SNikolas Klauser }
177*569d6630SNikolas Klauser {
178*569d6630SNikolas Klauser int a[] = {4, 6, 34, 76, 5};
179*569d6630SNikolas Klauser int b[] = {4, 6, 34, 67, 5};
180*569d6630SNikolas Klauser auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 5)));
181*569d6630SNikolas Klauser auto range2 = std::ranges::subrange(Iter2(b), Sent2(Iter2(b + 5)));
182*569d6630SNikolas Klauser auto ret = std::ranges::equal(range1, range2);
183*569d6630SNikolas Klauser assert(!ret);
184*569d6630SNikolas Klauser }
185*569d6630SNikolas Klauser }
186*569d6630SNikolas Klauser
187*569d6630SNikolas Klauser { // check that two empty ranges work
188*569d6630SNikolas Klauser {
189*569d6630SNikolas Klauser int a[] = {};
190*569d6630SNikolas Klauser int b[] = {};
191*569d6630SNikolas Klauser auto ret = std::ranges::equal(Iter1(a), Sent1(Iter1(a)), Iter2(b), Sent2(Iter2(b)));
192*569d6630SNikolas Klauser assert(ret);
193*569d6630SNikolas Klauser }
194*569d6630SNikolas Klauser {
195*569d6630SNikolas Klauser int a[] = {};
196*569d6630SNikolas Klauser int b[] = {};
197*569d6630SNikolas Klauser auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a)));
198*569d6630SNikolas Klauser auto range2 = std::ranges::subrange(Iter2(b), Sent2(Iter2(b)));
199*569d6630SNikolas Klauser auto ret = std::ranges::equal(range1, range2);
200*569d6630SNikolas Klauser assert(ret);
201*569d6630SNikolas Klauser }
202*569d6630SNikolas Klauser }
203*569d6630SNikolas Klauser
204*569d6630SNikolas Klauser { // check that it works with the first range empty
205*569d6630SNikolas Klauser {
206*569d6630SNikolas Klauser int a[] = {};
207*569d6630SNikolas Klauser int b[] = {1, 2};
208*569d6630SNikolas Klauser auto ret = std::ranges::equal(Iter1(a), Sent1(Iter1(a)), Iter2(b), Sent2(Iter2(b + 2)));
209*569d6630SNikolas Klauser assert(!ret);
210*569d6630SNikolas Klauser }
211*569d6630SNikolas Klauser {
212*569d6630SNikolas Klauser int a[] = {};
213*569d6630SNikolas Klauser int b[] = {1, 2};
214*569d6630SNikolas Klauser auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a)));
215*569d6630SNikolas Klauser auto range2 = std::ranges::subrange(Iter2(b), Sent2(Iter2(b + 2)));
216*569d6630SNikolas Klauser auto ret = std::ranges::equal(range1, range2);
217*569d6630SNikolas Klauser assert(!ret);
218*569d6630SNikolas Klauser }
219*569d6630SNikolas Klauser }
220*569d6630SNikolas Klauser
221*569d6630SNikolas Klauser { // check that it works with the second range empty
222*569d6630SNikolas Klauser {
223*569d6630SNikolas Klauser int a[] = {1, 2};
224*569d6630SNikolas Klauser int b[] = {};
225*569d6630SNikolas Klauser auto ret = std::ranges::equal(Iter1(a), Sent1(Iter1(a + 2)), Iter2(b), Sent2(Iter2(b)));
226*569d6630SNikolas Klauser assert(!ret);
227*569d6630SNikolas Klauser }
228*569d6630SNikolas Klauser {
229*569d6630SNikolas Klauser int a[] = {1, 2};
230*569d6630SNikolas Klauser int b[] = {};
231*569d6630SNikolas Klauser auto range1 = std::ranges::subrange(Iter1(a), Sent1(Iter1(a + 2)));
232*569d6630SNikolas Klauser auto range2 = std::ranges::subrange(Iter2(b), Sent2(Iter2(b)));
233*569d6630SNikolas Klauser auto ret = std::ranges::equal(range1, range2);
234*569d6630SNikolas Klauser assert(!ret);
235*569d6630SNikolas Klauser }
236*569d6630SNikolas Klauser }
237*569d6630SNikolas Klauser }
238*569d6630SNikolas Klauser
239*569d6630SNikolas Klauser template<class Iter1, class Sent1 = Iter1>
test_iterators2()240*569d6630SNikolas Klauser constexpr void test_iterators2() {
241*569d6630SNikolas Klauser test_iterators<Iter1, Sent1, cpp17_input_iterator<int*>, sentinel_wrapper<cpp17_input_iterator<int*>>>();
242*569d6630SNikolas Klauser test_iterators<Iter1, Sent1, cpp20_input_iterator<int*>, sentinel_wrapper<cpp20_input_iterator<int*>>>();
243*569d6630SNikolas Klauser test_iterators<Iter1, Sent1, forward_iterator<int*>>();
244*569d6630SNikolas Klauser test_iterators<Iter1, Sent1, bidirectional_iterator<int*>>();
245*569d6630SNikolas Klauser test_iterators<Iter1, Sent1, random_access_iterator<int*>>();
246*569d6630SNikolas Klauser test_iterators<Iter1, Sent1, contiguous_iterator<int*>>();
247*569d6630SNikolas Klauser test_iterators<Iter1, Sent1, int*>();
248*569d6630SNikolas Klauser test_iterators<Iter1, Sent1, const int*>();
249*569d6630SNikolas Klauser }
250*569d6630SNikolas Klauser
test()251*569d6630SNikolas Klauser constexpr bool test() {
252*569d6630SNikolas Klauser test_iterators2<cpp17_input_iterator<int*>, sentinel_wrapper<cpp17_input_iterator<int*>>>();
253*569d6630SNikolas Klauser test_iterators2<cpp20_input_iterator<int*>, sentinel_wrapper<cpp20_input_iterator<int*>>>();
254*569d6630SNikolas Klauser test_iterators2<forward_iterator<int*>>();
255*569d6630SNikolas Klauser test_iterators2<bidirectional_iterator<int*>>();
256*569d6630SNikolas Klauser test_iterators2<random_access_iterator<int*>>();
257*569d6630SNikolas Klauser test_iterators2<contiguous_iterator<int*>>();
258*569d6630SNikolas Klauser test_iterators2<int*>();
259*569d6630SNikolas Klauser test_iterators2<const int*>();
260*569d6630SNikolas Klauser
261*569d6630SNikolas Klauser { // check that std::invoke is used
262*569d6630SNikolas Klauser struct S {
263*569d6630SNikolas Klauser constexpr S(int i_) : i(i_) {}
264*569d6630SNikolas Klauser constexpr bool equal(int o) { return i == o; }
265*569d6630SNikolas Klauser constexpr S& identity() { return *this; }
266*569d6630SNikolas Klauser int i;
267*569d6630SNikolas Klauser };
268*569d6630SNikolas Klauser {
269*569d6630SNikolas Klauser S a[] = {7, 8, 9};
270*569d6630SNikolas Klauser S b[] = {7, 8, 9};
271*569d6630SNikolas Klauser auto ret = std::ranges::equal(a, a + 3, b, b + 3, &S::equal, &S::identity, &S::i);
272*569d6630SNikolas Klauser assert(ret);
273*569d6630SNikolas Klauser }
274*569d6630SNikolas Klauser {
275*569d6630SNikolas Klauser S a[] = {7, 8, 9};
276*569d6630SNikolas Klauser S b[] = {7, 8, 9};
277*569d6630SNikolas Klauser auto ret = std::ranges::equal(a, b, &S::equal, &S::identity, &S::i);
278*569d6630SNikolas Klauser assert(ret);
279*569d6630SNikolas Klauser }
280*569d6630SNikolas Klauser }
281*569d6630SNikolas Klauser
282*569d6630SNikolas Klauser { // check that the complexity requirements are met
283*569d6630SNikolas Klauser { // different size
284*569d6630SNikolas Klauser {
285*569d6630SNikolas Klauser int a[] = {1, 2, 3};
286*569d6630SNikolas Klauser int b[] = {1, 2, 3, 4};
287*569d6630SNikolas Klauser int predCount = 0;
288*569d6630SNikolas Klauser int projCount = 0;
289*569d6630SNikolas Klauser auto pred = [&](int l, int r) { ++predCount; return l == r; };
290*569d6630SNikolas Klauser auto proj = [&](int i) { ++projCount; return i; };
291*569d6630SNikolas Klauser auto ret = std::ranges::equal(a, a + 3, b, b + 4, pred, proj, proj);
292*569d6630SNikolas Klauser assert(!ret);
293*569d6630SNikolas Klauser assert(predCount == 0);
294*569d6630SNikolas Klauser assert(projCount == 0);
295*569d6630SNikolas Klauser }
296*569d6630SNikolas Klauser {
297*569d6630SNikolas Klauser int a[] = {1, 2, 3};
298*569d6630SNikolas Klauser int b[] = {1, 2, 3, 4};
299*569d6630SNikolas Klauser int predCount = 0;
300*569d6630SNikolas Klauser int projCount = 0;
301*569d6630SNikolas Klauser auto pred = [&](int l, int r) { ++predCount; return l == r; };
302*569d6630SNikolas Klauser auto proj = [&](int i) { ++projCount; return i; };
303*569d6630SNikolas Klauser auto ret = std::ranges::equal(a, b, pred, proj, proj);
304*569d6630SNikolas Klauser assert(!ret);
305*569d6630SNikolas Klauser assert(predCount == 0);
306*569d6630SNikolas Klauser assert(projCount == 0);
307*569d6630SNikolas Klauser }
308*569d6630SNikolas Klauser }
309*569d6630SNikolas Klauser
310*569d6630SNikolas Klauser { // not a sized sentinel
311*569d6630SNikolas Klauser {
312*569d6630SNikolas Klauser int a[] = {1, 2, 3};
313*569d6630SNikolas Klauser int b[] = {1, 2, 3, 4};
314*569d6630SNikolas Klauser int predCount = 0;
315*569d6630SNikolas Klauser int projCount = 0;
316*569d6630SNikolas Klauser auto pred = [&](int l, int r) { ++predCount; return l == r; };
317*569d6630SNikolas Klauser auto proj = [&](int i) { ++projCount; return i; };
318*569d6630SNikolas Klauser auto ret = std::ranges::equal(a, sentinel_wrapper(a + 3), b, sentinel_wrapper(b + 4), pred, proj, proj);
319*569d6630SNikolas Klauser assert(!ret);
320*569d6630SNikolas Klauser assert(predCount <= 4);
321*569d6630SNikolas Klauser assert(projCount <= 7);
322*569d6630SNikolas Klauser }
323*569d6630SNikolas Klauser {
324*569d6630SNikolas Klauser int a[] = {1, 2, 3};
325*569d6630SNikolas Klauser int b[] = {1, 2, 3, 4};
326*569d6630SNikolas Klauser int predCount = 0;
327*569d6630SNikolas Klauser int projCount = 0;
328*569d6630SNikolas Klauser auto pred = [&](int l, int r) { ++predCount; return l == r; };
329*569d6630SNikolas Klauser auto proj = [&](int i) { ++projCount; return i; };
330*569d6630SNikolas Klauser auto range1 = std::ranges::subrange(a, sentinel_wrapper(a + 3));
331*569d6630SNikolas Klauser auto range2 = std::ranges::subrange(b, sentinel_wrapper(b + 4));
332*569d6630SNikolas Klauser auto ret = std::ranges::equal(range1, range2, pred, proj, proj);
333*569d6630SNikolas Klauser assert(!ret);
334*569d6630SNikolas Klauser assert(predCount <= 4);
335*569d6630SNikolas Klauser assert(projCount <= 7);
336*569d6630SNikolas Klauser }
337*569d6630SNikolas Klauser }
338*569d6630SNikolas Klauser
339*569d6630SNikolas Klauser { // same size
340*569d6630SNikolas Klauser {
341*569d6630SNikolas Klauser int a[] = {1, 2, 3};
342*569d6630SNikolas Klauser int b[] = {1, 2, 3};
343*569d6630SNikolas Klauser int predCount = 0;
344*569d6630SNikolas Klauser int projCount = 0;
345*569d6630SNikolas Klauser auto pred = [&](int l, int r) { ++predCount; return l == r; };
346*569d6630SNikolas Klauser auto proj = [&](int i) { ++projCount; return i; };
347*569d6630SNikolas Klauser auto ret = std::ranges::equal(a, a + 3, b, b + 3, pred, proj, proj);
348*569d6630SNikolas Klauser assert(ret);
349*569d6630SNikolas Klauser assert(predCount == 3);
350*569d6630SNikolas Klauser assert(projCount == 6);
351*569d6630SNikolas Klauser }
352*569d6630SNikolas Klauser {
353*569d6630SNikolas Klauser int a[] = {1, 2, 3};
354*569d6630SNikolas Klauser int b[] = {1, 2, 3};
355*569d6630SNikolas Klauser int predCount = 0;
356*569d6630SNikolas Klauser int projCount = 0;
357*569d6630SNikolas Klauser auto pred = [&](int l, int r) { ++predCount; return l == r; };
358*569d6630SNikolas Klauser auto proj = [&](int i) { ++projCount; return i; };
359*569d6630SNikolas Klauser auto ret = std::ranges::equal(a, b, pred, proj, proj);
360*569d6630SNikolas Klauser assert(ret);
361*569d6630SNikolas Klauser assert(predCount == 3);
362*569d6630SNikolas Klauser assert(projCount == 6);
363*569d6630SNikolas Klauser }
364*569d6630SNikolas Klauser }
365*569d6630SNikolas Klauser }
366*569d6630SNikolas Klauser
367*569d6630SNikolas Klauser return true;
368*569d6630SNikolas Klauser }
369*569d6630SNikolas Klauser
main(int,char **)370*569d6630SNikolas Klauser int main(int, char**) {
371*569d6630SNikolas Klauser test();
372*569d6630SNikolas Klauser static_assert(test());
373*569d6630SNikolas Klauser
374*569d6630SNikolas Klauser return 0;
375*569d6630SNikolas Klauser }
376