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 iterator& operator++();
13 // constexpr void operator++(int);
14 // constexpr iterator operator++(int) requires all_forward<Const, Views...>;
15 
16 #include <array>
17 #include <cassert>
18 #include <ranges>
19 #include <tuple>
20 
21 #include "../types.h"
22 
23 struct InputRange : IntBufferView {
24   using IntBufferView::IntBufferView;
25   using iterator = cpp20_input_iterator<int*>;
beginInputRange26   constexpr iterator begin() const { return iterator(buffer_); }
endInputRange27   constexpr sentinel_wrapper<iterator> end() const { return sentinel_wrapper<iterator>(iterator(buffer_ + size_)); }
28 };
29 
test()30 constexpr bool test() {
31   std::array a{1, 2, 3, 4};
32   std::array b{4.1, 3.2, 4.3};
33   {
34     // random/contiguous
35     std::ranges::zip_view v(a, b, std::views::iota(0, 5));
36     auto it = v.begin();
37     using Iter = decltype(it);
38 
39     assert(&(std::get<0>(*it)) == &(a[0]));
40     assert(&(std::get<1>(*it)) == &(b[0]));
41     assert(std::get<2>(*it) == 0);
42 
43     static_assert(std::is_same_v<decltype(++it), Iter&>);
44 
45     auto& it_ref = ++it;
46     assert(&it_ref == &it);
47 
48     assert(&(std::get<0>(*it)) == &(a[1]));
49     assert(&(std::get<1>(*it)) == &(b[1]));
50     assert(std::get<2>(*it) == 1);
51 
52     static_assert(std::is_same_v<decltype(it++), Iter>);
53     auto original = it;
54     auto copy = it++;
55     assert(original == copy);
56     assert(&(std::get<0>(*it)) == &(a[2]));
57     assert(&(std::get<1>(*it)) == &(b[2]));
58     assert(std::get<2>(*it) == 2);
59   }
60 
61   {
62     //  bidi
63     int buffer[2] = {1, 2};
64 
65     std::ranges::zip_view v(BidiCommonView{buffer});
66     auto it = v.begin();
67     using Iter = decltype(it);
68 
69     assert(&(std::get<0>(*it)) == &(buffer[0]));
70 
71     static_assert(std::is_same_v<decltype(++it), Iter&>);
72     auto& it_ref = ++it;
73     assert(&it_ref == &it);
74     assert(&(std::get<0>(*it)) == &(buffer[1]));
75 
76     static_assert(std::is_same_v<decltype(it++), Iter>);
77     auto original = it;
78     auto copy = it++;
79     assert(copy == original);
80     assert(&(std::get<0>(*it)) == &(buffer[2]));
81   }
82 
83   {
84     //  forward
85     int buffer[2] = {1, 2};
86 
87     std::ranges::zip_view v(ForwardSizedView{buffer});
88     auto it = v.begin();
89     using Iter = decltype(it);
90 
91     assert(&(std::get<0>(*it)) == &(buffer[0]));
92 
93     static_assert(std::is_same_v<decltype(++it), Iter&>);
94     auto& it_ref = ++it;
95     assert(&it_ref == &it);
96     assert(&(std::get<0>(*it)) == &(buffer[1]));
97 
98     static_assert(std::is_same_v<decltype(it++), Iter>);
99     auto original = it;
100     auto copy = it++;
101     assert(copy == original);
102     assert(&(std::get<0>(*it)) == &(buffer[2]));
103   }
104 
105   {
106     // all input+
107     int buffer[3] = {4, 5, 6};
108     std::ranges::zip_view v(a, InputRange{buffer});
109     auto it = v.begin();
110     using Iter = decltype(it);
111 
112     assert(&(std::get<0>(*it)) == &(a[0]));
113     assert(&(std::get<1>(*it)) == &(buffer[0]));
114 
115     static_assert(std::is_same_v<decltype(++it), Iter&>);
116     auto& it_ref = ++it;
117     assert(&it_ref == &it);
118     assert(&(std::get<0>(*it)) == &(a[1]));
119     assert(&(std::get<1>(*it)) == &(buffer[1]));
120 
121     static_assert(std::is_same_v<decltype(it++), void>);
122     it++;
123     assert(&(std::get<0>(*it)) == &(a[2]));
124     assert(&(std::get<1>(*it)) == &(buffer[2]));
125   }
126 
127   return true;
128 }
129 
main(int,char **)130 int main(int, char**) {
131   test();
132   static_assert(test());
133 
134   return 0;
135 }
136