From 058efff580a749f2d87631354c0421c6e057834a Mon Sep 17 00:00:00 2001 From: q66 Date: Sat, 11 Mar 2017 03:53:41 +0100 Subject: [PATCH] coroutine cleanups --- ostd/coroutine.hh | 83 +++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/ostd/coroutine.hh b/ostd/coroutine.hh index e74626a..6129e83 100644 --- a/ostd/coroutine.hh +++ b/ostd/coroutine.hh @@ -99,16 +99,31 @@ namespace detail { template struct coro_types { using yield_type = std::tuple; + + static yield_type get(std::tuple...> &args) { + return std::move(args); + } }; template struct coro_types { using yield_type = A; + + static yield_type get(std::tuple> &args) { + return std::forward(std::get<0>(args)); + } }; template struct coro_types { using yield_type = std::pair; + + static yield_type get(std::tuple, arg_wrapper> &args) { + return std::make_pair( + std::forward(std::get<0>(args)), + std::forward(std::get<1>(args)) + ); + } }; template<> @@ -130,15 +145,15 @@ namespace detail { template coro_args get_args(std::index_sequence) { - if constexpr(sizeof...(A) == 0) { - return; - } else if constexpr(sizeof...(A) == 1) { - return std::forward(std::get<0>(p_args)); - } else if constexpr(sizeof...(A) == 2) { - return std::make_pair(std::forward(std::get(p_args))...); - } else { - return std::move(p_args); - } + return coro_types::get(p_args); + } + + void set_args(A ...args) { + p_args = std::make_tuple(arg_wrapper(std::forward(args))...); + } + + R get_result() { + return std::forward(p_result); } template @@ -149,12 +164,6 @@ namespace detail { )); } - R call(A ...args) { - p_args = std::make_tuple(arg_wrapper(std::forward(args))...); - coroutine_context::call(); - return std::forward(p_result); - } - void swap(coro_base &other) { using std::swap; swap(p_args, other.p_args); @@ -175,16 +184,17 @@ namespace detail { template void get_args(std::index_sequence) {} + void set_args() {} + + R get_result() { + return std::forward(p_result); + } + template void call_helper(Y &&yielder, F &func, std::index_sequence) { p_result = std::forward(func(std::forward(yielder))); } - R call() { - coroutine_context::call(); - return std::forward(this->p_result); - } - void swap(coro_base &other) { using std::swap; swap(p_result, other.p_result); @@ -202,17 +212,15 @@ namespace detail { template coro_args get_args(std::index_sequence) { - if constexpr(sizeof...(A) == 0) { - return; - } else if constexpr(sizeof...(A) == 1) { - return std::forward(std::get<0>(p_args)); - } else if constexpr(sizeof...(A) == 2) { - return std::make_pair(std::forward(std::get(p_args))...); - } else { - return std::move(p_args); - } + return coro_types::get(p_args); } + void set_args(A ...args) { + p_args = std::make_tuple(arg_wrapper(std::forward(args))...); + } + + void get_result() {} + template void call_helper(Y &&yielder, F &func, std::index_sequence) { func( @@ -221,11 +229,6 @@ namespace detail { ); } - void call(A ...args) { - p_args = std::make_tuple(arg_wrapper(std::forward(args))...); - coroutine_context::call(); - } - void swap(coro_base &other) { using std::swap; swap(p_args, other.p_args); @@ -244,15 +247,15 @@ namespace detail { template void get_args(std::index_sequence) {} + void set_args() {} + + void get_result() {} + template void call_helper(Y &&yielder, F &func, std::index_sequence) { func(std::forward(yielder)); } - void call() { - coroutine_context::call(); - } - void swap(coro_base &other) { coroutine_context::swap(other); } @@ -373,7 +376,9 @@ public: if (this->p_state == detail::coroutine_context::state::TERM) { throw coroutine_error{"dead coroutine"}; } - return this->call(std::forward(args)...); + this->set_args(std::forward(args)...); + detail::coroutine_context::call(); + return this->get_result(); } R operator()(A ...args) {