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, c++20
10 // UNSUPPORTED: libcpp-has-no-incomplete-ranges
11
12 // constexpr auto end() requires(!(simple-view<Views> && ...))
13 // constexpr auto end() const requires(range<const Views>&&...)
14
15 #include <ranges>
16 #include <tuple>
17
18 #include "types.h"
19
20 // ID | simple | common | bidi | random | sized | #views | v.end() | as_const(v)
21 // | | | | access | | | | .end()
22 // ---|--------|--------|------|--------|-------|--------|----------------|---------------
23 // 1 | Y | Y | Y | Y | Y | 1 | iterator<true> | iterator<true>
24 // 2 | Y | Y | Y | Y | Y | >1 | iterator<true> | iterator<true>
25 // 3 | Y | N | Y | Y | N | 1 | sentinel<true> | sentinel<true>
26 // 4 | Y | N | Y | Y | N | >1 | sentinel<true> | sentinel<true>
27 // 5 | Y | Y | Y | N | Y | 1 | iterator<true> | iterator<true>
28 // 6 | Y | Y | Y | N | Y | >1 | sentinel<true> | sentinel<true>
29 // 7 | Y | Y | Y | N | N | 1 | iterator<true> | iterator<true>
30 // 8 | Y | Y | Y | N | N | >1 | sentinel<true> | sentinel<true>
31 // 9 | Y | Y | N | N | Y | 1 | iterator<true> | iterator<true>
32 // 10 | Y | Y | N | N | Y | >1 | iterator<true> | iterator<true>
33 // 11 | Y | Y | N | N | N | 1 | iterator<true> | iterator<true>
34 // 12 | Y | Y | N | N | N | >1 | iterator<true> | iterator<true>
35 // 13 | Y | N | Y | Y | Y | 1 | iterator<true> | iterator<true>
36 // 14 | Y | N | Y | Y | Y | >1 | iterator<true> | iterator<true>
37 // 15 | Y | N | Y | N | Y | 1 | sentinel<true> | sentinel<true>
38 // 16 | Y | N | Y | N | Y | >1 | sentinel<true> | sentinel<true>
39 // 17 | Y | N | Y | N | N | 1 | sentinel<true> | sentinel<true>
40 // 18 | Y | N | Y | N | N | >1 | sentinel<true> | sentinel<true>
41 // 19 | Y | N | N | N | Y | 1 | sentinel<true> | sentinel<true>
42 // 20 | Y | N | N | N | Y | >1 | sentinel<true> | sentinel<true>
43 // 21 | Y | N | N | N | N | 1 | sentinel<true> | sentinel<true>
44 // 22 | Y | N | N | N | N | >1 | sentinel<true> | sentinel<true>
45 // 23 | N | Y | Y | Y | Y | 1 | iterator<false>| iterator<true>
46 // 24 | N | Y | Y | Y | Y | >1 | iterator<false>| iterator<true>
47 // 25 | N | N | Y | Y | N | 1 | sentinel<false>| sentinel<true>
48 // 26 | N | N | Y | Y | N | >1 | sentinel<false>| sentinel<true>
49 // 27 | N | Y | Y | N | Y | 1 | iterator<false>| iterator<true>
50 // 28 | N | Y | Y | N | Y | >1 | sentinel<false>| sentinel<true>
51 // 29 | N | Y | Y | N | N | 1 | iterator<false>| iterator<true>
52 // 30 | N | Y | Y | N | N | >1 | sentinel<false>| sentinel<true>
53 // 31 | N | Y | N | N | Y | 1 | iterator<false>| iterator<true>
54 // 32 | N | Y | N | N | Y | >1 | iterator<false>| iterator<true>
55 // 33 | N | Y | N | N | N | 1 | iterator<false>| iterator<true>
56 // 34 | N | Y | N | N | N | >1 | iterator<false>| iterator<true>
57 // 35 | N | N | Y | Y | Y | 1 | iterator<false>| iterator<true>
58 // 36 | N | N | Y | Y | Y | >1 | iterator<false>| iterator<true>
59 // 37 | N | N | Y | N | Y | 1 | sentinel<false>| sentinel<true>
60 // 38 | N | N | Y | N | Y | >1 | sentinel<false>| sentinel<true>
61 // 39 | N | N | Y | N | N | 1 | sentinel<false>| sentinel<true>
62 // 40 | N | N | Y | N | N | >1 | sentinel<false>| sentinel<true>
63 // 41 | N | N | N | N | Y | 1 | sentinel<false>| sentinel<true>
64 // 42 | N | N | N | N | Y | >1 | sentinel<false>| sentinel<true>
65 // 43 | N | N | N | N | N | 1 | sentinel<false>| sentinel<true>
66 // 44 | N | N | N | N | N | >1 | sentinel<false>| sentinel<true>
67
test()68 constexpr bool test() {
69 int buffer1[5] = {1, 2, 3, 4, 5};
70 int buffer2[1] = {1};
71 int buffer3[3] = {1, 2, 3};
72 {
73 // test ID 1
74 std::ranges::zip_view v{SimpleCommonRandomAccessSized(buffer1)};
75 static_assert(std::ranges::common_range<decltype(v)>);
76 assert(v.begin() + 5 == v.end());
77 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
78 }
79 {
80 // test ID 2
81 std::ranges::zip_view v{SimpleCommonRandomAccessSized(buffer1), SimpleCommonRandomAccessSized(buffer2)};
82 static_assert(std::ranges::common_range<decltype(v)>);
83 assert(v.begin() + 1 == v.end());
84 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
85 }
86 {
87 // test ID 3
88 std::ranges::zip_view v{NonSizedRandomAccessView(buffer1)};
89 static_assert(!std::ranges::common_range<decltype(v)>);
90 assert(v.begin() + 5 == v.end());
91 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
92 }
93 {
94 // test ID 4
95 std::ranges::zip_view v{NonSizedRandomAccessView(buffer1), NonSizedRandomAccessView(buffer3)};
96 static_assert(!std::ranges::common_range<decltype(v)>);
97 assert(v.begin() + 3 == v.end());
98 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
99 }
100 {
101 // test ID 5
102 std::ranges::zip_view v{SizedBidiCommon(buffer1)};
103 static_assert(std::ranges::common_range<decltype(v)>);
104 assert(std::next(v.begin(), 5) == v.end());
105 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
106 }
107 {
108 // test ID 6
109 std::ranges::zip_view v{SizedBidiCommon(buffer1), SizedBidiCommon(buffer2)};
110 static_assert(!std::ranges::common_range<decltype(v)>);
111 assert(++v.begin() == v.end());
112 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
113 }
114 {
115 // test ID 7
116 std::ranges::zip_view v{BidiCommonView(buffer1)};
117 static_assert(std::ranges::common_range<decltype(v)>);
118 assert(std::next(v.begin(), 5) == v.end());
119 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
120 }
121 {
122 // test ID 8
123 std::ranges::zip_view v{BidiCommonView(buffer1), BidiCommonView(buffer2)};
124 static_assert(!std::ranges::common_range<decltype(v)>);
125 assert(++v.begin() == v.end());
126 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
127 }
128 {
129 // test ID 9
130 std::ranges::zip_view v{ForwardSizedView(buffer1)};
131 static_assert(std::ranges::common_range<decltype(v)>);
132 assert(std::next(v.begin(), 5) == v.end());
133 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
134 }
135 {
136 // test ID 10
137 std::ranges::zip_view v{ForwardSizedView(buffer1), ForwardSizedView(buffer2)};
138 static_assert(std::ranges::common_range<decltype(v)>);
139 assert(++v.begin() == v.end());
140 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
141 }
142 {
143 // test ID 11
144 std::ranges::zip_view v{InputCommonView(buffer1)};
145 static_assert(std::ranges::common_range<decltype(v)>);
146 assert(std::ranges::next(v.begin(), 5) == v.end());
147 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
148 }
149 {
150 // test ID 12
151 std::ranges::zip_view v{InputCommonView(buffer1), InputCommonView(buffer2)};
152 static_assert(std::ranges::common_range<decltype(v)>);
153 assert(++v.begin() == v.end());
154 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
155 }
156 {
157 // test ID 13
158 std::ranges::zip_view v{SimpleNonCommonRandomAcessSized(buffer1)};
159 static_assert(std::ranges::common_range<decltype(v)>);
160 assert(v.begin() + 5 == v.end());
161 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
162 }
163 {
164 // test ID 14
165 std::ranges::zip_view v{SimpleNonCommonRandomAcessSized(buffer1), SimpleNonCommonRandomAcessSized(buffer2)};
166 static_assert(std::ranges::common_range<decltype(v)>);
167 assert(v.begin() + 1 == v.end());
168 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
169 }
170 {
171 // test ID 15
172 std::ranges::zip_view v{SizedBidiNonCommonView(buffer1)};
173 static_assert(!std::ranges::common_range<decltype(v)>);
174 assert(std::next(v.begin(), 5) == v.end());
175 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
176 }
177 {
178 // test ID 16
179 std::ranges::zip_view v{SizedBidiNonCommonView(buffer1), SizedBidiNonCommonView(buffer2)};
180 static_assert(!std::ranges::common_range<decltype(v)>);
181 assert(++v.begin() == v.end());
182 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
183 }
184 {
185 // test ID 17
186 std::ranges::zip_view v{BidiNonCommonView(buffer1)};
187 static_assert(!std::ranges::common_range<decltype(v)>);
188 assert(std::next(v.begin(), 5) == v.end());
189 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
190 }
191 {
192 // test ID 18
193 std::ranges::zip_view v{BidiNonCommonView(buffer1), BidiNonCommonView(buffer2)};
194 static_assert(!std::ranges::common_range<decltype(v)>);
195 assert(++v.begin() == v.end());
196 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
197 }
198 {
199 // test ID 19
200 std::ranges::zip_view v{ForwardSizedNonCommon(buffer1)};
201 static_assert(!std::ranges::common_range<decltype(v)>);
202 assert(std::next(v.begin(), 5) == v.end());
203 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
204 }
205 {
206 // test ID 20
207 std::ranges::zip_view v{ForwardSizedNonCommon(buffer1), ForwardSizedNonCommon(buffer2)};
208 static_assert(!std::ranges::common_range<decltype(v)>);
209 assert(++v.begin() == v.end());
210 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
211 }
212 {
213 // test ID 21
214 std::ranges::zip_view v{InputNonCommonView(buffer1)};
215 static_assert(!std::ranges::common_range<decltype(v)>);
216 assert(std::ranges::next(v.begin(), 5) == v.end());
217 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
218 }
219 {
220 // test ID 22
221 std::ranges::zip_view v{InputNonCommonView(buffer1), InputNonCommonView(buffer2)};
222 static_assert(!std::ranges::common_range<decltype(v)>);
223 assert(++v.begin() == v.end());
224 static_assert(std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
225 }
226 {
227 // test ID 23
228 std::ranges::zip_view v{NonSimpleCommonRandomAccessSized(buffer1)};
229 static_assert(std::ranges::common_range<decltype(v)>);
230 assert(v.begin() + 5 == v.end());
231 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
232 }
233 {
234 // test ID 24
235 std::ranges::zip_view v{NonSimpleCommonRandomAccessSized(buffer1), NonSimpleCommonRandomAccessSized(buffer2)};
236 static_assert(std::ranges::common_range<decltype(v)>);
237 assert(v.begin() + 1 == v.end());
238 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
239 }
240 {
241 // test ID 25
242 std::ranges::zip_view v{NonSimpleNonSizedRandomAccessView(buffer1)};
243 static_assert(!std::ranges::common_range<decltype(v)>);
244 assert(v.begin() + 5 == v.end());
245 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
246 }
247 {
248 // test ID 26
249 std::ranges::zip_view v{NonSimpleNonSizedRandomAccessView(buffer1), NonSimpleNonSizedRandomAccessView(buffer3)};
250 static_assert(!std::ranges::common_range<decltype(v)>);
251 assert(v.begin() + 3 == v.end());
252 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
253 }
254 {
255 // test ID 27
256 std::ranges::zip_view v{NonSimpleSizedBidiCommon(buffer1)};
257 static_assert(std::ranges::common_range<decltype(v)>);
258 assert(std::next(v.begin(), 5) == v.end());
259 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
260 }
261 {
262 // test ID 28
263 std::ranges::zip_view v{NonSimpleSizedBidiCommon(buffer1), NonSimpleSizedBidiCommon(buffer2)};
264 static_assert(!std::ranges::common_range<decltype(v)>);
265 assert(++v.begin() == v.end());
266 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
267 }
268 {
269 // test ID 29
270 std::ranges::zip_view v{NonSimpleBidiCommonView(buffer1)};
271 static_assert(std::ranges::common_range<decltype(v)>);
272 assert(std::next(v.begin(), 5) == v.end());
273 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
274 }
275 {
276 // test ID 30
277 std::ranges::zip_view v{NonSimpleBidiCommonView(buffer1), NonSimpleBidiCommonView(buffer2)};
278 static_assert(!std::ranges::common_range<decltype(v)>);
279 assert(++v.begin() == v.end());
280 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
281 }
282 {
283 // test ID 31
284 std::ranges::zip_view v{NonSimpleForwardSizedView(buffer1)};
285 static_assert(std::ranges::common_range<decltype(v)>);
286 assert(std::next(v.begin(), 5) == v.end());
287 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
288 }
289 {
290 // test ID 32
291 std::ranges::zip_view v{NonSimpleForwardSizedView(buffer1), NonSimpleForwardSizedView(buffer2)};
292 static_assert(std::ranges::common_range<decltype(v)>);
293 assert(++v.begin() == v.end());
294 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
295 }
296 {
297 // test ID 33
298 std::ranges::zip_view v{NonSimpleInputCommonView(buffer1)};
299 static_assert(std::ranges::common_range<decltype(v)>);
300 assert(std::ranges::next(v.begin(), 5) == v.end());
301 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
302 }
303 {
304 // test ID 34
305 std::ranges::zip_view v{NonSimpleInputCommonView(buffer1), NonSimpleInputCommonView(buffer2)};
306 static_assert(std::ranges::common_range<decltype(v)>);
307 assert(++v.begin() == v.end());
308 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
309 }
310 {
311 // test ID 35
312 std::ranges::zip_view v{NonSimpleNonCommonRandomAcessSized(buffer1)};
313 static_assert(std::ranges::common_range<decltype(v)>);
314 assert(v.begin() + 5 == v.end());
315 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
316 }
317 {
318 // test ID 36
319 std::ranges::zip_view v{NonSimpleNonCommonRandomAcessSized(buffer1), NonSimpleNonCommonRandomAcessSized(buffer2)};
320 static_assert(std::ranges::common_range<decltype(v)>);
321 assert(v.begin() + 1 == v.end());
322 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
323 }
324 {
325 // test ID 37
326 std::ranges::zip_view v{NonSimpleSizedBidiNonCommonView(buffer1)};
327 static_assert(!std::ranges::common_range<decltype(v)>);
328 assert(std::next(v.begin(), 5) == v.end());
329 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
330 }
331 {
332 // test ID 38
333 std::ranges::zip_view v{NonSimpleSizedBidiNonCommonView(buffer1), NonSimpleSizedBidiNonCommonView(buffer2)};
334 static_assert(!std::ranges::common_range<decltype(v)>);
335 assert(++v.begin() == v.end());
336 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
337 }
338 {
339 // test ID 39
340 std::ranges::zip_view v{NonSimpleBidiNonCommonView(buffer1)};
341 static_assert(!std::ranges::common_range<decltype(v)>);
342 assert(std::next(v.begin(), 5) == v.end());
343 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
344 }
345 {
346 // test ID 40
347 std::ranges::zip_view v{NonSimpleBidiNonCommonView(buffer1), NonSimpleBidiNonCommonView(buffer2)};
348 static_assert(!std::ranges::common_range<decltype(v)>);
349 assert(++v.begin() == v.end());
350 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
351 }
352 {
353 // test ID 41
354 std::ranges::zip_view v{NonSimpleForwardSizedNonCommon(buffer1)};
355 static_assert(!std::ranges::common_range<decltype(v)>);
356 assert(std::next(v.begin(), 5) == v.end());
357 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
358 }
359 {
360 // test ID 42
361 std::ranges::zip_view v{NonSimpleForwardSizedNonCommon(buffer1), NonSimpleForwardSizedNonCommon(buffer2)};
362 static_assert(!std::ranges::common_range<decltype(v)>);
363 assert(++v.begin() == v.end());
364 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
365 }
366 {
367 // test ID 43
368 std::ranges::zip_view v{NonSimpleInputNonCommonView(buffer1)};
369 static_assert(!std::ranges::common_range<decltype(v)>);
370 assert(std::ranges::next(v.begin(), 5) == v.end());
371 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
372 }
373 {
374 // test ID 44
375 std::ranges::zip_view v{NonSimpleInputNonCommonView(buffer1), NonSimpleInputNonCommonView(buffer2)};
376 static_assert(!std::ranges::common_range<decltype(v)>);
377 assert(++v.begin() == v.end());
378 static_assert(!std::is_same_v<decltype(v.end()), decltype(std::as_const(v).end())>);
379 }
380 {
381 // end should go to the minimum length when zip is common and random_access sized
382 std::ranges::zip_view v(std::views::iota(0, 4), std::views::iota(0, 8));
383 auto it = --(v.end());
384 auto [x, y] = *it;
385 assert(x == 3);
386 assert(y == 3); // y should not go to the end "7"
387 }
388 return true;
389 }
390
main(int,char **)391 int main(int, char**) {
392 test();
393 static_assert(test());
394
395 return 0;
396 }
397