xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.zip/types.h (revision e07a2f49e3d3c13b6e9b89e0f6118652f2b2d3ac)
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 #ifndef TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_ZIP_TYPES_H
10 #define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_ZIP_TYPES_H
11 
12 #include <functional>
13 #include <ranges>
14 
15 #include "test_macros.h"
16 #include "test_iterators.h"
17 #include "test_range.h"
18 
19 #if TEST_STD_VER <= 20
20 #  error "range.zip/types.h" can only be included in builds supporting C++20
21 #endif // TEST_STD_VER <= 20
22 
23 template <class T>
24 struct BufferView : std::ranges::view_base {
25   T* buffer_;
26   std::size_t size_;
27 
28   template <std::size_t N>
BufferViewBufferView29   constexpr BufferView(T (&b)[N]) : buffer_(b), size_(N) {}
30 };
31 
32 using IntBufferView = BufferView<int>;
33 
34 template <bool Simple>
35 struct Common :  IntBufferView {
36   using IntBufferView::IntBufferView;
37 
beginCommon38   constexpr int* begin()
39     requires(!Simple)
40   {
41     return buffer_;
42   }
beginCommon43   constexpr const int* begin() const { return buffer_; }
endCommon44   constexpr int* end()
45     requires(!Simple)
46   {
47     return buffer_ + size_;
48   }
endCommon49   constexpr const int* end() const { return buffer_ + size_; }
50 };
51 using SimpleCommon = Common<true>;
52 using NonSimpleCommon = Common<false>;
53 
54 using SimpleCommonRandomAccessSized = SimpleCommon;
55 using NonSimpleCommonRandomAccessSized = NonSimpleCommon;
56 
57 static_assert(std::ranges::common_range<Common<true>>);
58 static_assert(std::ranges::random_access_range<SimpleCommon>);
59 static_assert(std::ranges::sized_range<SimpleCommon>);
60 static_assert(simple_view<SimpleCommon>);
61 static_assert(!simple_view<NonSimpleCommon>);
62 
63 template <bool Simple>
64 struct CommonNonRandom : IntBufferView {
65   using IntBufferView::IntBufferView;
66   using const_iterator = forward_iterator<const int*>;
67   using iterator = forward_iterator<int*>;
beginCommonNonRandom68   constexpr iterator begin()
69     requires(!Simple) {
70     return iterator(buffer_);
71   }
beginCommonNonRandom72   constexpr const_iterator begin() const { return const_iterator(buffer_); }
endCommonNonRandom73   constexpr iterator end()
74     requires(!Simple) {
75     return iterator(buffer_ + size_);
76   }
endCommonNonRandom77   constexpr const_iterator end() const { return const_iterator(buffer_ + size_); }
78 };
79 
80 using SimpleCommonNonRandom = CommonNonRandom<true>;
81 using NonSimpleCommonNonRandom = CommonNonRandom<false>;
82 
83 static_assert(std::ranges::common_range<SimpleCommonNonRandom>);
84 static_assert(!std::ranges::random_access_range<SimpleCommonNonRandom>);
85 static_assert(!std::ranges::sized_range<SimpleCommonNonRandom>);
86 static_assert(simple_view<SimpleCommonNonRandom>);
87 static_assert(!simple_view<NonSimpleCommonNonRandom>);
88 
89 template <bool Simple>
90 struct NonCommon : IntBufferView {
91   using IntBufferView::IntBufferView;
beginNonCommon92   constexpr int* begin()
93     requires(!Simple) {
94     return buffer_;
95   }
beginNonCommon96   constexpr const int* begin() const { return buffer_; }
endNonCommon97   constexpr sentinel_wrapper<int*> end()
98     requires(!Simple) {
99     return sentinel_wrapper<int*>(buffer_ + size_);
100   }
endNonCommon101   constexpr sentinel_wrapper<const int*> end() const { return sentinel_wrapper<const int*>(buffer_ + size_); }
102 };
103 
104 using SimpleNonCommon = NonCommon<true>;
105 using NonSimpleNonCommon = NonCommon<false>;
106 
107 static_assert(!std::ranges::common_range<SimpleNonCommon>);
108 static_assert(std::ranges::random_access_range<SimpleNonCommon>);
109 static_assert(!std::ranges::sized_range<SimpleNonCommon>);
110 static_assert(simple_view<SimpleNonCommon>);
111 static_assert(!simple_view<NonSimpleNonCommon>);
112 
113 template <bool Simple>
114 struct NonCommonSized : IntBufferView {
115   using IntBufferView::IntBufferView;
beginNonCommonSized116   constexpr int* begin()
117     requires(!Simple) {
118     return buffer_;
119   }
beginNonCommonSized120   constexpr const int* begin() const { return buffer_; }
endNonCommonSized121   constexpr sentinel_wrapper<int*> end()
122     requires(!Simple) {
123     return sentinel_wrapper<int*>(buffer_ + size_);
124   }
endNonCommonSized125   constexpr sentinel_wrapper<const int*> end() const { return sentinel_wrapper<const int*>(buffer_ + size_); }
sizeNonCommonSized126   constexpr std::size_t size() const { return size_; }
127 };
128 
129 using SimpleNonCommonSized = NonCommonSized<true>;
130 using SimpleNonCommonRandomAccessSized    = SimpleNonCommonSized;
131 using NonSimpleNonCommonSized = NonCommonSized<false>;
132 using NonSimpleNonCommonRandomAccessSized = NonSimpleNonCommonSized;
133 
134 static_assert(!std::ranges::common_range<SimpleNonCommonSized>);
135 static_assert(std::ranges::random_access_range<SimpleNonCommonSized>);
136 static_assert(std::ranges::sized_range<SimpleNonCommonSized>);
137 static_assert(simple_view<SimpleNonCommonSized>);
138 static_assert(!simple_view<NonSimpleNonCommonSized>);
139 
140 template <bool Simple>
141 struct NonCommonNonRandom : IntBufferView {
142   using IntBufferView::IntBufferView;
143 
144   using const_iterator = forward_iterator<const int*>;
145   using iterator = forward_iterator<int*>;
146 
beginNonCommonNonRandom147   constexpr iterator begin()
148     requires(!Simple) {
149     return iterator(buffer_);
150   }
beginNonCommonNonRandom151   constexpr const_iterator begin() const { return const_iterator(buffer_); }
endNonCommonNonRandom152   constexpr sentinel_wrapper<iterator> end()
153     requires(!Simple) {
154     return sentinel_wrapper<iterator>(iterator(buffer_ + size_));
155   }
endNonCommonNonRandom156   constexpr sentinel_wrapper<const_iterator> end() const {
157     return sentinel_wrapper<const_iterator>(const_iterator(buffer_ + size_));
158   }
159 };
160 
161 using SimpleNonCommonNonRandom = NonCommonNonRandom<true>;
162 using NonSimpleNonCommonNonRandom = NonCommonNonRandom<false>;
163 
164 static_assert(!std::ranges::common_range<SimpleNonCommonNonRandom>);
165 static_assert(!std::ranges::random_access_range<SimpleNonCommonNonRandom>);
166 static_assert(!std::ranges::sized_range<SimpleNonCommonNonRandom>);
167 static_assert(simple_view<SimpleNonCommonNonRandom>);
168 static_assert(!simple_view<NonSimpleNonCommonNonRandom>);
169 
170 template <class Iter, class Sent = Iter, class NonConstIter = Iter, class NonConstSent = Sent>
171 struct BasicView : IntBufferView {
172   using IntBufferView::IntBufferView;
173 
beginBasicView174   constexpr NonConstIter begin()
175     requires(!std::is_same_v<Iter, NonConstIter>) {
176     return NonConstIter(buffer_);
177   }
beginBasicView178   constexpr Iter begin() const { return Iter(buffer_); }
179 
endBasicView180   constexpr NonConstSent end()
181     requires(!std::is_same_v<Sent, NonConstSent>) {
182     if constexpr (std::is_same_v<NonConstIter, NonConstSent>) {
183       return NonConstIter(buffer_ + size_);
184     } else {
185       return NonConstSent(NonConstIter(buffer_ + size_));
186     }
187   }
188 
endBasicView189   constexpr Sent end() const {
190     if constexpr (std::is_same_v<Iter, Sent>) {
191       return Iter(buffer_ + size_);
192     } else {
193       return Sent(Iter(buffer_ + size_));
194     }
195   }
196 };
197 
198 template <class Base = int*>
199 struct forward_sized_iterator {
200   Base it_ = nullptr;
201 
202   using iterator_category = std::forward_iterator_tag;
203   using value_type = int;
204   using difference_type = std::intptr_t;
205   using pointer = Base;
206   using reference = decltype(*Base{});
207 
208   forward_sized_iterator() = default;
forward_sized_iteratorforward_sized_iterator209   constexpr forward_sized_iterator(Base it) : it_(it) {}
210 
211   constexpr reference operator*() const { return *it_; }
212 
213   constexpr forward_sized_iterator& operator++() {
214     ++it_;
215     return *this;
216   }
217   constexpr forward_sized_iterator operator++(int) { return forward_sized_iterator(it_++); }
218 
219   friend constexpr bool operator==(const forward_sized_iterator&, const forward_sized_iterator&) = default;
220 
221   friend constexpr difference_type operator-(const forward_sized_iterator& x, const forward_sized_iterator& y) {
222     return x.it_ - y.it_;
223   }
224 };
225 static_assert(std::forward_iterator<forward_sized_iterator<>>);
226 static_assert(std::sized_sentinel_for<forward_sized_iterator<>, forward_sized_iterator<>>);
227 
228 using ForwardSizedView = BasicView<forward_sized_iterator<>>;
229 static_assert(std::ranges::forward_range<ForwardSizedView>);
230 static_assert(std::ranges::sized_range<ForwardSizedView>);
231 static_assert(std::ranges::common_range<ForwardSizedView>);
232 static_assert(!std::ranges::random_access_range<ForwardSizedView>);
233 static_assert(simple_view<ForwardSizedView>);
234 
235 using NonSimpleForwardSizedView = BasicView<forward_sized_iterator<const int*>, forward_sized_iterator<const int*>,
236                                             forward_sized_iterator<int*>, forward_sized_iterator<int*>>;
237 static_assert(std::ranges::forward_range<NonSimpleForwardSizedView>);
238 static_assert(std::ranges::sized_range<NonSimpleForwardSizedView>);
239 static_assert(std::ranges::common_range<NonSimpleForwardSizedView>);
240 static_assert(!std::ranges::random_access_range<NonSimpleForwardSizedView>);
241 static_assert(!simple_view<NonSimpleForwardSizedView>);
242 
243 using ForwardSizedNonCommon = BasicView<forward_sized_iterator<>, sized_sentinel<forward_sized_iterator<>>>;
244 static_assert(std::ranges::forward_range<ForwardSizedNonCommon>);
245 static_assert(std::ranges::sized_range<ForwardSizedNonCommon>);
246 static_assert(!std::ranges::common_range<ForwardSizedNonCommon>);
247 static_assert(!std::ranges::random_access_range<ForwardSizedNonCommon>);
248 static_assert(simple_view<ForwardSizedNonCommon>);
249 
250 using NonSimpleForwardSizedNonCommon =
251     BasicView<forward_sized_iterator<const int*>, sized_sentinel<forward_sized_iterator<const int*>>,
252               forward_sized_iterator<int*>, sized_sentinel<forward_sized_iterator<int*>>>;
253 static_assert(std::ranges::forward_range<NonSimpleForwardSizedNonCommon>);
254 static_assert(std::ranges::sized_range<NonSimpleForwardSizedNonCommon>);
255 static_assert(!std::ranges::common_range<NonSimpleForwardSizedNonCommon>);
256 static_assert(!std::ranges::random_access_range<NonSimpleForwardSizedNonCommon>);
257 static_assert(!simple_view<NonSimpleForwardSizedNonCommon>);
258 
259 struct SizedRandomAccessView : IntBufferView {
260   using IntBufferView::IntBufferView;
261   using iterator = random_access_iterator<int*>;
262 
beginSizedRandomAccessView263   constexpr auto begin() const { return iterator(buffer_); }
endSizedRandomAccessView264   constexpr auto end() const { return sized_sentinel<iterator>(iterator(buffer_ + size_)); }
265 
decltypeSizedRandomAccessView266   constexpr decltype(auto) operator[](std::size_t n) const { return *(begin() + n); }
267 };
268 static_assert(std::ranges::view<SizedRandomAccessView>);
269 static_assert(std::ranges::random_access_range<SizedRandomAccessView>);
270 static_assert(std::ranges::sized_range<SizedRandomAccessView>);
271 
272 using NonSizedRandomAccessView =
273     BasicView<random_access_iterator<int*>, sentinel_wrapper<random_access_iterator<int*>>>;
274 static_assert(!std::ranges::contiguous_range<NonSizedRandomAccessView>);
275 static_assert(std::ranges::random_access_range<SizedRandomAccessView>);
276 static_assert(!std::ranges::common_range<NonSizedRandomAccessView>);
277 static_assert(!std::ranges::sized_range<NonSizedRandomAccessView>);
278 static_assert(simple_view<NonSizedRandomAccessView>);
279 
280 using NonSimpleNonSizedRandomAccessView =
281     BasicView<random_access_iterator<const int*>, sentinel_wrapper<random_access_iterator<const int*>>,
282               random_access_iterator<int*>, sentinel_wrapper<random_access_iterator<int*>> >;
283 static_assert(!std::ranges::contiguous_range<NonSimpleNonSizedRandomAccessView>);
284 static_assert(std::ranges::random_access_range<NonSimpleNonSizedRandomAccessView>);
285 static_assert(!std::ranges::common_range<NonSimpleNonSizedRandomAccessView>);
286 static_assert(!std::ranges::sized_range<NonSimpleNonSizedRandomAccessView>);
287 static_assert(!simple_view<NonSimpleNonSizedRandomAccessView>);
288 
289 using ContiguousCommonView = BasicView<int*>;
290 static_assert(std::ranges::contiguous_range<ContiguousCommonView>);
291 static_assert(std::ranges::common_range<ContiguousCommonView>);
292 static_assert(std::ranges::sized_range<ContiguousCommonView>);
293 
294 using ContiguousNonCommonView = BasicView<int*, sentinel_wrapper<int*>>;
295 static_assert(std::ranges::contiguous_range<ContiguousNonCommonView>);
296 static_assert(!std::ranges::common_range<ContiguousNonCommonView>);
297 static_assert(!std::ranges::sized_range<ContiguousNonCommonView>);
298 
299 using ContiguousNonCommonSized = BasicView<int*, sized_sentinel<int*>>;
300 
301 static_assert(std::ranges::contiguous_range<ContiguousNonCommonSized>);
302 static_assert(!std::ranges::common_range<ContiguousNonCommonSized>);
303 static_assert(std::ranges::sized_range<ContiguousNonCommonSized>);
304 
305 using InputCommonView = BasicView<common_input_iterator<int*>>;
306 static_assert(std::ranges::input_range<InputCommonView>);
307 static_assert(!std::ranges::forward_range<InputCommonView>);
308 static_assert(std::ranges::common_range<InputCommonView>);
309 static_assert(simple_view<InputCommonView>);
310 
311 using NonSimpleInputCommonView = BasicView<common_input_iterator<const int*>, common_input_iterator<const int*>,
312                                            common_input_iterator<int*>, common_input_iterator<int*>>;
313 static_assert(std::ranges::input_range<NonSimpleInputCommonView>);
314 static_assert(!std::ranges::forward_range<NonSimpleInputCommonView>);
315 static_assert(std::ranges::common_range<NonSimpleInputCommonView>);
316 static_assert(!simple_view<NonSimpleInputCommonView>);
317 
318 using InputNonCommonView = BasicView<common_input_iterator<int*>, sentinel_wrapper<common_input_iterator<int*>>>;
319 static_assert(std::ranges::input_range<InputNonCommonView>);
320 static_assert(!std::ranges::forward_range<InputNonCommonView>);
321 static_assert(!std::ranges::common_range<InputNonCommonView>);
322 static_assert(simple_view<InputNonCommonView>);
323 
324 using NonSimpleInputNonCommonView =
325     BasicView<common_input_iterator<const int*>, sentinel_wrapper<common_input_iterator<const int*>>,
326               common_input_iterator<int*>, sentinel_wrapper<common_input_iterator<int*>>>;
327 static_assert(std::ranges::input_range<InputNonCommonView>);
328 static_assert(!std::ranges::forward_range<InputNonCommonView>);
329 static_assert(!std::ranges::common_range<InputNonCommonView>);
330 static_assert(!simple_view<NonSimpleInputNonCommonView>);
331 
332 using BidiCommonView = BasicView<bidirectional_iterator<int*>>;
333 static_assert(!std::ranges::sized_range<BidiCommonView>);
334 static_assert(std::ranges::bidirectional_range<BidiCommonView>);
335 static_assert(!std::ranges::random_access_range<BidiCommonView>);
336 static_assert(std::ranges::common_range<BidiCommonView>);
337 static_assert(simple_view<BidiCommonView>);
338 
339 using NonSimpleBidiCommonView = BasicView<bidirectional_iterator<const int*>, bidirectional_iterator<const int*>,
340                                           bidirectional_iterator<int*>, bidirectional_iterator<int*>>;
341 static_assert(!std::ranges::sized_range<NonSimpleBidiCommonView>);
342 static_assert(std::ranges::bidirectional_range<NonSimpleBidiCommonView>);
343 static_assert(!std::ranges::random_access_range<NonSimpleBidiCommonView>);
344 static_assert(std::ranges::common_range<NonSimpleBidiCommonView>);
345 static_assert(!simple_view<NonSimpleBidiCommonView>);
346 
347 struct SizedBidiCommon : BidiCommonView {
348   using BidiCommonView::BidiCommonView;
sizeSizedBidiCommon349   std::size_t size() const { return base(end()) - base(begin()); }
350 };
351 static_assert(std::ranges::sized_range<SizedBidiCommon>);
352 static_assert(std::ranges::bidirectional_range<SizedBidiCommon>);
353 static_assert(!std::ranges::random_access_range<SizedBidiCommon>);
354 static_assert(std::ranges::common_range<SizedBidiCommon>);
355 static_assert(simple_view<SizedBidiCommon>);
356 
357 struct NonSimpleSizedBidiCommon : NonSimpleBidiCommonView {
358   using NonSimpleBidiCommonView::NonSimpleBidiCommonView;
sizeNonSimpleSizedBidiCommon359   std::size_t size() const { return base(end()) - base(begin()); }
360 };
361 static_assert(std::ranges::sized_range<NonSimpleSizedBidiCommon>);
362 static_assert(std::ranges::bidirectional_range<NonSimpleSizedBidiCommon>);
363 static_assert(!std::ranges::random_access_range<NonSimpleSizedBidiCommon>);
364 static_assert(std::ranges::common_range<NonSimpleSizedBidiCommon>);
365 static_assert(!simple_view<NonSimpleSizedBidiCommon>);
366 
367 using BidiNonCommonView = BasicView<bidirectional_iterator<int*>, sentinel_wrapper<bidirectional_iterator<int*>>>;
368 static_assert(!std::ranges::sized_range<BidiNonCommonView>);
369 static_assert(std::ranges::bidirectional_range<BidiNonCommonView>);
370 static_assert(!std::ranges::random_access_range<BidiNonCommonView>);
371 static_assert(!std::ranges::common_range<BidiNonCommonView>);
372 static_assert(simple_view<BidiNonCommonView>);
373 
374 using NonSimpleBidiNonCommonView =
375     BasicView<bidirectional_iterator<const int*>, sentinel_wrapper<bidirectional_iterator<const int*>>,
376               bidirectional_iterator<int*>, sentinel_wrapper<bidirectional_iterator<int*>>>;
377 static_assert(!std::ranges::sized_range<NonSimpleBidiNonCommonView>);
378 static_assert(std::ranges::bidirectional_range<NonSimpleBidiNonCommonView>);
379 static_assert(!std::ranges::random_access_range<NonSimpleBidiNonCommonView>);
380 static_assert(!std::ranges::common_range<NonSimpleBidiNonCommonView>);
381 static_assert(!simple_view<NonSimpleBidiNonCommonView>);
382 
383 using SizedBidiNonCommonView = BasicView<bidirectional_iterator<int*>, sized_sentinel<bidirectional_iterator<int*>>>;
384 static_assert(std::ranges::sized_range<SizedBidiNonCommonView>);
385 static_assert(std::ranges::bidirectional_range<SizedBidiNonCommonView>);
386 static_assert(!std::ranges::random_access_range<SizedBidiNonCommonView>);
387 static_assert(!std::ranges::common_range<SizedBidiNonCommonView>);
388 static_assert(simple_view<SizedBidiNonCommonView>);
389 
390 using NonSimpleSizedBidiNonCommonView =
391     BasicView<bidirectional_iterator<const int*>, sized_sentinel<bidirectional_iterator<const int*>>,
392               bidirectional_iterator<int*>, sized_sentinel<bidirectional_iterator<int*>>>;
393 static_assert(std::ranges::sized_range<NonSimpleSizedBidiNonCommonView>);
394 static_assert(std::ranges::bidirectional_range<NonSimpleSizedBidiNonCommonView>);
395 static_assert(!std::ranges::random_access_range<NonSimpleSizedBidiNonCommonView>);
396 static_assert(!std::ranges::common_range<NonSimpleSizedBidiNonCommonView>);
397 static_assert(!simple_view<NonSimpleSizedBidiNonCommonView>);
398 
399 namespace adltest{
400 struct iter_move_swap_iterator {
401 
402   std::reference_wrapper<int> iter_move_called_times;
403   std::reference_wrapper<int> iter_swap_called_times;
404   int i = 0;
405 
406   using iterator_category = std::input_iterator_tag;
407   using value_type = int;
408   using difference_type = std::intptr_t;
409 
410   constexpr int operator*() const { return i; }
411 
412   constexpr iter_move_swap_iterator& operator++() {
413     ++i;
414     return *this;
415   }
416   constexpr void operator++(int) { ++i; }
417 
418   friend constexpr bool operator==(const iter_move_swap_iterator& x, std::default_sentinel_t) { return x.i == 5; }
419 
iter_moveiter_move_swap_iterator420   friend constexpr int iter_move(iter_move_swap_iterator const& it) {
421     ++it.iter_move_called_times;
422     return it.i;
423   }
iter_swapiter_move_swap_iterator424   friend constexpr void iter_swap(iter_move_swap_iterator const& x, iter_move_swap_iterator const& y) {
425     ++x.iter_swap_called_times;
426     ++y.iter_swap_called_times;
427   }
428 };
429 
430 struct IterMoveSwapRange {
431   int iter_move_called_times = 0;
432   int iter_swap_called_times = 0;
beginIterMoveSwapRange433   constexpr auto begin() { return iter_move_swap_iterator{iter_move_called_times, iter_swap_called_times}; }
endIterMoveSwapRange434   constexpr auto end() const { return std::default_sentinel; }
435 };
436 } // namespace adltest
437 
438 #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_ZIP_TYPES_H
439