From c5ea0c2c21f69b23530fa5c209703f672a18d8f5 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Sun, 2 Jan 2022 17:32:05 +0000 Subject: [PATCH] Refactor co_generator_t into something a little more comprehensible to me. --- inc/co_generator_t.h | 71 +++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/inc/co_generator_t.h b/inc/co_generator_t.h index 412bebf..e35fd5c 100644 --- a/inc/co_generator_t.h +++ b/inc/co_generator_t.h @@ -8,53 +8,68 @@ namespace EightBit { template -struct co_generator_t final { +class co_generator_t final { +public: + class promise_type; - struct promise_type; - using handle_type = std::coroutine_handle; +private: + using handle_t = std::coroutine_handle; - struct promise_type { + class promise_type final { + private: 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(); } + public: template From> // C++20 concept - std::suspend_always yield_value(From&& from) { + [[nodiscard]] constexpr std::suspend_always yield_value(From&& from) noexcept { value_ = std::forward(from); return {}; } - void return_void() {} + + [[nodiscard]] constexpr std::suspend_always initial_suspend() noexcept { return {}; } + [[nodiscard]] constexpr std::suspend_always final_suspend() noexcept { return {}; } + + [[nodiscard]] constexpr co_generator_t get_return_object() noexcept { + return co_generator_t(handle_t::from_promise(*this)); + } + + constexpr void return_void() {} + + constexpr void unhandled_exception() noexcept { exception_ = std::current_exception(); } + + [[nodiscard]] constexpr auto& value() noexcept { return value_; }; + [[nodiscard]] constexpr auto& exception() noexcept { return exception_; }; }; - 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_); - } + handle_t h_; private: bool full_ = false; - void fill() { + constexpr void fill() { if (!full_) { h_(); - if (h_.promise().exception_) - std::rethrow_exception(h_.promise().exception_); + if (h_.promise().exception()) + std::rethrow_exception(h_.promise().exception()); full_ = true; } } + +public: + co_generator_t(handle_t h) noexcept : h_(h) {} + + ~co_generator_t() noexcept { h_.destroy(); } + + constexpr explicit operator bool() { + fill(); + return !h_.done(); + } + + [[nodiscard]] constexpr T operator()() { + fill(); + full_ = false; + return std::move(h_.promise().value()); + } }; }