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