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-no-concepts
11 // UNSUPPORTED: libcpp-has-no-incomplete-ranges
12 
13 // constexpr iterator& operator++();
14 // constexpr void operator++(int);
15 // constexpr iterator operator++(int);
16 
17 #include <cassert>
18 #include <ranges>
19 
20 #include "test_macros.h"
21 #include "../types.h"
22 
23 constexpr bool test() {
24   // This way if we read past end we'll catch the error.
25   int buffer1[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
26   int dummy = 42;
27   (void) dummy;
28   int buffer2[2][4] = {{9, 10, 11, 12}, {13, 14, 15, 16}};
29 
30   // operator++(int);
31   {
32     std::ranges::join_view jv(buffer1);
33     auto iter = jv.begin();
34     for (int i = 1; i < 9; ++i) {
35       assert(*iter++ == i);
36     }
37   }
38   {
39     ValueView<int> children[4] = {ValueView(buffer1[0]), ValueView(buffer1[1]), ValueView(buffer2[0]), ValueView(buffer2[1])};
40     std::ranges::join_view jv(ValueView<ValueView<int>>{children});
41     auto iter = jv.begin();
42     for (int i = 1; i < 17; ++i) {
43       assert(*iter == i);
44       iter++;
45     }
46 
47     ASSERT_SAME_TYPE(decltype(iter++), void);
48   }
49   {
50     std::ranges::join_view jv(buffer1);
51     auto iter = std::next(jv.begin(), 7);
52     assert(*iter++ == 8);
53     assert(iter == jv.end());
54   }
55   {
56     int small[2][1] = {{1}, {2}};
57     std::ranges::join_view jv(small);
58     auto iter = jv.begin();
59     for (int i = 1; i < 3; ++i) {
60       assert(*iter++ == i);
61     }
62   }
63   // Has some empty children.
64   {
65     CopyableChild children[4] = {CopyableChild(buffer1[0], 4), CopyableChild(buffer1[1], 0), CopyableChild(buffer2[0], 1), CopyableChild(buffer2[1], 0)};
66     auto jv = std::ranges::join_view(ParentView(children));
67     auto iter = jv.begin();
68     assert(*iter == 1); iter++;
69     assert(*iter == 2); iter++;
70     assert(*iter == 3); iter++;
71     assert(*iter == 4); iter++;
72     assert(*iter == 9); iter++;
73     assert(iter == jv.end());
74   }
75   // Parent is empty.
76   {
77     CopyableChild children[4] = {CopyableChild(buffer1[0]), CopyableChild(buffer1[1]), CopyableChild(buffer2[0]), CopyableChild(buffer2[1])};
78     std::ranges::join_view jv(ParentView(children, 0));
79     assert(jv.begin() == jv.end());
80   }
81   // Parent size is one.
82   {
83     CopyableChild children[1] = {CopyableChild(buffer1[0])};
84     std::ranges::join_view jv(ParentView(children, 1));
85     auto iter = jv.begin();
86     assert(*iter == 1); iter++;
87     assert(*iter == 2); iter++;
88     assert(*iter == 3); iter++;
89     assert(*iter == 4); iter++;
90     assert(iter == jv.end());
91   }
92   // Parent and child size is one.
93   {
94     CopyableChild children[1] = {CopyableChild(buffer1[0], 1)};
95     std::ranges::join_view jv(ParentView(children, 1));
96     auto iter = jv.begin();
97     assert(*iter == 1); iter++;
98     assert(iter == jv.end());
99   }
100   // Parent size is one child is empty
101   {
102     CopyableChild children[1] = {CopyableChild(buffer1[0], 0)};
103     std::ranges::join_view jv(ParentView(children, 1));
104     assert(jv.begin() == jv.end());
105   }
106   // Has all empty children.
107   {
108     CopyableChild children[4] = {CopyableChild(buffer1[0], 0), CopyableChild(buffer1[1], 0), CopyableChild(buffer2[0], 0), CopyableChild(buffer2[1], 0)};
109     auto jv = std::ranges::join_view(ParentView(children));
110     assert(jv.begin() == jv.end());
111   }
112   // First child is empty, others are not.
113   {
114     CopyableChild children[4] = {CopyableChild(buffer1[0], 4), CopyableChild(buffer1[1], 0), CopyableChild(buffer2[0], 0), CopyableChild(buffer2[1], 0)};
115     auto jv = std::ranges::join_view(ParentView(children));
116     auto iter = jv.begin();
117     assert(*iter == 1); iter++;
118     assert(*iter == 2); iter++;
119     assert(*iter == 3); iter++;
120     assert(*iter == 4); iter++;
121     assert(iter == jv.end());
122   }
123   // Last child is empty, others are not.
124   {
125     CopyableChild children[4] = {CopyableChild(buffer1[0], 4), CopyableChild(buffer1[1], 4), CopyableChild(buffer2[0], 4), CopyableChild(buffer2[1], 0)};
126     auto jv = std::ranges::join_view(ParentView(children));
127     auto iter = jv.begin();
128     for (int i = 1; i < 13; ++i) {
129       assert(*iter == i);
130       iter++;
131     }
132   }
133   // operator++();
134   {
135     std::ranges::join_view jv(buffer1);
136     auto iter = jv.begin();
137     for (int i = 2; i < 9; ++i) {
138       assert(*++iter == i);
139     }
140   }
141   {
142     ValueView<int> children[4] = {ValueView(buffer1[0]), ValueView(buffer1[1]), ValueView(buffer2[0]), ValueView(buffer2[1])};
143     std::ranges::join_view jv(ValueView<ValueView<int>>{children});
144     auto iter = jv.begin();
145     for (int i = 2; i < 17; ++i) {
146       assert(*++iter == i);
147     }
148 
149     ASSERT_SAME_TYPE(decltype(++iter), decltype(iter)&);
150   }
151 
152   return true;
153 }
154 
155 int main(int, char**) {
156   test();
157   static_assert(test());
158 
159   return 0;
160 }
161