]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/experimental/scopeguard/exit.cc
libstdc++: Remove dg-options "-std=gnu++20" from remaining tests
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / scopeguard / exit.cc
1 // { dg-do run { target c++20 } }
2
3 #include <experimental/scope>
4 #include <testsuite_hooks.h>
5
6 int da_funk = 0;
7 void funk() { ++da_funk; }
8
9 struct ThrowingCopy
10 {
11 ThrowingCopy() = default;
12 ThrowingCopy(ThrowingCopy&&) noexcept(false) { VERIFY(false); }
13 ThrowingCopy(const ThrowingCopy&) { if (nocopy) throw 1; }
14
15 void operator()() const noexcept { ++counter; }
16
17 static ThrowingCopy create() noexcept { nocopy = false; return {}; }
18
19 static bool nocopy;
20 static int counter;
21 };
22
23 bool ThrowingCopy::nocopy = false;
24 int ThrowingCopy::counter = 0;
25
26 void
27 test_exit()
28 {
29 using std::experimental::scope_exit;
30
31 int counter = 0;
32 auto d = [&counter] () { ++counter; };
33
34 {
35 scope_exit e(d);
36 }
37 VERIFY( counter == 1 );
38
39 try
40 {
41 scope_exit e(d);
42 throw 1;
43 }
44 catch (int)
45 {
46 }
47 VERIFY( counter == 2 );
48
49 {
50 scope_exit e(d);
51 scope_exit e2(std::move(e));
52 }
53 VERIFY( counter == 3 );
54
55 {
56 scope_exit e(d);
57 e.release();
58 }
59 VERIFY( counter == 3 );
60
61 try
62 {
63 scope_exit e(d);
64 e.release();
65 throw 1;
66 }
67 catch (int)
68 {
69 }
70 VERIFY( counter == 3 );
71
72 {
73 da_funk = 0;
74 scope_exit<void(&)()> e(funk);
75 }
76 VERIFY( da_funk == 1 );
77
78 static_assert(!std::is_move_assignable_v<scope_exit<void(*)()>>);
79 static_assert(!std::is_move_assignable_v<scope_exit<void(&)()>>);
80 static_assert(!std::is_move_assignable_v<scope_exit<ThrowingCopy>>);
81 static_assert(!std::is_move_assignable_v<scope_exit<decltype(d)>>);
82
83 {
84 ThrowingCopy::counter = 0;
85 try
86 {
87 scope_exit<ThrowingCopy> e(ThrowingCopy::create());
88 ThrowingCopy::nocopy = true;
89 scope_exit<ThrowingCopy> e2(std::move(e));
90 VERIFY(false);
91 }
92 catch (int)
93 {
94 }
95 VERIFY( ThrowingCopy::counter == 1 );
96
97 scope_exit<ThrowingCopy> e(ThrowingCopy::create());
98 try
99 {
100 ThrowingCopy::nocopy = true;
101 scope_exit<ThrowingCopy> e2(std::move(e));
102 VERIFY(false);
103 }
104 catch (int)
105 {
106 }
107 VERIFY( ThrowingCopy::counter == 1 );
108 }
109 VERIFY( ThrowingCopy::counter == 2 );
110 }
111
112 void
113 test_fail()
114 {
115 using std::experimental::scope_fail;
116
117 int counter = 0;
118 auto d = [&counter] () { ++counter; };
119
120 {
121 scope_fail f(d);
122 }
123 VERIFY( counter == 0 );
124
125 try
126 {
127 scope_fail f(d);
128 throw 1;
129 }
130 catch (int)
131 {
132 }
133 VERIFY( counter == 1 );
134
135 {
136 scope_fail f(d);
137 f.release();
138 }
139 VERIFY( counter == 1 );
140
141 try
142 {
143 scope_fail f(d);
144 scope_fail f2(std::move(f));
145 throw 1;
146 }
147 catch(int)
148 {
149 }
150 VERIFY( counter == 2 );
151
152 try
153 {
154 scope_fail f(d);
155 f.release();
156 throw 1;
157 }
158 catch (int)
159 {
160 }
161 VERIFY( counter == 2 );
162
163 try
164 {
165 da_funk = 0;
166 scope_fail<void(&)()> e(funk);
167 throw 1;
168 }
169 catch (int)
170 {
171 }
172 VERIFY( da_funk == 1 );
173
174 static_assert(!std::is_move_assignable_v<scope_fail<void(*)()>>);
175 static_assert(!std::is_move_assignable_v<scope_fail<void(&)()>>);
176 static_assert(!std::is_move_assignable_v<scope_fail<ThrowingCopy>>);
177 static_assert(!std::is_move_assignable_v<scope_fail<decltype(d)>>);
178
179 {
180 ThrowingCopy::counter = 0;
181 try
182 {
183 scope_fail<ThrowingCopy> f(ThrowingCopy::create());
184 ThrowingCopy::nocopy = true;
185 scope_fail<ThrowingCopy> f2(std::move(f));
186 VERIFY(false);
187 }
188 catch (int)
189 {
190 }
191 VERIFY( ThrowingCopy::counter == 1 );
192
193 scope_fail<ThrowingCopy> f(ThrowingCopy::create());
194 try
195 {
196 ThrowingCopy::nocopy = true;
197 scope_fail<ThrowingCopy> f2(std::move(f));
198 VERIFY(false);
199 }
200 catch (int)
201 {
202 }
203 VERIFY( ThrowingCopy::counter == 1 );
204 }
205 VERIFY( ThrowingCopy::counter == 1 );
206 }
207
208 void
209 test_success()
210 {
211 using std::experimental::scope_success;
212
213 int counter = 0;
214 auto d = [&counter] () { ++counter; };
215
216 {
217 scope_success s(d);
218 }
219 VERIFY( counter == 1 );
220
221 try
222 {
223 scope_success s(d);
224 throw 1;
225 }
226 catch (int)
227 {
228 }
229 VERIFY( counter == 1 );
230
231 {
232 scope_success s(d);
233 scope_success s2(std::move(s));
234 }
235 VERIFY( counter == 2 );
236
237 {
238 scope_success s(d);
239 s.release();
240 }
241 VERIFY( counter == 2 );
242
243 try
244 {
245 scope_success s(d);
246 s.release();
247 throw 1;
248 }
249 catch (int)
250 {
251 }
252 VERIFY( counter == 2 );
253
254 {
255 da_funk = 0;
256 scope_success<void(&)()> e(funk);
257 }
258 VERIFY( da_funk == 1 );
259
260 static_assert(!std::is_move_assignable_v<scope_success<void(*)()>>);
261 static_assert(!std::is_move_assignable_v<scope_success<void(&)()>>);
262 static_assert(!std::is_move_assignable_v<scope_success<ThrowingCopy>>);
263 static_assert(!std::is_move_assignable_v<scope_success<decltype(d)>>);
264
265 {
266 ThrowingCopy::counter = 0;
267 try
268 {
269 scope_success<ThrowingCopy> s(ThrowingCopy::create());
270 ThrowingCopy::nocopy = true;
271 scope_success<ThrowingCopy> s2(std::move(s));
272 VERIFY(false);
273 }
274 catch (int)
275 {
276 }
277 VERIFY( ThrowingCopy::counter == 0 );
278
279 scope_success<ThrowingCopy> s(ThrowingCopy::create());
280 try
281 {
282 ThrowingCopy::nocopy = true;
283 scope_success<ThrowingCopy> s2(std::move(s));
284 VERIFY(false);
285 }
286 catch (int)
287 {
288 }
289 VERIFY( ThrowingCopy::counter == 0 );
290 }
291 VERIFY( ThrowingCopy::counter == 1 );
292 }
293
294 int main()
295 {
296 test_exit();
297 test_fail();
298 test_success();
299 }