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