40
40
#include < optional>
41
41
#include < string>
42
42
43
+ #define DEBUG_LOG 0 // Logs break no-localization CI, set to 1 if needed
44
+
45
+ #ifndef TEST_HAS_NO_EXCEPTIONS
46
+ # define THROW (_ex ) throw _ex;
47
+ #else
48
+ # define THROW (_ex )
49
+ #endif
50
+
43
51
struct my_err : std::exception {};
44
52
45
53
enum test_toggles {
@@ -110,7 +118,7 @@ struct optional_wrapper {
110
118
operator std::optional<T>() {
111
119
if (driver_.toggles (test_toggles::throw_in_convert_optional_wrapper)) {
112
120
driver_.log (test_event::throw_convert_optional_wrapper);
113
- throw my_err ();
121
+ THROW ( my_err () );
114
122
}
115
123
driver_.log (test_event::convert_optional_wrapper);
116
124
return std::move (storage_);
@@ -143,7 +151,7 @@ struct std::coroutine_traits<std::optional<T>, test_driver&, Args...> {
143
151
driver_.log (test_event::return_value, value);
144
152
if (driver_.toggles (test_toggles::throw_in_return_value)) {
145
153
driver_.log (test_event::throw_return_value);
146
- throw my_err ();
154
+ THROW ( my_err () );
147
155
}
148
156
*storagePtr_ = std::move (value);
149
157
}
@@ -169,7 +177,7 @@ struct base_optional_awaitable {
169
177
T await_resume () {
170
178
if (driver_.toggles (test_toggles::throw_in_await_resume)) {
171
179
driver_.log (test_event::throw_await_resume, id_);
172
- throw my_err ();
180
+ THROW ( my_err () );
173
181
}
174
182
driver_.log (test_event::await_resume, id_);
175
183
return std::move (opt_).value ();
@@ -184,7 +192,7 @@ struct base_optional_awaitable {
184
192
assert (promise.storagePtr_ );
185
193
if (driver_.toggles (test_toggles::throw_in_await_suspend_destroy)) {
186
194
driver_.log (test_event::throw_await_suspend_destroy, id_);
187
- throw my_err ();
195
+ THROW ( my_err () );
188
196
}
189
197
driver_.log (test_event::await_suspend_destroy, id_);
190
198
}
@@ -218,20 +226,29 @@ void check_coro_with_driver_for(auto coro_fn) {
218
226
auto old_driver = driver;
219
227
std::optional<T> old_res;
220
228
bool old_threw = false ;
229
+ #ifndef TEST_HAS_NO_EXCEPTIONS
221
230
try {
231
+ #endif
222
232
old_res = coro_fn.template operator ()<old_optional_awaitable<T>, T>(old_driver);
233
+ #ifndef TEST_HAS_NO_EXCEPTIONS
223
234
} catch (const my_err&) {
224
235
old_threw = true ;
225
236
}
237
+ #endif
226
238
auto new_driver = driver;
227
239
std::optional<T> new_res;
228
240
bool new_threw = false ;
241
+ #ifndef TEST_HAS_NO_EXCEPTIONS
229
242
try {
243
+ #endif
230
244
new_res = coro_fn.template operator ()<new_optional_awaitable<T>, T>(new_driver);
245
+ #ifndef TEST_HAS_NO_EXCEPTIONS
231
246
} catch (const my_err&) {
232
247
new_threw = true ;
233
248
}
249
+ #endif
234
250
251
+ #if DEBUG_LOG
235
252
// Print toggle values for debugging
236
253
std::string toggle_info = " Toggles: " ;
237
254
for (int i = 0 ; i <= test_toggles::largest; ++i) {
@@ -241,6 +258,7 @@ void check_coro_with_driver_for(auto coro_fn) {
241
258
}
242
259
toggle_info += " \n " ;
243
260
std::cerr << toggle_info.c_str () << std::endl;
261
+ #endif
244
262
245
263
assert (old_threw == new_threw);
246
264
assert (old_res == new_res);
@@ -282,7 +300,9 @@ std::optional<T> coro_shortcircuits_to_empty(test_driver& driver) {
282
300
}
283
301
284
302
void test_coro_shortcircuits_to_empty () {
303
+ #if DEBUG_LOG
285
304
std::cerr << " test_coro_shortcircuits_to_empty" << std::endl;
305
+ #endif
286
306
check_coro_with_driver ([]<typename Awaitable, typename T>(test_driver& driver) {
287
307
return coro_shortcircuits_to_empty<Awaitable, T>(driver);
288
308
});
@@ -295,7 +315,9 @@ std::optional<T> coro_simple_await(test_driver& driver) {
295
315
}
296
316
297
317
void test_coro_simple_await () {
318
+ #if DEBUG_LOG
298
319
std::cerr << " test_coro_simple_await" << std::endl;
320
+ #endif
299
321
check_coro_with_driver ([]<typename Awaitable, typename T>(test_driver& driver) {
300
322
return coro_simple_await<Awaitable, T>(driver);
301
323
});
@@ -306,37 +328,49 @@ void test_coro_simple_await() {
306
328
307
329
template <typename Awaitable, typename T>
308
330
std::optional<T> coro_catching_shortcircuits_to_empty (test_driver& driver) {
331
+ #ifndef TEST_HAS_NO_EXCEPTIONS
309
332
try {
333
+ #endif
310
334
T n = co_await Awaitable{driver, 1 , std::optional<T>{11 }};
311
335
co_await Awaitable{driver, 2 , std::optional<T>{}}; // return early!
312
336
co_return n + co_await Awaitable{driver, 3 , std::optional<T>{22 }};
337
+ #ifndef TEST_HAS_NO_EXCEPTIONS
313
338
} catch (...) {
314
339
driver.log (test_event::coro_catch);
315
340
throw ;
316
341
}
342
+ #endif
317
343
}
318
344
319
345
void test_coro_catching_shortcircuits_to_empty () {
346
+ #if DEBUG_LOG
320
347
std::cerr << " test_coro_catching_shortcircuits_to_empty" << std::endl;
348
+ #endif
321
349
check_coro_with_driver ([]<typename Awaitable, typename T>(test_driver& driver) {
322
350
return coro_catching_shortcircuits_to_empty<Awaitable, T>(driver);
323
351
});
324
352
}
325
353
326
354
template <typename Awaitable, typename T>
327
355
std::optional<T> coro_catching_simple_await (test_driver& driver) {
356
+ #ifndef TEST_HAS_NO_EXCEPTIONS
328
357
try {
358
+ #endif
329
359
co_return co_await Awaitable{driver, 1 , std::optional<T>{11 }} +
330
360
co_await Awaitable{
331
361
driver, 2 , driver.toggles (dynamic_short_circuit) ? std::optional<T>{} : std::optional<T>{22 }};
362
+ #ifndef TEST_HAS_NO_EXCEPTIONS
332
363
} catch (...) {
333
364
driver.log (test_event::coro_catch);
334
365
throw ;
335
366
}
367
+ #endif
336
368
}
337
369
338
370
void test_coro_catching_simple_await () {
371
+ #if DEBUG_LOG
339
372
std::cerr << " test_coro_catching_simple_await" << std::endl;
373
+ #endif
340
374
check_coro_with_driver ([]<typename Awaitable, typename T>(test_driver& driver) {
341
375
return coro_catching_simple_await<Awaitable, T>(driver);
342
376
});
@@ -354,7 +388,9 @@ std::optional<T> noneliding_coro_shortcircuits_to_empty(test_driver& driver) {
354
388
}
355
389
356
390
void test_noneliding_coro_shortcircuits_to_empty () {
391
+ #if DEBUG_LOG
357
392
std::cerr << " test_noneliding_coro_shortcircuits_to_empty" << std::endl;
393
+ #endif
358
394
check_coro_with_driver ([]<typename Awaitable, typename T>(test_driver& driver) {
359
395
return noneliding_coro_shortcircuits_to_empty<Awaitable, T>(driver);
360
396
});
@@ -368,7 +404,9 @@ std::optional<T> noneliding_coro_simple_await(test_driver& driver) {
368
404
}
369
405
370
406
void test_noneliding_coro_simple_await () {
407
+ #if DEBUG_LOG
371
408
std::cerr << " test_noneliding_coro_simple_await" << std::endl;
409
+ #endif
372
410
check_coro_with_driver ([]<typename Awaitable, typename T>(test_driver& driver) {
373
411
return noneliding_coro_simple_await<Awaitable, T>(driver);
374
412
});
@@ -391,7 +429,9 @@ std::optional<T> outer_coro(test_driver& driver) {
391
429
}
392
430
393
431
void test_nested_coroutines () {
432
+ #if DEBUG_LOG
394
433
std::cerr << " test_nested_coroutines" << std::endl;
434
+ #endif
395
435
check_coro_with_driver ([]<typename Awaitable, typename T>(test_driver& driver) {
396
436
return outer_coro<Awaitable, T>(driver);
397
437
});
0 commit comments