2 // experimental/detail/partial_promise.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2021-2022 Klemens D. Morgenstern
6 // (klemens dot morgenstern at gmx dot net)
8 // Distributed under the Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
12 #ifndef BOOST_ASIO_EXPERIMENTAL_DETAIL_PARTIAL_PROMISE_HPP
13 #define BOOST_ASIO_EXPERIMENTAL_DETAIL_PARTIAL_PROMISE_HPP
15 #include <boost/asio/detail/config.hpp>
16 #include <boost/asio/awaitable.hpp>
17 #include <boost/asio/experimental/coro_traits.hpp>
19 #if defined(BOOST_ASIO_HAS_STD_COROUTINE)
21 #else // defined(BOOST_ASIO_HAS_STD_COROUTINE)
22 # include <experimental/coroutine>
23 #endif // defined(BOOST_ASIO_HAS_STD_COROUTINE)
27 namespace experimental {
30 #if defined(BOOST_ASIO_HAS_STD_COROUTINE)
32 using std::coroutine_handle;
33 using std::coroutine_traits;
34 using std::suspend_never;
35 using std::suspend_always;
36 using std::noop_coroutine;
38 #else // defined(BOOST_ASIO_HAS_STD_COROUTINE)
40 using std::experimental::coroutine_handle;
41 using std::experimental::coroutine_traits;
42 using std::experimental::suspend_never;
43 using std::experimental::suspend_always;
44 using std::experimental::noop_coroutine;
46 #endif // defined(BOOST_ASIO_HAS_STD_COROUTINE)
48 struct partial_promise
50 auto initial_suspend() noexcept
52 return boost::asio::detail::suspend_always{};
55 auto final_suspend() noexcept
61 constexpr bool await_ready() noexcept { return true; }
63 auto await_suspend(boost::asio::detail::coroutine_handle<>) noexcept
65 p->get_return_object().destroy();
68 constexpr void await_resume() noexcept {}
71 return awaitable_t{this};
76 coroutine_handle<partial_promise> get_return_object()
78 return coroutine_handle<partial_promise>::from_promise(*this);
81 void unhandled_exception()
88 } // namespace experimental
92 #if defined(BOOST_ASIO_HAS_STD_COROUTINE)
96 template <typename ... Args>
97 struct coroutine_traits<
98 coroutine_handle<boost::asio::experimental::detail::partial_promise>,
101 using promise_type = boost::asio::experimental::detail::partial_promise;
106 #else // defined(BOOST_ASIO_HAS_STD_COROUTINE)
108 namespace std { namespace experimental {
110 template <typename... Args>
111 struct coroutine_traits<
112 coroutine_handle<boost::asio::experimental::detail::partial_promise>,
115 using promise_type = boost::asio::experimental::detail::partial_promise;
118 }} // namespace std::experimental
120 #endif // defined(BOOST_ASIO_HAS_STD_COROUTINE)
124 namespace experimental {
127 template <typename CompletionToken>
128 auto post_coroutine(CompletionToken token) noexcept
129 -> coroutine_handle<partial_promise>
131 post(std::move(token));
135 template <execution::executor Executor, typename CompletionToken>
136 auto post_coroutine(Executor exec, CompletionToken token) noexcept
137 -> coroutine_handle<partial_promise>
139 post(exec, std::move(token));
143 template <detail::execution_context Context, typename CompletionToken>
144 auto post_coroutine(Context &ctx, CompletionToken token) noexcept
145 -> coroutine_handle<partial_promise>
147 post(ctx, std::move(token));
151 template <typename CompletionToken>
152 auto dispatch_coroutine(CompletionToken token) noexcept
153 -> coroutine_handle<partial_promise>
155 dispatch(std::move(token));
159 template <execution::executor Executor, typename CompletionToken>
160 auto dispatch_coroutine(Executor exec, CompletionToken token) noexcept
161 -> coroutine_handle<partial_promise>
163 dispatch(exec, std::move(token));
167 template <detail::execution_context Context, typename CompletionToken>
168 auto dispatch_coroutine(Context &ctx, CompletionToken token) noexcept
169 -> coroutine_handle<partial_promise>
171 dispatch(ctx, std::move(token));
175 } // namespace detail
176 } // namespace experimental
180 #endif // BOOST_ASIO_EXPERIMENTAL_DETAIL_PARTIAL_PROMISE_HPP