#pragma once #include #include // from https://www.scs.stanford.edu/~dm/blog/c++-coroutines.html template struct co_generator_t final { struct promise_type; using handle_type = std::coroutine_handle; struct promise_type { T value_; std::exception_ptr exception_; co_generator_t get_return_object() { return co_generator_t(handle_type::from_promise(*this)); } std::suspend_always initial_suspend() { return {}; } std::suspend_always final_suspend() noexcept { return {}; } void unhandled_exception() { exception_ = std::current_exception(); } template From> // C++20 concept std::suspend_always yield_value(From&& from) { value_ = std::forward(from); return {}; } void return_void() {} }; handle_type h_; co_generator_t(handle_type h) : h_(h) {} ~co_generator_t() { h_.destroy(); } explicit operator bool() { fill(); return !h_.done(); } T operator()() { fill(); full_ = false; return std::move(h_.promise().value_); } private: bool full_ = false; void fill() { if (!full_) { h_(); if (h_.promise().exception_) std::rethrow_exception(h_.promise().exception_); full_ = true; } } };