Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:44:27

0001 //
0002 // Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 
0008 #ifndef BOOST_COBALT_TASK_HPP
0009 #define BOOST_COBALT_TASK_HPP
0010 
0011 #include <boost/cobalt/detail/handler.hpp>
0012 #include <boost/cobalt/detail/task.hpp>
0013 #include <boost/cobalt/op.hpp>
0014 
0015 #include <boost/asio/append.hpp>
0016 #include <boost/asio/deferred.hpp>
0017 
0018 namespace boost::cobalt
0019 {
0020 
0021 // tag::outline[]
0022 template<typename Return>
0023 struct [[nodiscard]] task
0024 {
0025     task(task &&lhs) noexcept = default;
0026     task& operator=(task &&) noexcept = default;
0027 
0028     // enable `co_await`
0029     auto operator co_await ();
0030 
0031     // end::outline[]
0032     task(const task &) = delete;
0033     task& operator=(const task &) = delete;
0034 
0035     using promise_type = detail::task_promise<Return>;
0036 
0037     constexpr task(noop<Return> n) : receiver_(std::move(n)){}
0038 
0039  private:
0040     template<typename>
0041     friend struct detail::task_promise;
0042 
0043     task(detail::task_promise<Return> * task) : receiver_(task)
0044     {
0045     }
0046 
0047     detail::task_receiver<Return> receiver_;
0048     friend struct detail::async_initiate_spawn;
0049     // tag::outline[]
0050 };
0051 // end::outline[]
0052 
0053 
0054 struct use_task_t
0055 {
0056   /// Default constructor.
0057   constexpr use_task_t()
0058   {
0059   }
0060 
0061   /// Adapts an executor to add the @c use_task_t completion token as the
0062   /// default.
0063   template <typename InnerExecutor>
0064   struct executor_with_default : InnerExecutor
0065   {
0066     /// Specify @c use_task_t as the default completion token type.
0067     typedef use_task_t default_completion_token_type;
0068 
0069     executor_with_default(const InnerExecutor& ex) noexcept
0070         : InnerExecutor(ex)
0071     {
0072     }
0073 
0074     /// Construct the adapted executor from the inner executor type.
0075     template <typename InnerExecutor1>
0076     executor_with_default(const InnerExecutor1& ex,
0077                           typename std::enable_if<
0078                               std::conditional<
0079                                   !std::is_same<InnerExecutor1, executor_with_default>::value,
0080                                   std::is_convertible<InnerExecutor1, InnerExecutor>,
0081                                   std::false_type
0082                               >::type::value>::type = 0) noexcept
0083         : InnerExecutor(ex)
0084     {
0085     }
0086   };
0087 
0088   /// Type alias to adapt an I/O object to use @c use_task_t as its
0089   /// default completion token type.
0090   template <typename T>
0091   using as_default_on_t = typename T::template rebind_executor<
0092       executor_with_default<typename T::executor_type> >::other;
0093 
0094   /// Function helper to adapt an I/O object to use @c use_task_t as its
0095   /// default completion token type.
0096   template <typename T>
0097   static typename std::decay_t<T>::template rebind_executor<
0098       executor_with_default<typename std::decay_t<T>::executor_type>
0099   >::other
0100   as_default_on(T && object)
0101   {
0102     return typename std::decay_t<T>::template rebind_executor<
0103         executor_with_default<typename std::decay_t<T>::executor_type>
0104     >::other(std::forward<T>(object));
0105   }
0106 
0107 };
0108 
0109 constexpr use_task_t use_task{};
0110 
0111 template<typename T>
0112 inline auto task<T>::operator co_await () {return receiver_.get_awaitable();}
0113 
0114 }
0115 
0116 
0117 namespace boost::asio
0118 {
0119 
0120 template<typename ... Args>
0121 struct async_result<boost::cobalt::use_task_t, void(Args...)>
0122 {
0123   using return_type = cobalt::task<
0124       typename decltype(cobalt::interpret_as_result(std::declval<std::tuple<Args...>>()))::value_type>;
0125 
0126   template <typename Initiation, typename... InitArgs>
0127   static auto initiate(Initiation initiation,
0128                        boost::cobalt::use_task_t,
0129                        InitArgs ... args) -> return_type
0130 
0131   {
0132     co_return co_await async_initiate<
0133           const cobalt::use_op_t&, void(Args...)>(
0134               std::move(initiation),
0135               cobalt::use_op, std::move(args)...);
0136   }
0137 };
0138 
0139 }
0140 
0141 
0142 #endif //BOOST_COBALT_COBALT_HPP