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