commit b7acadc829f6d835137fd72de76689db9c9a91e7 parent a792edfe4c25b783dd7d55c1cc547ee62b4c265f Author: Henry Wilson <henry@henryandlizzy.uk> Date: Mon, 6 Feb 2023 21:54:43 +0000 coro-throwing: Test type that can handle throwing coroutine body Diffstat:
M | .gitignore | | | 1 | + |
A | src/coro-throwing.cpp | | | 98 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 99 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore @@ -13,6 +13,7 @@ /cobs /coro-poll /coro-round-robin +/coro-throwing /coro-timer-dispatch /coro-unconditional-dispatch /crc-table diff --git a/src/coro-throwing.cpp b/src/coro-throwing.cpp @@ -0,0 +1,98 @@ +#include <coroutine> +#include <iostream> +#include <optional> +#include <stdexcept> + +using namespace std; + +struct coroutine +{ + struct promise_type; + coroutine_handle<> h; + ~coroutine() + { + if (not h.done()) + h.destroy(); + } +}; + +struct coroutine::promise_type +{ + coroutine get_return_object() noexcept { return {coroutine_handle<promise_type>::from_promise(*this)}; } + suspend_never initial_suspend() noexcept { return {}; } + suspend_always final_suspend() noexcept { return {}; } + void return_void() noexcept {} + void unhandled_exception() { throw; } +}; + + +struct awaitable : suspend_always +{ + coroutine_handle<> suspended; + void await_suspend(coroutine_handle<> h) + { + suspended = h; + } +} awaitable; + +coroutine no_throw() +{ + cerr << "no_throw()\n"; + co_return; +} + + +coroutine initial_throw() +{ + cerr << "\ninitial_throw()\n"; + throw runtime_error("initial_throw"); + co_return; +} + +coroutine resume_throw() +{ + cerr << "\nresume_throw()\n"; + for (;;) + { + co_await awaitable; + cerr << "resume_throw() RESUMED\n"; + throw runtime_error("resume_throw"); + } +} + +coroutine resume_nothrow() +{ + cerr << "\nresume_nothrow()\n"; + for (;;) + { + co_await awaitable; + cerr << "resume_nothrow() RESUMED\n"; + } +} + +int main() +{ + try { + { + no_throw(); + } + [[maybe_unused]] auto coro = initial_throw(); + } catch (exception& e) + { + cerr << "Exception caught: " << e.what() << endl; + } + + try { + { + [[maybe_unused]] auto coro = resume_nothrow(); + cerr << " suspend OK\n"; + awaitable.suspended.resume(); + } + [[maybe_unused]] auto coro = resume_throw(); + cerr << " suspend OK\n"; + awaitable.suspended.resume(); + } catch (exception& e) + { + cerr << "Exception caught: " << e.what() << endl; + } +}