// // experimental/detail/partial_promise.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2021-2022 Klemens D. Morgenstern // (klemens dot morgenstern at gmx dot net) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef BOOST_ASIO_EXPERIMENTAL_DETAIL_PARTIAL_PROMISE_HPP #define BOOST_ASIO_EXPERIMENTAL_DETAIL_PARTIAL_PROMISE_HPP #include #include #include #if defined(BOOST_ASIO_HAS_STD_COROUTINE) # include #else // defined(BOOST_ASIO_HAS_STD_COROUTINE) # include #endif // defined(BOOST_ASIO_HAS_STD_COROUTINE) namespace boost { namespace asio { namespace experimental { namespace detail { #if defined(BOOST_ASIO_HAS_STD_COROUTINE) using std::coroutine_handle; using std::coroutine_traits; using std::suspend_never; using std::suspend_always; using std::noop_coroutine; #else // defined(BOOST_ASIO_HAS_STD_COROUTINE) using std::experimental::coroutine_handle; using std::experimental::coroutine_traits; using std::experimental::suspend_never; using std::experimental::suspend_always; using std::experimental::noop_coroutine; #endif // defined(BOOST_ASIO_HAS_STD_COROUTINE) struct partial_promise { auto initial_suspend() noexcept { return boost::asio::detail::suspend_always{}; } auto final_suspend() noexcept { struct awaitable_t { partial_promise *p; constexpr bool await_ready() noexcept { return true; } auto await_suspend(boost::asio::detail::coroutine_handle<>) noexcept { p->get_return_object().destroy(); } constexpr void await_resume() noexcept {} }; return awaitable_t{this}; } void return_void() {} coroutine_handle get_return_object() { return coroutine_handle::from_promise(*this); } void unhandled_exception() { assert(false); } }; } // namespace detail } // namespace experimental } // namespace asio } // namespace boost #if defined(BOOST_ASIO_HAS_STD_COROUTINE) namespace std { template struct coroutine_traits< coroutine_handle, Args...> { using promise_type = boost::asio::experimental::detail::partial_promise; }; } // namespace std #else // defined(BOOST_ASIO_HAS_STD_COROUTINE) namespace std { namespace experimental { template struct coroutine_traits< coroutine_handle, Args...> { using promise_type = boost::asio::experimental::detail::partial_promise; }; }} // namespace std::experimental #endif // defined(BOOST_ASIO_HAS_STD_COROUTINE) namespace boost { namespace asio { namespace experimental { namespace detail { template auto post_coroutine(CompletionToken token) noexcept -> coroutine_handle { post(std::move(token)); co_return; } template auto post_coroutine(Executor exec, CompletionToken token) noexcept -> coroutine_handle { post(exec, std::move(token)); co_return; } template auto post_coroutine(Context &ctx, CompletionToken token) noexcept -> coroutine_handle { post(ctx, std::move(token)); co_return; } template auto dispatch_coroutine(CompletionToken token) noexcept -> coroutine_handle { dispatch(std::move(token)); co_return; } template auto dispatch_coroutine(Executor exec, CompletionToken token) noexcept -> coroutine_handle { dispatch(exec, std::move(token)); co_return; } template auto dispatch_coroutine(Context &ctx, CompletionToken token) noexcept -> coroutine_handle { dispatch(ctx, std::move(token)); co_return; } } // namespace detail } // namespace experimental } // namespace asio } // namespace boost #endif // BOOST_ASIO_EXPERIMENTAL_DETAIL_PARTIAL_PROMISE_HPP