Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:51

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(const 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, const 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 
0115 
0116 }; // namespace detail
0117 } // namespace experimental
0118 } // namespace asio
0119 } // namespace boost
0120 
0121 #if defined(BOOST_ASIO_HAS_STD_COROUTINE)
0122 
0123 namespace std {
0124 
0125 template <typename Executor, typename Completion, typename... Args>
0126 struct coroutine_traits<
0127     boost::asio::experimental::detail::partial_coro,
0128     Executor, Completion, Args...>
0129 {
0130   using promise_type =
0131     boost::asio::experimental::detail::partial_promise<
0132       boost::asio::associated_allocator_t<Completion>>;
0133 };
0134 
0135 } // namespace std
0136 
0137 #else // defined(BOOST_ASIO_HAS_STD_COROUTINE)
0138 
0139 namespace std { namespace experimental {
0140 
0141 template <typename Executor, typename Completion, typename... Args>
0142 struct coroutine_traits<
0143     boost::asio::experimental::detail::partial_coro,
0144     Executor, Completion, Args...>
0145 {
0146   using promise_type =
0147     boost::asio::experimental::detail::partial_promise<
0148       boost::asio::associated_allocator_t<Completion>>;
0149 };
0150 
0151 }} // namespace std::experimental
0152 
0153 #endif // defined(BOOST_ASIO_HAS_STD_COROUTINE)
0154 
0155 namespace boost {
0156 namespace asio {
0157 namespace experimental {
0158 namespace detail {
0159 
0160 template <execution::executor Executor,
0161     typename CompletionToken, typename... Args>
0162 partial_coro post_coroutine(Executor exec,
0163     CompletionToken token, Args&&... args) noexcept
0164 {
0165   post(exec, boost::asio::append(std::move(token), std::move(args)...));
0166   co_return;
0167 }
0168 
0169 template <detail::execution_context Context,
0170     typename CompletionToken, typename... Args>
0171 partial_coro post_coroutine(Context& ctx,
0172     CompletionToken token, Args&&... args) noexcept
0173 {
0174   post(ctx, boost::asio::append(std::move(token), std::move(args)...));
0175   co_return;
0176 }
0177 
0178 template <execution::executor Executor,
0179     typename CompletionToken, typename... Args>
0180 partial_coro dispatch_coroutine(Executor exec,
0181     CompletionToken token, Args&&... args) noexcept
0182 {
0183   dispatch(exec, boost::asio::append(std::move(token), std::move(args)...));
0184   co_return;
0185 }
0186 
0187 template <detail::execution_context Context,
0188     typename CompletionToken, typename... Args>
0189 partial_coro dispatch_coroutine(Context& ctx,
0190     CompletionToken token, Args &&... args) noexcept
0191 {
0192   dispatch(ctx, boost::asio::append(std::move(token), std::move(args)...));
0193   co_return;
0194 }
0195 
0196 } // namespace detail
0197 } // namespace experimental
0198 } // namespace asio
0199 } // namespace boost
0200 
0201 #endif // BOOST_ASIO_EXPERIMENTAL_DETAIL_PARTIAL_PROMISE_HPP