diff --git a/include/continuable/detail/awaiting.hpp b/include/continuable/detail/awaiting.hpp index 291a3a0..7aeb86e 100644 --- a/include/continuable/detail/awaiting.hpp +++ b/include/continuable/detail/awaiting.hpp @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -57,11 +58,11 @@ struct void_guard_tag {}; template struct result_trait; template <> -struct result_trait> { +struct result_trait> { using expected = util::expected; - static auto wrap() { - return expected(void_guard_tag{}); + static constexpr void_guard_tag wrap() noexcept { + return {}; } static void unwrap(expected&& e) { assert(e.is_value()); @@ -75,9 +76,8 @@ struct result_trait> { static auto wrap(T arg) { return std::move(arg); } - static void unwrap(expected&& e) { + static auto unwrap(expected&& e) { assert(e.is_value()); - (void)e; return std::move(e.get_value()); } }; @@ -89,16 +89,15 @@ struct result_trait> { return std::make_tuple(std::move(first), std::move(second), std::move(rest)...); } - static void unwrap(expected&& e) { + static auto unwrap(expected&& e) { assert(e.is_value()); - (void)e; return std::move(e.get_value()); } }; template -using result_storage_of_t = - result_trait()))>; +using result_trait_t = + result_trait()))>; } // namespace detail /// We import the coroutine handle in our namespace @@ -108,7 +107,7 @@ using std::experimental::coroutine_handle; /// for waiting on a continuable in a stackless coroutine. template class awaitable { - using trait_t = detail::result_trait; + using trait_t = detail::result_trait_t; /// The continuable which is invoked upon suspension Continuable continuable_; @@ -117,6 +116,10 @@ class awaitable { typename trait_t::expected result_; public: + explicit awaitable(Continuable&& continuable) + : continuable_(std::move(continuable)) { + } + /// Since continuables are evaluated lazily we are not /// capable to say whether the resumption will be instantly. bool await_ready() const noexcept { @@ -135,14 +138,15 @@ public: .done(); } + /// Resume the coroutine represented by the handle auto await_resume() noexcept(false) { if (result_) { // When the result was resolved return it - trait_t::unwrap(std::move(result_)); + return trait_t::unwrap(std::move(result_)); } #if defined(CONTINUABLE_WITH_EXCEPTIONS) - std::rethrow_exception(result_.get_error()); + std::rethrow_exception(result_.get_exception()); #else // CONTINUABLE_WITH_EXCEPTIONS // Returning error types in await isn't supported as of now util::trap(); @@ -153,12 +157,12 @@ private: /// Resolve the continuation through the result template void resolve(Args&&... args) { - // ... + result_.set_value(trait_t::wrap(std::forward(args)...)); } /// Resolve the continuation through an error void resolve(types::dispatch_error_tag, types::error_type error) { - // ... + result_.set_exception(std::move(error)); } }; @@ -166,7 +170,7 @@ private: /// the C++ coroutine TS. template auto create_awaiter(T&& continuable) { - return awaitable>{std::forward(continuable)}; + return awaitable>(std::forward(continuable)); } } // namespace awaiting } // namespace detail diff --git a/include/continuable/detail/expected.hpp b/include/continuable/detail/expected.hpp index 2d2fd7f..371ecbd 100644 --- a/include/continuable/detail/expected.hpp +++ b/include/continuable/detail/expected.hpp @@ -240,11 +240,11 @@ public: assert(is_value()); return cast(); } - T& get_exception() noexcept { + types::error_type& get_exception() noexcept { assert(is_exception()); return cast(); } - T const& get_exception() const noexcept { + types::error_type const& get_exception() const noexcept { assert(is_exception()); return cast(); } diff --git a/test/unit-test/test-continuable-await.cpp b/test/unit-test/test-continuable-await.cpp index 2d9c964..634c8f3 100644 --- a/test/unit-test/test-continuable-await.cpp +++ b/test/unit-test/test-continuable-await.cpp @@ -51,11 +51,6 @@ struct coroutine_traits { } // namespace experimental } // namespace std -TYPED_TEST(single_dimension_tests, is_awaitable) { - - {} -} - auto mk() { return cti::make_continuable([](auto&& promise) { // ... @@ -66,7 +61,15 @@ auto mk() { void teststhh() { auto c = mk(); - // co_await std::move(c); + co_await std::move(c); + + co_return; } +TYPED_TEST(single_dimension_tests, is_awaitable) { + + teststhh(); +} + + #endif // CONTINUABLE_HAS_EXPERIMENTAL_COROUTINE