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 | bool operator!=(const Iterator &that) const { |
72 | owner->print(msg: "iterator %d != %d" , 2 - this->pos, 2 - that.pos); |
73 | return this->pos != that.pos; |
74 | } |
75 | |
76 | Iterator &operator++() { |
77 | owner->print(msg: "iterator prefix ++" ); |
78 | pos -= 1; |
79 | return *this; |
80 | } |
81 | |
82 | Iterator operator++(int) { |
83 | owner->print(msg: "iterator postfix ++" ); |
84 | auto result = *this; |
85 | pos -= 1; |
86 | return result; |
87 | } |
88 | |
89 | int operator*() const { |
90 | int result = 2 - pos; |
91 | owner->print(msg: "iterator deref: %i" , result); |
92 | return result; |
93 | } |
94 | |
95 | size_t operator-(const Iterator &that) const { |
96 | int result = (2 - this->pos) - (2 - that.pos); |
97 | owner->print(msg: "iterator distance: %d" , result); |
98 | return result; |
99 | } |
100 | |
101 | Iterator operator+(int steps) const { |
102 | owner->print(msg: "iterator advance: %i += %i" , 2 - this->pos, steps); |
103 | return Iterator(owner, pos - steps); |
104 | } |
105 | |
106 | void print(const char *msg) const { owner->print(msg); } |
107 | }; |
108 | |
109 | Iterator begin() const { |
110 | print(msg: "begin()" ); |
111 | return Iterator(this, 2); |
112 | } |
113 | |
114 | Iterator end() const { |
115 | print(msg: "end()" ); |
116 | return Iterator(this, -1); |
117 | } |
118 | |
119 | void print(const char *msg, ...) const { |
120 | va_list args; |
121 | va_start(args, msg); |
122 | printf(format: "[%s] " , name); |
123 | vprintf(format: msg, arg: args); |
124 | printf(format: "\n" ); |
125 | va_end(args); |
126 | } |
127 | }; |
128 | |
129 | int main() { |
130 | printf(format: "do\n" ); |
131 | #pragma omp unroll partial(2) |
132 | for (Reporter c{"init-stmt" }; auto &&v : Reporter("range" )) |
133 | printf(format: "v=%d\n" , v); |
134 | printf(format: "done\n" ); |
135 | return EXIT_SUCCESS; |
136 | } |
137 | |
138 | #endif /* HEADER */ |
139 | |
140 | // CHECK: do |
141 | // CHECK-NEXT: [init-stmt] ctor |
142 | // CHECK-NEXT: [range] ctor |
143 | // CHECK-NEXT: [range] begin() |
144 | // CHECK-NEXT: [range] end() |
145 | // CHECK-NEXT: [range] iterator 0 != 3 |
146 | // CHECK-NEXT: [range] iterator deref: 0 |
147 | // CHECK-NEXT: v=0 |
148 | // CHECK-NEXT: [range] iterator prefix ++ |
149 | // CHECK-NEXT: [range] iterator 1 != 3 |
150 | // CHECK-NEXT: [range] iterator deref: 1 |
151 | // CHECK-NEXT: v=1 |
152 | // CHECK-NEXT: [range] iterator prefix ++ |
153 | // CHECK-NEXT: [range] iterator 2 != 3 |
154 | // CHECK-NEXT: [range] iterator deref: 2 |
155 | // CHECK-NEXT: v=2 |
156 | // CHECK-NEXT: [range] iterator prefix ++ |
157 | // CHECK-NEXT: [range] iterator 3 != 3 |
158 | // CHECK-NEXT: [range] iterator dtor |
159 | // CHECK-NEXT: [range] iterator dtor |
160 | // CHECK-NEXT: [range] dtor |
161 | // CHECK-NEXT: [init-stmt] dtor |
162 | // CHECK-NEXT: done |
163 | |