|
| 1 | +#if defined(USE_LIBSTDCPP) |
| 2 | +#include <bits/c++config.h> |
| 3 | +// glibc++ >= 11 and c++20 |
| 4 | +#if defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 11 |
1 | 5 | #include <coroutine>
|
| 6 | +#define HAS_CPP_COROUTINES 1 |
| 7 | +#endif |
| 8 | +#endif |
| 9 | + |
| 10 | +// libc++ always has 'coroutine' feature. |
| 11 | +#if defined(USE_LIBCPP) |
| 12 | +#include <coroutine> |
| 13 | +#define HAS_CPP_COROUTINES 1 |
| 14 | +#endif |
2 | 15 |
|
3 | 16 | bool is_implementation_supported() {
|
4 |
| -#ifdef _GLIBCXX_RELEASE |
5 |
| - return _GLIBCXX_RELEASE >= 11; |
6 |
| -#else |
| 17 | +#ifdef HAS_CPP_COROUTINES |
7 | 18 | return true;
|
| 19 | +#else |
| 20 | + return false; |
8 | 21 | #endif
|
9 | 22 | }
|
10 | 23 |
|
| 24 | +#ifdef HAS_CPP_COROUTINES |
11 | 25 | // `int_generator` is a stripped down, minimal coroutine generator
|
12 | 26 | // type.
|
13 | 27 | struct int_generator {
|
@@ -39,13 +53,20 @@ int_generator my_generator_func() { co_yield 42; }
|
39 | 53 | // a place to reliably set a breakpoint on.
|
40 | 54 | void empty_function_so_we_can_set_a_breakpoint() {}
|
41 | 55 |
|
| 56 | +#endif // HAS_CPP_COROUTINES |
| 57 | + |
42 | 58 | int main() {
|
43 | 59 | bool is_supported = is_implementation_supported();
|
| 60 | +#ifdef HAS_CPP_COROUTINES |
44 | 61 | int_generator gen = my_generator_func();
|
45 | 62 | std::coroutine_handle<> type_erased_hdl = gen.hdl;
|
46 | 63 | std::coroutine_handle<int> incorrectly_typed_hdl =
|
47 | 64 | std::coroutine_handle<int>::from_address(gen.hdl.address());
|
48 | 65 | gen.hdl.resume(); // Break at initial_suspend
|
49 | 66 | gen.hdl.resume(); // Break after co_yield
|
50 | 67 | empty_function_so_we_can_set_a_breakpoint(); // Break at final_suspend
|
| 68 | + return 0; |
| 69 | +#else |
| 70 | + return 0; // Break at initial_suspend |
| 71 | +#endif // HAS_CPP_COROUTINES |
51 | 72 | }
|
0 commit comments