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 | void print(const char *msg) const { owner->print(msg); } |
102 | }; |
103 | |
104 | Iterator begin() const { |
105 | print(msg: "begin()" ); |
106 | return Iterator(this, 2); |
107 | } |
108 | |
109 | Iterator end() const { |
110 | print(msg: "end()" ); |
111 | return Iterator(this, -1); |
112 | } |
113 | |
114 | void print(const char *msg, ...) const { |
115 | va_list args; |
116 | va_start(args, msg); |
117 | printf(format: "[%s] " , name); |
118 | vprintf(format: msg, arg: args); |
119 | printf(format: "\n" ); |
120 | va_end(args); |
121 | } |
122 | }; |
123 | |
124 | int main() { |
125 | printf(format: "do\n" ); |
126 | #pragma omp tile sizes(2, 2) |
127 | for (Reporter c{"C" }; auto &&v : Reporter("A" )) |
128 | for (Reporter d{"D" }; auto &&w : Reporter("B" )) |
129 | printf("v=%d w=%d\n" , v, w); |
130 | printf(format: "done\n" ); |
131 | return EXIT_SUCCESS; |
132 | } |
133 | |
134 | #endif /* HEADER */ |
135 | |
136 | // CHECK: do |
137 | // CHECK-NEXT: [C] ctor |
138 | // CHECK-NEXT: [A] ctor |
139 | // CHECK-NEXT: [A] end() |
140 | // CHECK-NEXT: [A] begin() |
141 | // CHECK-NEXT: [A] begin() |
142 | // CHECK-NEXT: [A] iterator distance: 3 |
143 | // CHECK-NEXT: [D] ctor |
144 | // CHECK-NEXT: [B] ctor |
145 | // CHECK-NEXT: [B] end() |
146 | // CHECK-NEXT: [B] begin() |
147 | // CHECK-NEXT: [B] begin() |
148 | // CHECK-NEXT: [B] iterator distance: 3 |
149 | // CHECK-NEXT: [A] iterator advance: 0 += 0 |
150 | // CHECK-NEXT: [A] iterator move assign |
151 | // CHECK-NEXT: [A] iterator deref: 0 |
152 | // CHECK-NEXT: [B] iterator advance: 0 += 0 |
153 | // CHECK-NEXT: [B] iterator move assign |
154 | // CHECK-NEXT: [B] iterator deref: 0 |
155 | // CHECK-NEXT: v=0 w=0 |
156 | // CHECK-NEXT: [B] iterator dtor |
157 | // CHECK-NEXT: [B] iterator advance: 0 += 1 |
158 | // CHECK-NEXT: [B] iterator move assign |
159 | // CHECK-NEXT: [B] iterator deref: 1 |
160 | // CHECK-NEXT: v=0 w=1 |
161 | // CHECK-NEXT: [B] iterator dtor |
162 | // CHECK-NEXT: [A] iterator dtor |
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: [B] iterator advance: 0 += 0 |
167 | // CHECK-NEXT: [B] iterator move assign |
168 | // CHECK-NEXT: [B] iterator deref: 0 |
169 | // CHECK-NEXT: v=1 w=0 |
170 | // CHECK-NEXT: [B] iterator dtor |
171 | // CHECK-NEXT: [B] iterator advance: 0 += 1 |
172 | // CHECK-NEXT: [B] iterator move assign |
173 | // CHECK-NEXT: [B] iterator deref: 1 |
174 | // CHECK-NEXT: v=1 w=1 |
175 | // CHECK-NEXT: [B] iterator dtor |
176 | // CHECK-NEXT: [A] iterator dtor |
177 | // CHECK-NEXT: [A] iterator advance: 0 += 0 |
178 | // CHECK-NEXT: [A] iterator move assign |
179 | // CHECK-NEXT: [A] iterator deref: 0 |
180 | // CHECK-NEXT: [B] iterator advance: 0 += 2 |
181 | // CHECK-NEXT: [B] iterator move assign |
182 | // CHECK-NEXT: [B] iterator deref: 2 |
183 | // CHECK-NEXT: v=0 w=2 |
184 | // CHECK-NEXT: [B] iterator dtor |
185 | // CHECK-NEXT: [A] iterator dtor |
186 | // CHECK-NEXT: [A] iterator advance: 0 += 1 |
187 | // CHECK-NEXT: [A] iterator move assign |
188 | // CHECK-NEXT: [A] iterator deref: 1 |
189 | // CHECK-NEXT: [B] iterator advance: 0 += 2 |
190 | // CHECK-NEXT: [B] iterator move assign |
191 | // CHECK-NEXT: [B] iterator deref: 2 |
192 | // CHECK-NEXT: v=1 w=2 |
193 | // CHECK-NEXT: [B] iterator dtor |
194 | // CHECK-NEXT: [A] iterator dtor |
195 | // CHECK-NEXT: [A] iterator advance: 0 += 2 |
196 | // CHECK-NEXT: [A] iterator move assign |
197 | // CHECK-NEXT: [A] iterator deref: 2 |
198 | // CHECK-NEXT: [B] iterator advance: 0 += 0 |
199 | // CHECK-NEXT: [B] iterator move assign |
200 | // CHECK-NEXT: [B] iterator deref: 0 |
201 | // CHECK-NEXT: v=2 w=0 |
202 | // CHECK-NEXT: [B] iterator dtor |
203 | // CHECK-NEXT: [B] iterator advance: 0 += 1 |
204 | // CHECK-NEXT: [B] iterator move assign |
205 | // CHECK-NEXT: [B] iterator deref: 1 |
206 | // CHECK-NEXT: v=2 w=1 |
207 | // CHECK-NEXT: [B] iterator dtor |
208 | // CHECK-NEXT: [A] iterator dtor |
209 | // CHECK-NEXT: [A] iterator advance: 0 += 2 |
210 | // CHECK-NEXT: [A] iterator move assign |
211 | // CHECK-NEXT: [A] iterator deref: 2 |
212 | // CHECK-NEXT: [B] iterator advance: 0 += 2 |
213 | // CHECK-NEXT: [B] iterator move assign |
214 | // CHECK-NEXT: [B] iterator deref: 2 |
215 | // CHECK-NEXT: v=2 w=2 |
216 | // CHECK-NEXT: [B] iterator dtor |
217 | // CHECK-NEXT: [A] iterator dtor |
218 | // CHECK-NEXT: [B] iterator dtor |
219 | // CHECK-NEXT: [B] iterator dtor |
220 | // CHECK-NEXT: [B] iterator dtor |
221 | // CHECK-NEXT: [B] dtor |
222 | // CHECK-NEXT: [D] dtor |
223 | // CHECK-NEXT: [A] iterator dtor |
224 | // CHECK-NEXT: [A] iterator dtor |
225 | // CHECK-NEXT: [A] iterator dtor |
226 | // CHECK-NEXT: [A] dtor |
227 | // CHECK-NEXT: [C] dtor |
228 | // CHECK-NEXT: done |
229 | |