diff options
Diffstat (limited to '3rdparty/asio/include/asio/experimental/detail/partial_promise.hpp')
-rw-r--r-- | 3rdparty/asio/include/asio/experimental/detail/partial_promise.hpp | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/3rdparty/asio/include/asio/experimental/detail/partial_promise.hpp b/3rdparty/asio/include/asio/experimental/detail/partial_promise.hpp new file mode 100644 index 00000000000..8495af2f0ba --- /dev/null +++ b/3rdparty/asio/include/asio/experimental/detail/partial_promise.hpp @@ -0,0 +1,197 @@ +// +// experimental/detail/partial_promise.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2021-2023 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 ASIO_EXPERIMENTAL_DETAIL_PARTIAL_PROMISE_HPP +#define ASIO_EXPERIMENTAL_DETAIL_PARTIAL_PROMISE_HPP + +#include "asio/detail/config.hpp" +#include "asio/append.hpp" +#include "asio/awaitable.hpp" +#include "asio/experimental/coro_traits.hpp" + +#if defined(ASIO_HAS_STD_COROUTINE) +# include <coroutine> +#else // defined(ASIO_HAS_STD_COROUTINE) +# include <experimental/coroutine> +#endif // defined(ASIO_HAS_STD_COROUTINE) + +namespace asio { +namespace experimental { +namespace detail { + +#if defined(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(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(ASIO_HAS_STD_COROUTINE) + +struct partial_coro +{ + coroutine_handle<void> handle{nullptr}; +}; + +template <typename Allocator> +struct partial_promise_base +{ + template <typename Executor, typename Token, typename... Args> + void* operator new(const std::size_t size, Executor&, Token& tk, Args&...) + { + return allocate_coroutine<Allocator>(size, get_associated_allocator(tk)); + } + + void operator delete(void* raw, const std::size_t size) + { + deallocate_coroutine<Allocator>(raw, size); + } +}; + +template <> +struct partial_promise_base<std::allocator<void>> +{ +}; + +template <typename Allocator> +struct partial_promise : partial_promise_base<Allocator> +{ + auto initial_suspend() noexcept + { + return asio::detail::suspend_always{}; + } + + auto final_suspend() noexcept + { + struct awaitable_t + { + partial_promise *p; + + constexpr bool await_ready() noexcept { return true; } + + auto await_suspend(asio::detail::coroutine_handle<>) noexcept + { + p->get_return_object().handle.destroy(); + } + + constexpr void await_resume() noexcept {} + }; + + return awaitable_t{this}; + } + + void return_void() {} + + partial_coro get_return_object() + { + return partial_coro{coroutine_handle<partial_promise>::from_promise(*this)}; + } + + void unhandled_exception() + { + assert(false); + } +}; + + + +}; // namespace detail +} // namespace experimental +} // namespace asio + +#if defined(ASIO_HAS_STD_COROUTINE) + +namespace std { + +template <typename Executor, typename Completion, typename... Args> +struct coroutine_traits< + asio::experimental::detail::partial_coro, + Executor, Completion, Args...> +{ + using promise_type = + asio::experimental::detail::partial_promise< + asio::associated_allocator_t<Completion>>; +}; + +} // namespace std + +#else // defined(ASIO_HAS_STD_COROUTINE) + +namespace std { namespace experimental { + +template <typename Executor, typename Completion, typename... Args> +struct coroutine_traits< + asio::experimental::detail::partial_coro, + Executor, Completion, Args...> +{ + using promise_type = + asio::experimental::detail::partial_promise< + asio::associated_allocator_t<Completion>>; +}; + +}} // namespace std::experimental + +#endif // defined(ASIO_HAS_STD_COROUTINE) + +namespace asio { +namespace experimental { +namespace detail { + +template <execution::executor Executor, + typename CompletionToken, typename... Args> +partial_coro post_coroutine(Executor exec, + CompletionToken token, Args&&... args) noexcept +{ + post(exec, asio::append(std::move(token), std::move(args)...)); + co_return; +} + +template <detail::execution_context Context, + typename CompletionToken, typename... Args> +partial_coro post_coroutine(Context& ctx, + CompletionToken token, Args&&... args) noexcept +{ + post(ctx, asio::append(std::move(token), std::move(args)...)); + co_return; +} + +template <execution::executor Executor, + typename CompletionToken, typename... Args> +partial_coro dispatch_coroutine(Executor exec, + CompletionToken token, Args&&... args) noexcept +{ + dispatch(exec, asio::append(std::move(token), std::move(args)...)); + co_return; +} + +template <detail::execution_context Context, + typename CompletionToken, typename... Args> +partial_coro dispatch_coroutine(Context& ctx, + CompletionToken token, Args &&... args) noexcept +{ + dispatch(ctx, asio::append(std::move(token), std::move(args)...)); + co_return; +} + +} // namespace detail +} // namespace experimental +} // namespace asio + +#endif // ASIO_EXPERIMENTAL_DETAIL_PARTIAL_PROMISE_HPP |