1 | // RUN: %libomp-cxx20-compile-and-run | FileCheck %s --match-full-lines |
2 | |
3 | #ifndef HEADER |
4 | #define |
5 | |
6 | #include <cstdlib> |
7 | #include <cstdarg> |
8 | #include <cstdio> |
9 | #include <vector> |
10 | |
11 | struct Reporter { |
12 | const char *name; |
13 | |
14 | Reporter(const char *name) : name(name) { print(msg: "ctor" ); } |
15 | |
16 | Reporter() : name("<anon>" ) { print(msg: "ctor" ); } |
17 | |
18 | Reporter(const Reporter &that) : name(that.name) { print(msg: "copy ctor" ); } |
19 | |
20 | Reporter(Reporter &&that) : name(that.name) { print(msg: "move ctor" ); } |
21 | |
22 | ~Reporter() { print(msg: "dtor" ); } |
23 | |
24 | const Reporter &operator=(const Reporter &that) { |
25 | print(msg: "copy assign" ); |
26 | this->name = that.name; |
27 | return *this; |
28 | } |
29 | |
30 | const Reporter &operator=(Reporter &&that) { |
31 | print(msg: "move assign" ); |
32 | this->name = that.name; |
33 | return *this; |
34 | } |
35 | |
36 | struct Iterator { |
37 | const Reporter *owner; |
38 | int pos; |
39 | |
40 | Iterator(const Reporter *owner, int pos) : owner(owner), pos(pos) {} |
41 | |
42 | Iterator(const Iterator &that) : owner(that.owner), pos(that.pos) { |
43 | owner->print(msg: "iterator copy ctor" ); |
44 | } |
45 | |
46 | Iterator(Iterator &&that) : owner(that.owner), pos(that.pos) { |
47 | owner->print(msg: "iterator move ctor" ); |
48 | } |
49 | |
50 | ~Iterator() { owner->print(msg: "iterator dtor" ); } |
51 | |
52 | const Iterator &operator=(const Iterator &that) { |
53 | owner->print(msg: "iterator copy assign" ); |
54 | this->owner = that.owner; |
55 | this->pos = that.pos; |
56 | return *this; |
57 | } |
58 | |
59 | const Iterator &operator=(Iterator &&that) { |
60 | owner->print(msg: "iterator move assign" ); |
61 | this->owner = that.owner; |
62 | this->pos = that.pos; |
63 | return *this; |
64 | } |
65 | |
66 | bool operator==(const Iterator &that) const { |
67 | owner->print(msg: "iterator %d == %d" , 2 - this->pos, 2 - that.pos); |
68 | return this->pos == that.pos; |
69 | } |
70 | |
71 | Iterator &operator++() { |
72 | owner->print(msg: "iterator prefix ++" ); |
73 | pos -= 1; |
74 | return *this; |
75 | } |
76 | |
77 | Iterator operator++(int) { |
78 | owner->print(msg: "iterator postfix ++" ); |
79 | auto result = *this; |
80 | pos -= 1; |
81 | return result; |
82 | } |
83 | |
84 | int operator*() const { |
85 | int result = 2 - pos; |
86 | owner->print(msg: "iterator deref: %i" , result); |
87 | return result; |
88 | } |
89 | |
90 | size_t operator-(const Iterator &that) const { |
91 | int result = (2 - this->pos) - (2 - that.pos); |
92 | owner->print(msg: "iterator distance: %d" , result); |
93 | return result; |
94 | } |
95 | |
96 | Iterator operator+(int steps) const { |
97 | owner->print(msg: "iterator advance: %i += %i" , 2 - this->pos, steps); |
98 | return Iterator(owner, pos - steps); |
99 | } |
100 | }; |
101 | |
102 | Iterator begin() const { |
103 | print(msg: "begin()" ); |
104 | return Iterator(this, 2); |
105 | } |
106 | |
107 | Iterator end() const { |
108 | print(msg: "end()" ); |
109 | return Iterator(this, -1); |
110 | } |
111 | |
112 | void print(const char *msg, ...) const { |
113 | va_list args; |
114 | va_start(args, msg); |
115 | printf(format: "[%s] " , name); |
116 | vprintf(format: msg, arg: args); |
117 | printf(format: "\n" ); |
118 | va_end(args); |
119 | } |
120 | }; |
121 | |
122 | int main() { |
123 | printf(format: "do\n" ); |
124 | #pragma omp parallel for collapse(3) num_threads(1) |
125 | for (int i = 0; i < 2; ++i) |
126 | #pragma omp interchange |
127 | for (Reporter c{"C" }; auto &&v : Reporter("A" )) |
128 | for (Reporter d{"D" }; auto &&w : Reporter("B" )) |
129 | for (int k = 0; k < 2; ++k) |
130 | printf("i=%d v=%d w=%d k=%d\n" , i, v, w, k); |
131 | printf(format: "done\n" ); |
132 | return EXIT_SUCCESS; |
133 | } |
134 | |
135 | #endif /* HEADER */ |
136 | |
137 | // CHECK: do |
138 | // CHECK-NEXT: [C] ctor |
139 | // CHECK-NEXT: [A] ctor |
140 | // CHECK-NEXT: [A] end() |
141 | // CHECK-NEXT: [A] begin() |
142 | // CHECK-NEXT: [A] begin() |
143 | // CHECK-NEXT: [A] iterator distance: 3 |
144 | // CHECK-NEXT: [D] ctor |
145 | // CHECK-NEXT: [B] ctor |
146 | // CHECK-NEXT: [B] end() |
147 | // CHECK-NEXT: [B] begin() |
148 | // CHECK-NEXT: [B] begin() |
149 | // CHECK-NEXT: [B] iterator distance: 3 |
150 | // CHECK-NEXT: [B] iterator advance: 0 += 0 |
151 | // CHECK-NEXT: [B] iterator move assign |
152 | // CHECK-NEXT: [B] iterator deref: 0 |
153 | // CHECK-NEXT: [A] iterator advance: 0 += 0 |
154 | // CHECK-NEXT: [A] iterator move assign |
155 | // CHECK-NEXT: [A] iterator deref: 0 |
156 | // CHECK-NEXT: i=0 v=0 w=0 k=0 |
157 | // CHECK-NEXT: i=0 v=0 w=0 k=1 |
158 | // CHECK-NEXT: [A] iterator dtor |
159 | // CHECK-NEXT: [B] iterator dtor |
160 | // CHECK-NEXT: [B] iterator advance: 0 += 0 |
161 | // CHECK-NEXT: [B] iterator move assign |
162 | // CHECK-NEXT: [B] iterator deref: 0 |
163 | // CHECK-NEXT: [A] iterator advance: 0 += 1 |
164 | // CHECK-NEXT: [A] iterator move assign |
165 | // CHECK-NEXT: [A] iterator deref: 1 |
166 | // CHECK-NEXT: i=0 v=1 w=0 k=0 |
167 | // CHECK-NEXT: i=0 v=1 w=0 k=1 |
168 | // CHECK-NEXT: [A] iterator dtor |
169 | // CHECK-NEXT: [B] iterator dtor |
170 | // CHECK-NEXT: [B] iterator advance: 0 += 0 |
171 | // CHECK-NEXT: [B] iterator move assign |
172 | // CHECK-NEXT: [B] iterator deref: 0 |
173 | // CHECK-NEXT: [A] iterator advance: 0 += 2 |
174 | // CHECK-NEXT: [A] iterator move assign |
175 | // CHECK-NEXT: [A] iterator deref: 2 |
176 | // CHECK-NEXT: i=0 v=2 w=0 k=0 |
177 | // CHECK-NEXT: i=0 v=2 w=0 k=1 |
178 | // CHECK-NEXT: [A] iterator dtor |
179 | // CHECK-NEXT: [B] iterator dtor |
180 | // CHECK-NEXT: [B] iterator advance: 0 += 1 |
181 | // CHECK-NEXT: [B] iterator move assign |
182 | // CHECK-NEXT: [B] iterator deref: 1 |
183 | // CHECK-NEXT: [A] iterator advance: 0 += 0 |
184 | // CHECK-NEXT: [A] iterator move assign |
185 | // CHECK-NEXT: [A] iterator deref: 0 |
186 | // CHECK-NEXT: i=0 v=0 w=1 k=0 |
187 | // CHECK-NEXT: i=0 v=0 w=1 k=1 |
188 | // CHECK-NEXT: [A] iterator dtor |
189 | // CHECK-NEXT: [B] iterator dtor |
190 | // CHECK-NEXT: [B] iterator advance: 0 += 1 |
191 | // CHECK-NEXT: [B] iterator move assign |
192 | // CHECK-NEXT: [B] iterator deref: 1 |
193 | // CHECK-NEXT: [A] iterator advance: 0 += 1 |
194 | // CHECK-NEXT: [A] iterator move assign |
195 | // CHECK-NEXT: [A] iterator deref: 1 |
196 | // CHECK-NEXT: i=0 v=1 w=1 k=0 |
197 | // CHECK-NEXT: i=0 v=1 w=1 k=1 |
198 | // CHECK-NEXT: [A] iterator dtor |
199 | // CHECK-NEXT: [B] iterator dtor |
200 | // CHECK-NEXT: [B] iterator advance: 0 += 1 |
201 | // CHECK-NEXT: [B] iterator move assign |
202 | // CHECK-NEXT: [B] iterator deref: 1 |
203 | // CHECK-NEXT: [A] iterator advance: 0 += 2 |
204 | // CHECK-NEXT: [A] iterator move assign |
205 | // CHECK-NEXT: [A] iterator deref: 2 |
206 | // CHECK-NEXT: i=0 v=2 w=1 k=0 |
207 | // CHECK-NEXT: i=0 v=2 w=1 k=1 |
208 | // CHECK-NEXT: [A] iterator dtor |
209 | // CHECK-NEXT: [B] iterator dtor |
210 | // CHECK-NEXT: [B] iterator advance: 0 += 2 |
211 | // CHECK-NEXT: [B] iterator move assign |
212 | // CHECK-NEXT: [B] iterator deref: 2 |
213 | // CHECK-NEXT: [A] iterator advance: 0 += 0 |
214 | // CHECK-NEXT: [A] iterator move assign |
215 | // CHECK-NEXT: [A] iterator deref: 0 |
216 | // CHECK-NEXT: i=0 v=0 w=2 k=0 |
217 | // CHECK-NEXT: i=0 v=0 w=2 k=1 |
218 | // CHECK-NEXT: [A] iterator dtor |
219 | // CHECK-NEXT: [B] iterator dtor |
220 | // CHECK-NEXT: [B] iterator advance: 0 += 2 |
221 | // CHECK-NEXT: [B] iterator move assign |
222 | // CHECK-NEXT: [B] iterator deref: 2 |
223 | // CHECK-NEXT: [A] iterator advance: 0 += 1 |
224 | // CHECK-NEXT: [A] iterator move assign |
225 | // CHECK-NEXT: [A] iterator deref: 1 |
226 | // CHECK-NEXT: i=0 v=1 w=2 k=0 |
227 | // CHECK-NEXT: i=0 v=1 w=2 k=1 |
228 | // CHECK-NEXT: [A] iterator dtor |
229 | // CHECK-NEXT: [B] iterator dtor |
230 | // CHECK-NEXT: [B] iterator advance: 0 += 2 |
231 | // CHECK-NEXT: [B] iterator move assign |
232 | // CHECK-NEXT: [B] iterator deref: 2 |
233 | // CHECK-NEXT: [A] iterator advance: 0 += 2 |
234 | // CHECK-NEXT: [A] iterator move assign |
235 | // CHECK-NEXT: [A] iterator deref: 2 |
236 | // CHECK-NEXT: i=0 v=2 w=2 k=0 |
237 | // CHECK-NEXT: i=0 v=2 w=2 k=1 |
238 | // CHECK-NEXT: [A] iterator dtor |
239 | // CHECK-NEXT: [B] iterator dtor |
240 | // CHECK-NEXT: [B] iterator advance: 0 += 0 |
241 | // CHECK-NEXT: [B] iterator move assign |
242 | // CHECK-NEXT: [B] iterator deref: 0 |
243 | // CHECK-NEXT: [A] iterator advance: 0 += 0 |
244 | // CHECK-NEXT: [A] iterator move assign |
245 | // CHECK-NEXT: [A] iterator deref: 0 |
246 | // CHECK-NEXT: i=1 v=0 w=0 k=0 |
247 | // CHECK-NEXT: i=1 v=0 w=0 k=1 |
248 | // CHECK-NEXT: [A] iterator dtor |
249 | // CHECK-NEXT: [B] iterator dtor |
250 | // CHECK-NEXT: [B] iterator advance: 0 += 0 |
251 | // CHECK-NEXT: [B] iterator move assign |
252 | // CHECK-NEXT: [B] iterator deref: 0 |
253 | // CHECK-NEXT: [A] iterator advance: 0 += 1 |
254 | // CHECK-NEXT: [A] iterator move assign |
255 | // CHECK-NEXT: [A] iterator deref: 1 |
256 | // CHECK-NEXT: i=1 v=1 w=0 k=0 |
257 | // CHECK-NEXT: i=1 v=1 w=0 k=1 |
258 | // CHECK-NEXT: [A] iterator dtor |
259 | // CHECK-NEXT: [B] iterator dtor |
260 | // CHECK-NEXT: [B] iterator advance: 0 += 0 |
261 | // CHECK-NEXT: [B] iterator move assign |
262 | // CHECK-NEXT: [B] iterator deref: 0 |
263 | // CHECK-NEXT: [A] iterator advance: 0 += 2 |
264 | // CHECK-NEXT: [A] iterator move assign |
265 | // CHECK-NEXT: [A] iterator deref: 2 |
266 | // CHECK-NEXT: i=1 v=2 w=0 k=0 |
267 | // CHECK-NEXT: i=1 v=2 w=0 k=1 |
268 | // CHECK-NEXT: [A] iterator dtor |
269 | // CHECK-NEXT: [B] iterator dtor |
270 | // CHECK-NEXT: [B] iterator advance: 0 += 1 |
271 | // CHECK-NEXT: [B] iterator move assign |
272 | // CHECK-NEXT: [B] iterator deref: 1 |
273 | // CHECK-NEXT: [A] iterator advance: 0 += 0 |
274 | // CHECK-NEXT: [A] iterator move assign |
275 | // CHECK-NEXT: [A] iterator deref: 0 |
276 | // CHECK-NEXT: i=1 v=0 w=1 k=0 |
277 | // CHECK-NEXT: i=1 v=0 w=1 k=1 |
278 | // CHECK-NEXT: [A] iterator dtor |
279 | // CHECK-NEXT: [B] iterator dtor |
280 | // CHECK-NEXT: [B] iterator advance: 0 += 1 |
281 | // CHECK-NEXT: [B] iterator move assign |
282 | // CHECK-NEXT: [B] iterator deref: 1 |
283 | // CHECK-NEXT: [A] iterator advance: 0 += 1 |
284 | // CHECK-NEXT: [A] iterator move assign |
285 | // CHECK-NEXT: [A] iterator deref: 1 |
286 | // CHECK-NEXT: i=1 v=1 w=1 k=0 |
287 | // CHECK-NEXT: i=1 v=1 w=1 k=1 |
288 | // CHECK-NEXT: [A] iterator dtor |
289 | // CHECK-NEXT: [B] iterator dtor |
290 | // CHECK-NEXT: [B] iterator advance: 0 += 1 |
291 | // CHECK-NEXT: [B] iterator move assign |
292 | // CHECK-NEXT: [B] iterator deref: 1 |
293 | // CHECK-NEXT: [A] iterator advance: 0 += 2 |
294 | // CHECK-NEXT: [A] iterator move assign |
295 | // CHECK-NEXT: [A] iterator deref: 2 |
296 | // CHECK-NEXT: i=1 v=2 w=1 k=0 |
297 | // CHECK-NEXT: i=1 v=2 w=1 k=1 |
298 | // CHECK-NEXT: [A] iterator dtor |
299 | // CHECK-NEXT: [B] iterator dtor |
300 | // CHECK-NEXT: [B] iterator advance: 0 += 2 |
301 | // CHECK-NEXT: [B] iterator move assign |
302 | // CHECK-NEXT: [B] iterator deref: 2 |
303 | // CHECK-NEXT: [A] iterator advance: 0 += 0 |
304 | // CHECK-NEXT: [A] iterator move assign |
305 | // CHECK-NEXT: [A] iterator deref: 0 |
306 | // CHECK-NEXT: i=1 v=0 w=2 k=0 |
307 | // CHECK-NEXT: i=1 v=0 w=2 k=1 |
308 | // CHECK-NEXT: [A] iterator dtor |
309 | // CHECK-NEXT: [B] iterator dtor |
310 | // CHECK-NEXT: [B] iterator advance: 0 += 2 |
311 | // CHECK-NEXT: [B] iterator move assign |
312 | // CHECK-NEXT: [B] iterator deref: 2 |
313 | // CHECK-NEXT: [A] iterator advance: 0 += 1 |
314 | // CHECK-NEXT: [A] iterator move assign |
315 | // CHECK-NEXT: [A] iterator deref: 1 |
316 | // CHECK-NEXT: i=1 v=1 w=2 k=0 |
317 | // CHECK-NEXT: i=1 v=1 w=2 k=1 |
318 | // CHECK-NEXT: [A] iterator dtor |
319 | // CHECK-NEXT: [B] iterator dtor |
320 | // CHECK-NEXT: [B] iterator advance: 0 += 2 |
321 | // CHECK-NEXT: [B] iterator move assign |
322 | // CHECK-NEXT: [B] iterator deref: 2 |
323 | // CHECK-NEXT: [A] iterator advance: 0 += 2 |
324 | // CHECK-NEXT: [A] iterator move assign |
325 | // CHECK-NEXT: [A] iterator deref: 2 |
326 | // CHECK-NEXT: i=1 v=2 w=2 k=0 |
327 | // CHECK-NEXT: i=1 v=2 w=2 k=1 |
328 | // CHECK-NEXT: [A] iterator dtor |
329 | // CHECK-NEXT: [B] iterator dtor |
330 | // CHECK-NEXT: [B] iterator dtor |
331 | // CHECK-NEXT: [B] iterator dtor |
332 | // CHECK-NEXT: [B] iterator dtor |
333 | // CHECK-NEXT: [B] dtor |
334 | // CHECK-NEXT: [D] dtor |
335 | // CHECK-NEXT: [A] iterator dtor |
336 | // CHECK-NEXT: [A] iterator dtor |
337 | // CHECK-NEXT: [A] iterator dtor |
338 | // CHECK-NEXT: [A] dtor |
339 | // CHECK-NEXT: [C] dtor |
340 | // CHECK-NEXT: done |
341 | |