Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-12 08:08:08

0001 //
0002 // experimental/detail/partial_promise.hpp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2021-2023 Klemens D. Morgenstern
0006 //                         (klemens dot morgenstern at gmx dot net)
0007 //
0008 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0009 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0010 //
0011 
0012 #ifndef BOOST_ASIO_EXPERIMENTAL_DETAIL_PARTIAL_PROMISE_HPP
0013 #define BOOST_ASIO_EXPERIMENTAL_DETAIL_PARTIAL_PROMISE_HPP
0014 
0015 #include <boost/asio/detail/config.hpp>
0016 #include <boost/asio/append.hpp>
0017 #include <boost/asio/awaitable.hpp>
0018 #include <boost/asio/experimental/coro_traits.hpp>
0019 
0020 #if defined(BOOST_ASIO_HAS_STD_COROUTINE)
0021 # include <coroutine>
0022 #else // defined(BOOST_ASIO_HAS_STD_COROUTINE)
0023 # include <experimental/coroutine>
0024 #endif // defined(BOOST_ASIO_HAS_STD_COROUTINE)
0025 
0026 namespace boost {
0027 namespace asio {
0028 namespace experimental {
0029 namespace detail {
0030 
0031 #if defined(BOOST_ASIO_HAS_STD_COROUTINE)
0032 
0033 using std::coroutine_handle;
0034 using std::coroutine_traits;
0035 using std::suspend_never;
0036 using std::suspend_always;
0037 using std::noop_coroutine;
0038 
0039 #else // defined(BOOST_ASIO_HAS_STD_COROUTINE)
0040 
0041 using std::experimental::coroutine_handle;
0042 using std::experimental::coroutine_traits;
0043 using std::experimental::suspend_never;
0044 using std::experimental::suspend_always;
0045 using std::experimental::noop_coroutine;
0046 
0047 #endif // defined(BOOST_ASIO_HAS_STD_COROUTINE)
0048 
0049 struct partial_coro
0050 {
0051   coroutine_handle<void> handle{nullptr};
0052 };
0053 
0054 template <typename Allocator>
0055 struct partial_promise_base
0056 {
0057   template <typename Executor, typename Token, typename... Args>
0058   void* operator new(std::size_t size, Executor&, Token& tk, Args&...)
0059   {
0060     return allocate_coroutine<Allocator>(size, get_associated_allocator(tk));
0061   }
0062 
0063   void operator delete(void* raw, std::size_t size)
0064   {
0065     deallocate_coroutine<Allocator>(raw, size);
0066   }
0067 };
0068 
0069 template <>
0070 struct partial_promise_base<std::allocator<void>>
0071 {
0072 };
0073 
0074 template <typename Allocator>
0075 struct partial_promise : partial_promise_base<Allocator>
0076 {
0077   auto initial_suspend() noexcept
0078   {
0079     return boost::asio::detail::suspend_always{};
0080   }
0081 
0082   auto final_suspend() noexcept
0083   {
0084     struct awaitable_t
0085     {
0086       partial_promise *p;
0087 
0088       constexpr bool await_ready() noexcept { return true; }
0089 
0090       auto await_suspend(boost::asio::detail::coroutine_handle<>) noexcept
0091       {
0092         p->get_return_object().handle.destroy();
0093       }
0094 
0095       constexpr void await_resume() noexcept {}
0096     };
0097 
0098     return awaitable_t{this};
0099   }
0100 
0101   void return_void() {}
0102 
0103   partial_coro get_return_object()
0104   {
0105     return partial_coro{coroutine_handle<partial_promise>::from_promise(*this)};
0106   }
0107 
0108   void unhandled_exception()
0109   {
0110     assert(false);
0111   }
0112 };
0113 
0114 } // namespace detail
0115 } // namespace experimental
0116 } // namespace asio
0117 } // namespace boost
0118 
0119 #if defined(BOOST_ASIO_HAS_STD_COROUTINE)
0120 
0121 namespace std {
0122 
0123 template <typename Executor, typename Completion, typename... Args>
0124 struct coroutine_traits<
0125     boost::asio::experimental::detail::partial_coro,
0126     Executor, Completion, Args...>
0127 {
0128   using promise_type =
0129     boost::asio::experimental::detail::partial_promise<
0130       boost::asio::associated_allocator_t<Completion>>;
0131 };
0132 
0133 } // namespace std
0134 
0135 #else // defined(BOOST_ASIO_HAS_STD_COROUTINE)
0136 
0137 namespace std { namespace experimental {
0138 
0139 template <typename Executor, typename Completion, typename... Args>
0140 struct coroutine_traits<
0141     boost::asio::experimental::detail::partial_coro,
0142     Executor, Completion, Args...>
0143 {
0144   using promise_type =
0145     boost::asio::experimental::detail::partial_promise<
0146       boost::asio::associated_allocator_t<Completion>>;
0147 };
0148 
0149 }} // namespace std::experimental
0150 
0151 #endif // defined(BOOST_ASIO_HAS_STD_COROUTINE)
0152 
0153 namespace boost {
0154 namespace asio {
0155 namespace experimental {
0156 namespace detail {
0157 
0158 template <execution::executor Executor,
0159     typename CompletionToken, typename... Args>
0160 partial_coro post_coroutine(Executor exec,
0161     CompletionToken token, Args&&... args) noexcept
0162 {
0163   post(exec, boost::asio::append(std::move(token), std::move(args)...));
0164   co_return;
0165 }
0166 
0167 template <detail::execution_context Context,
0168     typename CompletionToken, typename... Args>
0169 partial_coro post_coroutine(Context& ctx,
0170     CompletionToken token, Args&&... args) noexcept
0171 {
0172   post(ctx, boost::asio::append(std::move(token), std::move(args)...));
0173   co_return;
0174 }
0175 
0176 template <execution::executor Executor,
0177     typename CompletionToken, typename... Args>
0178 partial_coro dispatch_coroutine(Executor exec,
0179     CompletionToken token, Args&&... args) noexcept
0180 {
0181   dispatch(exec, boost::asio::append(std::move(token), std::move(args)...));
0182   co_return;
0183 }
0184 
0185 template <detail::execution_context Context,
0186     typename CompletionToken, typename... Args>
0187 partial_coro dispatch_coroutine(Context& ctx,
0188     CompletionToken token, Args &&... args) noexcept
0189 {
0190   dispatch(ctx, boost::asio::append(std::move(token), std::move(args)...));
0191   co_return;
0192 }
0193 
0194 } // namespace detail
0195 } // namespace experimental
0196 } // namespace asio
0197 } // namespace boost
0198 
0199 #endif // BOOST_ASIO_EXPERIMENTAL_DETAIL_PARTIAL_PROMISE_HPP