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 // constexpr iterator& operator++();
13 // constexpr void operator++(int);
14 // constexpr iterator operator++(int)
15 // requires ref-is-glvalue && forward_range<Base> &&
16 // forward_range<range_reference_t<Base>>;
17
18 #include <cassert>
19 #include <ranges>
20
21 #include "test_macros.h"
22 #include "../types.h"
23
test()24 constexpr bool test() {
25 // This way if we read past end we'll catch the error.
26 int buffer1[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
27 int dummy = 42;
28 (void) dummy;
29 int buffer2[2][4] = {{9, 10, 11, 12}, {13, 14, 15, 16}};
30
31 // operator++(int);
32 {
33 std::ranges::join_view jv(buffer1);
34 auto iter = jv.begin();
35 for (int i = 1; i < 9; ++i) {
36 assert(*iter++ == i);
37 }
38 }
39
40 {
41 ValueView<int> children[4] = {ValueView(buffer1[0]), ValueView(buffer1[1]), ValueView(buffer2[0]), ValueView(buffer2[1])};
42 std::ranges::join_view jv(ValueView<ValueView<int>>{children});
43 auto iter = jv.begin();
44 for (int i = 1; i < 17; ++i) {
45 assert(*iter == i);
46 iter++;
47 }
48
49 ASSERT_SAME_TYPE(decltype(iter++), void);
50 }
51
52 {
53 std::ranges::join_view jv(buffer1);
54 auto iter = std::next(jv.begin(), 7);
55 assert(*iter++ == 8);
56 assert(iter == jv.end());
57 }
58
59 {
60 int small[2][1] = {{1}, {2}};
61 std::ranges::join_view jv(small);
62 auto iter = jv.begin();
63 for (int i = 1; i < 3; ++i) {
64 assert(*iter++ == i);
65 }
66 }
67
68 // Has some empty children.
69 {
70 CopyableChild children[4] = {CopyableChild(buffer1[0], 4), CopyableChild(buffer1[1], 0), CopyableChild(buffer2[0], 1), CopyableChild(buffer2[1], 0)};
71 auto jv = std::ranges::join_view(ParentView(children));
72 auto iter = jv.begin();
73 assert(*iter == 1); iter++;
74 assert(*iter == 2); iter++;
75 assert(*iter == 3); iter++;
76 assert(*iter == 4); iter++;
77 assert(*iter == 9); iter++;
78 assert(iter == jv.end());
79 }
80
81 // Parent is empty.
82 {
83 CopyableChild children[4] = {CopyableChild(buffer1[0]), CopyableChild(buffer1[1]), CopyableChild(buffer2[0]), CopyableChild(buffer2[1])};
84 std::ranges::join_view jv(ParentView(children, 0));
85 assert(jv.begin() == jv.end());
86 }
87
88 // Parent size is one.
89 {
90 CopyableChild children[1] = {CopyableChild(buffer1[0])};
91 std::ranges::join_view jv(ParentView(children, 1));
92 auto iter = jv.begin();
93 assert(*iter == 1); iter++;
94 assert(*iter == 2); iter++;
95 assert(*iter == 3); iter++;
96 assert(*iter == 4); iter++;
97 assert(iter == jv.end());
98 }
99
100 // Parent and child size is one.
101 {
102 CopyableChild children[1] = {CopyableChild(buffer1[0], 1)};
103 std::ranges::join_view jv(ParentView(children, 1));
104 auto iter = jv.begin();
105 assert(*iter == 1); iter++;
106 assert(iter == jv.end());
107 }
108
109 // Parent size is one child is empty
110 {
111 CopyableChild children[1] = {CopyableChild(buffer1[0], 0)};
112 std::ranges::join_view jv(ParentView(children, 1));
113 assert(jv.begin() == jv.end());
114 }
115
116 // Has all empty children.
117 {
118 CopyableChild children[4] = {CopyableChild(buffer1[0], 0), CopyableChild(buffer1[1], 0), CopyableChild(buffer2[0], 0), CopyableChild(buffer2[1], 0)};
119 auto jv = std::ranges::join_view(ParentView(children));
120 assert(jv.begin() == jv.end());
121 }
122
123 // First child is empty, others are not.
124 {
125 CopyableChild children[4] = {CopyableChild(buffer1[0], 4), CopyableChild(buffer1[1], 0), CopyableChild(buffer2[0], 0), CopyableChild(buffer2[1], 0)};
126 auto jv = std::ranges::join_view(ParentView(children));
127 auto iter = jv.begin();
128 assert(*iter == 1); iter++;
129 assert(*iter == 2); iter++;
130 assert(*iter == 3); iter++;
131 assert(*iter == 4); iter++;
132 assert(iter == jv.end());
133 }
134
135 // Last child is empty, others are not.
136 {
137 CopyableChild children[4] = {CopyableChild(buffer1[0], 4), CopyableChild(buffer1[1], 4), CopyableChild(buffer2[0], 4), CopyableChild(buffer2[1], 0)};
138 auto jv = std::ranges::join_view(ParentView(children));
139 auto iter = jv.begin();
140 for (int i = 1; i < 13; ++i) {
141 assert(*iter == i);
142 iter++;
143 }
144 }
145
146 // operator++();
147 {
148 std::ranges::join_view jv(buffer1);
149 auto iter = jv.begin();
150 for (int i = 2; i < 9; ++i) {
151 assert(*++iter == i);
152 }
153 }
154
155 {
156 ValueView<int> children[4] = {ValueView(buffer1[0]), ValueView(buffer1[1]), ValueView(buffer2[0]), ValueView(buffer2[1])};
157 std::ranges::join_view jv(ValueView<ValueView<int>>{children});
158 auto iter = jv.begin();
159 for (int i = 2; i < 17; ++i) {
160 assert(*++iter == i);
161 }
162
163 ASSERT_SAME_TYPE(decltype(++iter), decltype(iter)&);
164 }
165
166 {
167 // check return value
168 std::ranges::join_view jv(buffer1);
169 auto iter = jv.begin();
170 using iterator = decltype(iter);
171
172 decltype(auto) iter2 = ++iter;
173 static_assert(std::is_same_v<decltype(iter2), iterator&>);
174 assert(&iter2 == &iter);
175
176 std::same_as<iterator> decltype(auto) iter3 = iter++;
177 assert(std::next(iter3) == iter);
178 }
179
180 {
181 // !ref-is-glvalue
182 BidiCommonInner inners[2] = {buffer1[0], buffer1[1]};
183 InnerRValue<BidiCommonOuter<BidiCommonInner>> outer{inners};
184 std::ranges::join_view jv(outer);
185 auto iter = jv.begin();
186 static_assert(std::is_void_v<decltype(iter++)>);
187 }
188
189 {
190 // !forward_range<Base>
191 BufferView<int*> inners[2] = {buffer1[0], buffer1[1]};
192 using Outer = SimpleInputCommonOuter<BufferView<int*>>;
193 std::ranges::join_view jv{Outer(inners)};
194 auto iter = jv.begin();
195 static_assert(std::is_void_v<decltype(iter++)>);
196 }
197
198 {
199 // !forward_range<range_reference_t<Base>>
200 InputCommonInner inners[1] = {buffer1[0]};
201 std::ranges::join_view jv{inners};
202 auto iter = jv.begin();
203 static_assert(std::is_void_v<decltype(iter++)>);
204 }
205
206 return true;
207 }
208
main(int,char **)209 int main(int, char**) {
210 test();
211 static_assert(test());
212
213 return 0;
214 }
215