|
| 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