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 // test if zip_view models input_range, forward_range, bidirectional_range,
13 //                         random_access_range, contiguous_range, common_range
14 //                         sized_range
15 
16 #include <cassert>
17 #include <concepts>
18 #include <ranges>
19 #include <tuple>
20 #include <utility>
21 
22 #include "types.h"
23 
testConceptPair()24 void testConceptPair() {
25   int buffer1[2] = {1, 2};
26   int buffer2[3] = {1, 2, 3};
27   {
28     std::ranges::zip_view v{ContiguousCommonView{buffer1}, ContiguousCommonView{buffer2}};
29     using View = decltype(v);
30     static_assert(std::ranges::random_access_range<View>);
31     static_assert(!std::ranges::contiguous_range<View>);
32     static_assert(std::ranges::common_range<View>);
33     static_assert(std::ranges::sized_range<View>);
34   }
35 
36   {
37     std::ranges::zip_view v{ContiguousNonCommonView{buffer1}, ContiguousNonCommonView{buffer2}};
38     using View = decltype(v);
39     static_assert(std::ranges::random_access_range<View>);
40     static_assert(!std::ranges::contiguous_range<View>);
41     static_assert(!std::ranges::common_range<View>);
42     static_assert(!std::ranges::sized_range<View>);
43   }
44 
45   {
46     std::ranges::zip_view v{ContiguousNonCommonSized{buffer1}, ContiguousNonCommonSized{buffer2}};
47     using View = decltype(v);
48     static_assert(std::ranges::random_access_range<View>);
49     static_assert(!std::ranges::contiguous_range<View>);
50     static_assert(std::ranges::common_range<View>);
51     static_assert(std::ranges::sized_range<View>);
52   }
53 
54   {
55     std::ranges::zip_view v{SizedRandomAccessView{buffer1}, ContiguousCommonView{buffer2}};
56     using View = decltype(v);
57     static_assert(std::ranges::random_access_range<View>);
58     static_assert(!std::ranges::contiguous_range<View>);
59     static_assert(std::ranges::common_range<View>);
60     static_assert(std::ranges::sized_range<View>);
61   }
62 
63   {
64     std::ranges::zip_view v{SizedRandomAccessView{buffer1}, SizedRandomAccessView{buffer2}};
65     using View = decltype(v);
66     static_assert(std::ranges::random_access_range<View>);
67     static_assert(!std::ranges::contiguous_range<View>);
68     static_assert(std::ranges::common_range<View>);
69     static_assert(std::ranges::sized_range<View>);
70   }
71 
72   {
73     std::ranges::zip_view v{NonSizedRandomAccessView{buffer1}, NonSizedRandomAccessView{buffer2}};
74     using View = decltype(v);
75     static_assert(std::ranges::random_access_range<View>);
76     static_assert(!std::ranges::contiguous_range<View>);
77     static_assert(!std::ranges::common_range<View>);
78     static_assert(!std::ranges::sized_range<View>);
79   }
80 
81   {
82     std::ranges::zip_view v{BidiCommonView{buffer1}, SizedRandomAccessView{buffer2}};
83     using View = decltype(v);
84     static_assert(std::ranges::bidirectional_range<View>);
85     static_assert(!std::ranges::random_access_range<View>);
86     static_assert(!std::ranges::common_range<View>);
87     static_assert(!std::ranges::sized_range<View>);
88   }
89 
90   {
91     std::ranges::zip_view v{BidiCommonView{buffer1}, BidiCommonView{buffer2}};
92     using View = decltype(v);
93     static_assert(std::ranges::bidirectional_range<View>);
94     static_assert(!std::ranges::random_access_range<View>);
95     static_assert(!std::ranges::common_range<View>);
96     static_assert(!std::ranges::sized_range<View>);
97   }
98 
99   {
100     std::ranges::zip_view v{BidiCommonView{buffer1}, ForwardSizedView{buffer2}};
101     using View = decltype(v);
102     static_assert(std::ranges::forward_range<View>);
103     static_assert(!std::ranges::bidirectional_range<View>);
104     static_assert(std::ranges::common_range<View>);
105     static_assert(!std::ranges::sized_range<View>);
106   }
107 
108   {
109     std::ranges::zip_view v{BidiNonCommonView{buffer1}, ForwardSizedView{buffer2}};
110     using View = decltype(v);
111     static_assert(std::ranges::forward_range<View>);
112     static_assert(!std::ranges::bidirectional_range<View>);
113     static_assert(!std::ranges::common_range<View>);
114     static_assert(!std::ranges::sized_range<View>);
115   }
116 
117   {
118     std::ranges::zip_view v{ForwardSizedView{buffer1}, ForwardSizedView{buffer2}};
119     using View = decltype(v);
120     static_assert(std::ranges::forward_range<View>);
121     static_assert(!std::ranges::bidirectional_range<View>);
122     static_assert(std::ranges::common_range<View>);
123     static_assert(std::ranges::sized_range<View>);
124   }
125 
126   {
127     std::ranges::zip_view v{ForwardSizedNonCommon{buffer1}, ForwardSizedView{buffer2}};
128     using View = decltype(v);
129     static_assert(std::ranges::forward_range<View>);
130     static_assert(!std::ranges::bidirectional_range<View>);
131     static_assert(!std::ranges::common_range<View>);
132     static_assert(std::ranges::sized_range<View>);
133   }
134 
135   {
136     std::ranges::zip_view v{InputCommonView{buffer1}, ForwardSizedView{buffer2}};
137     using View = decltype(v);
138     static_assert(std::ranges::input_range<View>);
139     static_assert(!std::ranges::forward_range<View>);
140     static_assert(std::ranges::common_range<View>);
141     static_assert(!std::ranges::sized_range<View>);
142   }
143 
144   {
145     std::ranges::zip_view v{InputCommonView{buffer1}, InputCommonView{buffer2}};
146     using View = decltype(v);
147     static_assert(std::ranges::input_range<View>);
148     static_assert(!std::ranges::forward_range<View>);
149     static_assert(std::ranges::common_range<View>);
150     static_assert(!std::ranges::sized_range<View>);
151   }
152 
153   {
154     std::ranges::zip_view v{InputNonCommonView{buffer1}, InputCommonView{buffer2}};
155     using View = decltype(v);
156     static_assert(std::ranges::input_range<View>);
157     static_assert(!std::ranges::forward_range<View>);
158     static_assert(!std::ranges::common_range<View>);
159     static_assert(!std::ranges::sized_range<View>);
160   }
161 }
162 
testConceptTuple()163 void testConceptTuple() {
164   int buffer1[2] = {1, 2};
165   int buffer2[3] = {1, 2, 3};
166   int buffer3[4] = {1, 2, 3, 4};
167 
168   {
169     std::ranges::zip_view v{ContiguousCommonView{buffer1}, ContiguousCommonView{buffer2},
170                             ContiguousCommonView{buffer3}};
171     using View = decltype(v);
172     static_assert(std::ranges::random_access_range<View>);
173     static_assert(!std::ranges::contiguous_range<View>);
174     static_assert(std::ranges::common_range<View>);
175     static_assert(std::ranges::sized_range<View>);
176   }
177 
178   {
179     std::ranges::zip_view v{ContiguousNonCommonView{buffer1}, ContiguousNonCommonView{buffer2},
180                             ContiguousNonCommonView{buffer3}};
181     using View = decltype(v);
182     static_assert(std::ranges::random_access_range<View>);
183     static_assert(!std::ranges::contiguous_range<View>);
184     static_assert(!std::ranges::common_range<View>);
185     static_assert(!std::ranges::sized_range<View>);
186   }
187 
188   {
189     std::ranges::zip_view v{ContiguousNonCommonSized{buffer1}, ContiguousNonCommonSized{buffer2},
190                             ContiguousNonCommonSized{buffer3}};
191     using View = decltype(v);
192     static_assert(std::ranges::random_access_range<View>);
193     static_assert(!std::ranges::contiguous_range<View>);
194     static_assert(std::ranges::common_range<View>);
195     static_assert(std::ranges::sized_range<View>);
196   }
197 
198   {
199     std::ranges::zip_view v{SizedRandomAccessView{buffer1}, ContiguousCommonView{buffer2},
200                             ContiguousCommonView{buffer3}};
201     using View = decltype(v);
202     static_assert(std::ranges::random_access_range<View>);
203     static_assert(!std::ranges::contiguous_range<View>);
204     static_assert(std::ranges::common_range<View>);
205     static_assert(std::ranges::sized_range<View>);
206   }
207 
208   {
209     std::ranges::zip_view v{SizedRandomAccessView{buffer1}, SizedRandomAccessView{buffer2},
210                             SizedRandomAccessView{buffer3}};
211     using View = decltype(v);
212     static_assert(std::ranges::random_access_range<View>);
213     static_assert(!std::ranges::contiguous_range<View>);
214     static_assert(std::ranges::common_range<View>);
215     static_assert(std::ranges::sized_range<View>);
216   }
217 
218   {
219     std::ranges::zip_view v{NonSizedRandomAccessView{buffer1}, NonSizedRandomAccessView{buffer2},
220                             NonSizedRandomAccessView{buffer3}};
221     using View = decltype(v);
222     static_assert(std::ranges::random_access_range<View>);
223     static_assert(!std::ranges::contiguous_range<View>);
224     static_assert(!std::ranges::common_range<View>);
225     static_assert(!std::ranges::sized_range<View>);
226   }
227 
228   {
229     std::ranges::zip_view v{BidiCommonView{buffer1}, SizedRandomAccessView{buffer2}, SizedRandomAccessView{buffer3}};
230     using View = decltype(v);
231     static_assert(std::ranges::bidirectional_range<View>);
232     static_assert(!std::ranges::random_access_range<View>);
233     static_assert(!std::ranges::common_range<View>);
234     static_assert(!std::ranges::sized_range<View>);
235   }
236 
237   {
238     std::ranges::zip_view v{BidiCommonView{buffer1}, BidiCommonView{buffer2}, BidiCommonView{buffer3}};
239     using View = decltype(v);
240     static_assert(std::ranges::bidirectional_range<View>);
241     static_assert(!std::ranges::random_access_range<View>);
242     static_assert(!std::ranges::common_range<View>);
243     static_assert(!std::ranges::sized_range<View>);
244   }
245 
246   {
247     std::ranges::zip_view v{BidiCommonView{buffer1}, ForwardSizedView{buffer2}, ForwardSizedView{buffer3}};
248     using View = decltype(v);
249     static_assert(std::ranges::forward_range<View>);
250     static_assert(!std::ranges::bidirectional_range<View>);
251     static_assert(std::ranges::common_range<View>);
252     static_assert(!std::ranges::sized_range<View>);
253   }
254 
255   {
256     std::ranges::zip_view v{BidiNonCommonView{buffer1}, ForwardSizedView{buffer2}, ForwardSizedView{buffer3}};
257     using View = decltype(v);
258     static_assert(std::ranges::forward_range<View>);
259     static_assert(!std::ranges::bidirectional_range<View>);
260     static_assert(!std::ranges::common_range<View>);
261     static_assert(!std::ranges::sized_range<View>);
262   }
263 
264   {
265     std::ranges::zip_view v{ForwardSizedView{buffer1}, ForwardSizedView{buffer2}, ForwardSizedView{buffer3}};
266     using View = decltype(v);
267     static_assert(std::ranges::forward_range<View>);
268     static_assert(!std::ranges::bidirectional_range<View>);
269     static_assert(std::ranges::common_range<View>);
270     static_assert(std::ranges::sized_range<View>);
271   }
272 
273   {
274     std::ranges::zip_view v{ForwardSizedNonCommon{buffer1}, ForwardSizedView{buffer2}, ForwardSizedView{buffer3}};
275     using View = decltype(v);
276     static_assert(std::ranges::forward_range<View>);
277     static_assert(!std::ranges::bidirectional_range<View>);
278     static_assert(!std::ranges::common_range<View>);
279     static_assert(std::ranges::sized_range<View>);
280   }
281 
282   {
283     std::ranges::zip_view v{InputCommonView{buffer1}, ForwardSizedView{buffer2}, ForwardSizedView{buffer3}};
284     using View = decltype(v);
285     static_assert(std::ranges::input_range<View>);
286     static_assert(!std::ranges::forward_range<View>);
287     static_assert(std::ranges::common_range<View>);
288     static_assert(!std::ranges::sized_range<View>);
289   }
290 
291   {
292     std::ranges::zip_view v{InputCommonView{buffer1}, InputCommonView{buffer2}, InputCommonView{buffer3}};
293     using View = decltype(v);
294     static_assert(std::ranges::input_range<View>);
295     static_assert(!std::ranges::forward_range<View>);
296     static_assert(std::ranges::common_range<View>);
297     static_assert(!std::ranges::sized_range<View>);
298   }
299 
300   {
301     std::ranges::zip_view v{InputNonCommonView{buffer1}, InputCommonView{buffer2}, InputCommonView{buffer3}};
302     using View = decltype(v);
303     static_assert(std::ranges::input_range<View>);
304     static_assert(!std::ranges::forward_range<View>);
305     static_assert(!std::ranges::common_range<View>);
306     static_assert(!std::ranges::sized_range<View>);
307   }
308 }
309 
310 using OutputIter = cpp17_output_iterator<int*>;
311 static_assert(std::output_iterator<OutputIter, int>);
312 
313 struct OutputView : std::ranges::view_base {
314   OutputIter begin() const;
315   sentinel_wrapper<OutputIter> end() const;
316 };
317 static_assert(std::ranges::output_range<OutputView, int>);
318 static_assert(!std::ranges::input_range<OutputView>);
319 
320 template <class... Ts>
321 concept zippable = requires {
322   typename std::ranges::zip_view<Ts...>;
323 };
324 
325 // output_range is not supported
326 static_assert(!zippable<OutputView>);
327 static_assert(!zippable<SimpleCommon, OutputView>);
328 static_assert(zippable<SimpleCommon>);
329