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