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 // UNSUPPORTED: c++03, c++11, c++14, c++17
10 // UNSUPPORTED: libcpp-has-no-incomplete-ranges
11
12 // template<class I, sentinel_for<I> S>
13 // requires (!sized_sentinel_for<S, I>)
14 // constexpr iter_difference_t<I> ranges::distance(I first, S last);
15 //
16 // template<class I, sized_sentinel_for<decay_t<I>> S>
17 // constexpr iter_difference_t<I> ranges::distance(I&& first, S last); // TODO: update when LWG3664 is resolved
18
19 #include <iterator>
20 #include <cassert>
21
22 #include "test_iterators.h"
23 #include "test_macros.h"
24
25 template<class It, class Sent>
test_unsized()26 constexpr void test_unsized() {
27 static_assert(std::sentinel_for<Sent, It> && !std::sized_sentinel_for<Sent, It>);
28 int a[3] = {1,2,3};
29 {
30 It first = It(a);
31 auto last = Sent(It(a));
32 assert(std::ranges::distance(first, last) == 0);
33 assert(std::ranges::distance(It(a), last) == 0);
34 assert(std::ranges::distance(first, Sent(It(a))) == 0);
35 assert(std::ranges::distance(It(a), Sent(It(a))) == 0);
36 ASSERT_SAME_TYPE(decltype(std::ranges::distance(It(a), Sent(It(a)))), std::iter_difference_t<It>);
37 }
38 {
39 It first = It(a);
40 auto last = Sent(It(a + 3));
41 assert(std::ranges::distance(first, last) == 3);
42
43 // Test all const/ref-qualifications of both operands.
44 assert(std::ranges::distance(static_cast<It&>(first), static_cast<Sent&>(last)) == 3);
45 assert(std::ranges::distance(static_cast<It&>(first), static_cast<Sent&&>(last)) == 3);
46 assert(std::ranges::distance(static_cast<It&>(first), static_cast<const Sent&>(last)) == 3);
47 assert(std::ranges::distance(static_cast<It&>(first), static_cast<const Sent&&>(last)) == 3);
48 assert(std::ranges::distance(static_cast<It&&>(first), static_cast<Sent&>(last)) == 3);
49 assert(std::ranges::distance(static_cast<It&&>(first), static_cast<Sent&&>(last)) == 3);
50 assert(std::ranges::distance(static_cast<It&&>(first), static_cast<const Sent&>(last)) == 3);
51 assert(std::ranges::distance(static_cast<It&&>(first), static_cast<const Sent&&>(last)) == 3);
52 assert(std::ranges::distance(static_cast<const It&>(first), static_cast<Sent&>(last)) == 3);
53 assert(std::ranges::distance(static_cast<const It&>(first), static_cast<Sent&&>(last)) == 3);
54 assert(std::ranges::distance(static_cast<const It&>(first), static_cast<const Sent&>(last)) == 3);
55 assert(std::ranges::distance(static_cast<const It&>(first), static_cast<const Sent&&>(last)) == 3);
56 assert(std::ranges::distance(static_cast<const It&&>(first), static_cast<Sent&>(last)) == 3);
57 assert(std::ranges::distance(static_cast<const It&&>(first), static_cast<Sent&&>(last)) == 3);
58 assert(std::ranges::distance(static_cast<const It&&>(first), static_cast<const Sent&>(last)) == 3);
59 assert(std::ranges::distance(static_cast<const It&&>(first), static_cast<const Sent&&>(last)) == 3);
60 }
61 }
62
63 template<class It, class Sent>
test_sized()64 constexpr void test_sized() {
65 static_assert(std::sized_sentinel_for<Sent, It>);
66 int a[] = {1,2,3};
67 {
68 It first = It(a + 3);
69 auto last = Sent(It(a));
70 assert(std::ranges::distance(first, last) == -3);
71
72 // Test all const/ref-qualifications of both operands.
73 assert(std::ranges::distance(static_cast<It&>(first), static_cast<Sent&>(last)) == -3);
74 assert(std::ranges::distance(static_cast<It&>(first), static_cast<Sent&&>(last)) == -3);
75 assert(std::ranges::distance(static_cast<It&>(first), static_cast<const Sent&>(last)) == -3);
76 assert(std::ranges::distance(static_cast<It&>(first), static_cast<const Sent&&>(last)) == -3);
77 assert(std::ranges::distance(static_cast<It&&>(first), static_cast<Sent&>(last)) == -3);
78 assert(std::ranges::distance(static_cast<It&&>(first), static_cast<Sent&&>(last)) == -3);
79 assert(std::ranges::distance(static_cast<It&&>(first), static_cast<const Sent&>(last)) == -3);
80 assert(std::ranges::distance(static_cast<It&&>(first), static_cast<const Sent&&>(last)) == -3);
81 assert(std::ranges::distance(static_cast<const It&>(first), static_cast<Sent&>(last)) == -3);
82 assert(std::ranges::distance(static_cast<const It&>(first), static_cast<Sent&&>(last)) == -3);
83 assert(std::ranges::distance(static_cast<const It&>(first), static_cast<const Sent&>(last)) == -3);
84 assert(std::ranges::distance(static_cast<const It&>(first), static_cast<const Sent&&>(last)) == -3);
85 assert(std::ranges::distance(static_cast<const It&&>(first), static_cast<Sent&>(last)) == -3);
86 assert(std::ranges::distance(static_cast<const It&&>(first), static_cast<Sent&&>(last)) == -3);
87 assert(std::ranges::distance(static_cast<const It&&>(first), static_cast<const Sent&>(last)) == -3);
88 assert(std::ranges::distance(static_cast<const It&&>(first), static_cast<const Sent&&>(last)) == -3);
89 }
90 {
91 It first = It(a);
92 auto last = Sent(It(a));
93 assert(std::ranges::distance(first, last) == 0);
94 assert(std::ranges::distance(It(a), last) == 0);
95 assert(std::ranges::distance(first, Sent(It(a))) == 0);
96 assert(std::ranges::distance(It(a), Sent(It(a))) == 0);
97 ASSERT_SAME_TYPE(decltype(std::ranges::distance(It(a), Sent(It(a)))), std::iter_difference_t<It>);
98 }
99 {
100 It first = It(a);
101 auto last = Sent(It(a + 3));
102 assert(std::ranges::distance(first, last) == 3);
103 assert(std::ranges::distance(It(a), last) == 3);
104 assert(std::ranges::distance(first, Sent(It(a + 3))) == 3);
105 assert(std::ranges::distance(It(a), Sent(It(a + 3))) == 3);
106 }
107 }
108
109 struct StrideCounter {
110 int *it_;
111 int *inc_;
112 using value_type = int;
113 using difference_type = int;
114 explicit StrideCounter();
StrideCounterStrideCounter115 constexpr explicit StrideCounter(int *it, int *inc) : it_(it), inc_(inc) {}
operator ++StrideCounter116 constexpr auto& operator++() { ++it_; *inc_ += 1; return *this; }
117 StrideCounter operator++(int);
118 int& operator*() const;
119 bool operator==(StrideCounter) const;
120 };
121 static_assert(std::forward_iterator<StrideCounter>);
122 static_assert(!std::sized_sentinel_for<StrideCounter, StrideCounter>);
123
124 struct SizedStrideCounter {
125 int *it_;
126 int *minus_;
127 using value_type = int;
128 explicit SizedStrideCounter();
SizedStrideCounterSizedStrideCounter129 constexpr explicit SizedStrideCounter(int *it, int *minus) : it_(it), minus_(minus) {}
130 SizedStrideCounter& operator++();
131 SizedStrideCounter operator++(int);
132 int& operator*() const;
133 bool operator==(SizedStrideCounter) const;
operator -SizedStrideCounter134 constexpr int operator-(SizedStrideCounter rhs) const { *minus_ += 1; return it_ - rhs.it_; }
135 };
136 static_assert(std::forward_iterator<SizedStrideCounter>);
137 static_assert(std::sized_sentinel_for<SizedStrideCounter, SizedStrideCounter>);
138
test_stride_counting()139 constexpr void test_stride_counting() {
140 {
141 int a[] = {1, 2, 3};
142 int inc = 0;
143 StrideCounter first(a, &inc);
144 StrideCounter last(a+3, nullptr);
145 std::same_as<int> auto result = std::ranges::distance(first, last);
146 assert(result == 3);
147 assert(inc == 3);
148 }
149 {
150 int a[] = {1, 2, 3};
151 int minus = 0;
152 SizedStrideCounter first(a, &minus);
153 SizedStrideCounter last(a+3, nullptr);
154 std::same_as<int> auto result = std::ranges::distance(first, last);
155 assert(result == 3);
156 assert(minus == 1);
157 }
158 }
159
test()160 constexpr bool test() {
161 {
162 int a[] = {1, 2, 3};
163 assert(std::ranges::distance(a, a + 3) == 3);
164 assert(std::ranges::distance(a, a) == 0);
165 assert(std::ranges::distance(a + 3, a) == -3);
166 }
167
168 test_unsized<cpp17_input_iterator<int*>, sentinel_wrapper<cpp17_input_iterator<int*>>>();
169 test_unsized<cpp17_output_iterator<int*>, sentinel_wrapper<cpp17_output_iterator<int*>>>();
170 test_unsized<forward_iterator<int*>, sentinel_wrapper<forward_iterator<int*>>>();
171 test_unsized<bidirectional_iterator<int*>, sentinel_wrapper<bidirectional_iterator<int*>>>();
172 test_unsized<random_access_iterator<int*>, sentinel_wrapper<random_access_iterator<int*>>>();
173 test_unsized<contiguous_iterator<int*>, sentinel_wrapper<contiguous_iterator<int*>>>();
174 test_unsized<int*, sentinel_wrapper<int*>>();
175 test_unsized<const int*, sentinel_wrapper<const int*>>();
176 test_unsized<forward_iterator<int*>, forward_iterator<int*>>();
177 test_unsized<bidirectional_iterator<int*>, bidirectional_iterator<int*>>();
178
179 test_sized<cpp17_input_iterator<int*>, sized_sentinel<cpp17_input_iterator<int*>>>();
180 test_sized<cpp20_input_iterator<int*>, sized_sentinel<cpp20_input_iterator<int*>>>();
181 test_sized<cpp17_output_iterator<int*>, sized_sentinel<cpp17_output_iterator<int*>>>();
182 test_sized<forward_iterator<int*>, sized_sentinel<forward_iterator<int*>>>();
183 test_sized<bidirectional_iterator<int*>, sized_sentinel<bidirectional_iterator<int*>>>();
184 test_sized<random_access_iterator<int*>, sized_sentinel<random_access_iterator<int*>>>();
185 test_sized<contiguous_iterator<int*>, sized_sentinel<contiguous_iterator<int*>>>();
186 test_sized<int*, sized_sentinel<int*>>();
187 test_sized<const int*, sized_sentinel<const int*>>();
188 test_sized<int*, int*>();
189 test_sized<int*, const int*>();
190 test_sized<random_access_iterator<int*>, random_access_iterator<int*>>();
191 test_sized<contiguous_iterator<int*>, contiguous_iterator<int*>>();
192
193 {
194 using It = cpp20_input_iterator<int*>; // non-copyable, thus not a sentinel for itself
195 static_assert(!std::is_copy_constructible_v<It>);
196 static_assert(!std::sentinel_for<It, It>);
197 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&, It&>);
198 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&, It&&>);
199 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&&, It&>);
200 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&&, It&&>);
201 }
202 {
203 using It = cpp20_input_iterator<int*>; // non-copyable
204 using Sent = sentinel_wrapper<It>; // not a sized sentinel
205 static_assert(std::sentinel_for<Sent, It> && !std::sized_sentinel_for<Sent, It>);
206 int a[] = {1,2,3};
207 Sent last = Sent(It(a + 3));
208 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&, Sent&>);
209 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&, Sent&&>);
210 assert(std::ranges::distance(It(a), last) == 3);
211 assert(std::ranges::distance(It(a), Sent(It(a + 3))) == 3);
212 }
213 {
214 using It = cpp17_input_iterator<int*>; // not a sentinel for itself
215 static_assert(!std::sentinel_for<It, It>);
216 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&, It&>);
217 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&, It&&>);
218 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&&, It&>);
219 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), It&&, It&&>);
220 }
221
222 // Calling it on a non-iterator or non-sentinel isn't allowed.
223 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), int, int>);
224 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), int*, int>);
225 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), int, int*>);
226 static_assert(!std::is_invocable_v<decltype(std::ranges::distance), int*, char*>);
227
228 return true;
229 }
230
main(int,char **)231 int main(int, char**) {
232 test();
233 static_assert(test());
234
235 return 0;
236 }
237