Aside from cppcoro, the standard library offers two more trivial awaitables: suspend_never and suspend_always. By looking at them, we can see how to implement our own awaitables when needed:
struct suspend_never { constexpr bool await_ready() const noexcept { return true; } constexpr void await_suspend(coroutine_handle<>) const noexcept {} constexpr void await_resume() const noexcept {} }; struct suspend_always { constexpr bool await_ready() const noexcept { return false; } constexpr void await_suspend(coroutine_handle<>) const noexcept {} constexpr void await_resume() const noexcept {} };
When typing co_await, you tell the compiler to first call the awaiter's await_ready(). If it says the awaiter is ready by returning true, await_resume() will get called. The return type of await_resume() should be the type the awaiter is actually producing. If the awaiter was not ready, the program will instead...