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
11 // common_iterator& operator++();
12 // decltype(auto) operator++(int);
13
14 #include <iterator>
15 #include <cassert>
16
17 #include "test_macros.h"
18 #include "types.h"
19
20 struct Incomplete;
21
test()22 void test() {
23 // Reference: http://eel.is/c++draft/iterators.common#common.iter.nav-5
24 // Case 2: can-reference
25 {
26 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
27 auto iter1 = simple_iterator<int*>(buffer);
28 auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
29 auto commonSent1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(sentinel_type<int*>{buffer + 8});
30
31 assert(*(commonIter1++) == 1);
32 assert(*commonIter1 == 2);
33 assert(*(++commonIter1) == 3);
34 assert(*commonIter1 == 3);
35
36 for (auto i = 3; commonIter1 != commonSent1; ++i) {
37 assert(*(commonIter1++) == i);
38 }
39 assert(commonIter1 == commonSent1);
40 }
41
42 // Case 2: can-reference
43 {
44 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
45 auto iter1 = value_iterator<int*>(buffer);
46 auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
47 auto commonSent1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(sentinel_type<int*>{buffer + 8});
48
49 assert(*(commonIter1++) == 1);
50 assert(*commonIter1 == 2);
51 assert(*(++commonIter1) == 3);
52 assert(*commonIter1 == 3);
53
54 for (auto i = 3; commonIter1 != commonSent1; ++i) {
55 assert(*(commonIter1++) == i);
56 }
57 assert(commonIter1 == commonSent1);
58 }
59
60 // Case 3: postfix-proxy
61 {
62 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
63 auto iter1 = void_plus_plus_iterator<int*>(buffer);
64 auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
65 auto commonSent1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(sentinel_type<int*>{buffer + 8});
66
67 assert(*(commonIter1++) == 1);
68 assert(*commonIter1 == 2);
69 assert(*(++commonIter1) == 3);
70 assert(*commonIter1 == 3);
71
72 for (auto i = 3; commonIter1 != commonSent1; ++i) {
73 assert(*(commonIter1++) == i);
74 }
75 assert(commonIter1 == commonSent1);
76 }
77
78 // Case 2: where this is not referencable or move constructible
79 {
80 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
81 auto iter1 = value_type_not_move_constructible_iterator<int*>(buffer);
82 auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
83 auto commonSent1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(sentinel_type<int*>{buffer + 8});
84
85 commonIter1++;
86 ASSERT_SAME_TYPE(decltype(commonIter1++), void);
87 assert(*commonIter1 == 2);
88 assert(*(++commonIter1) == 3);
89 assert(*commonIter1 == 3);
90
91 for (auto i = 3; commonIter1 != commonSent1; ++i) {
92 assert(*commonIter1 == i);
93 commonIter1++;
94 }
95 assert(commonIter1 == commonSent1);
96 }
97
98 // Case 2: can-reference
99 {
100 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
101 auto iter1 = cpp17_input_iterator<int*>(buffer);
102 auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
103 auto commonSent1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(sentinel_type<int*>{buffer + 8});
104
105 assert(*(commonIter1++) == 1);
106 assert(*commonIter1 == 2);
107 assert(*(++commonIter1) == 3);
108 assert(*commonIter1 == 3);
109
110 for (auto i = 3; commonIter1 != commonSent1; ++i) {
111 assert(*(commonIter1++) == i);
112 }
113 assert(commonIter1 == commonSent1);
114 }
115
116 // Case 1: forward_iterator
117 {
118 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
119 auto iter1 = forward_iterator<int*>(buffer);
120 auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
121 auto commonSent1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(sentinel_type<int*>{buffer + 8});
122
123 assert(*(commonIter1++) == 1);
124 assert(*commonIter1 == 2);
125 assert(*(++commonIter1) == 3);
126 assert(*commonIter1 == 3);
127
128 for (auto i = 3; commonIter1 != commonSent1; ++i) {
129 assert(*(commonIter1++) == i);
130 }
131 assert(commonIter1 == commonSent1);
132 }
133
134 // Case 1: forward_iterator
135 {
136 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
137 auto iter1 = random_access_iterator<int*>(buffer);
138 auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
139 auto commonSent1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(sentinel_type<int*>{buffer + 8});
140
141 assert(*(commonIter1++) == 1);
142 assert(*commonIter1 == 2);
143 assert(*(++commonIter1) == 3);
144 assert(*commonIter1 == 3);
145
146 for (auto i = 3; commonIter1 != commonSent1; ++i) {
147 assert(*(commonIter1++) == i);
148 }
149 assert(commonIter1 == commonSent1);
150 }
151
152 // Increment a common_iterator<cpp17_output_iterator>: iter_value_t is not always valid for
153 // output iterators (it isn't for our test cpp17_output_iterator). This is worth testing
154 // because it gets tricky when we define operator++(int).
155 {
156 int buffer[] = {0, 1, 2, 3, 4};
157 using Common = std::common_iterator<cpp17_output_iterator<int*>, sentinel_type<int*>>;
158 auto iter = Common(cpp17_output_iterator<int*>(buffer));
159 auto sent = Common(sentinel_type<int*>{buffer + 5});
160
161 *iter++ = 90;
162 assert(buffer[0] == 90);
163
164 *iter = 91;
165 assert(buffer[1] == 91);
166
167 *++iter = 92;
168 assert(buffer[2] == 92);
169
170 iter++;
171 iter++;
172 assert(iter != sent);
173 iter++;
174 assert(iter == sent);
175 }
176 }
177
main(int,char **)178 int main(int, char**) {
179 test();
180
181 return 0;
182 }
183