Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //
0002 // experimental/detail/coro_completion_handler.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_CORO_COMPLETION_HANDLER_HPP
0013 #define BOOST_ASIO_EXPERIMENTAL_DETAIL_CORO_COMPLETION_HANDLER_HPP
0014 
0015 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0016 # pragma once
0017 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0018 
0019 #include <boost/asio/detail/config.hpp>
0020 #include <boost/asio/deferred.hpp>
0021 #include <boost/asio/experimental/coro.hpp>
0022 
0023 #include <boost/asio/detail/push_options.hpp>
0024 
0025 namespace boost {
0026 namespace asio {
0027 namespace experimental {
0028 namespace detail {
0029 
0030 template <typename Promise, typename... Args>
0031 struct coro_completion_handler
0032 {
0033   coro_completion_handler(coroutine_handle<Promise> h,
0034       std::optional<std::tuple<Args...>>& result)
0035     : self(h),
0036       result(result)
0037   {
0038   }
0039 
0040   coro_completion_handler(coro_completion_handler&&) = default;
0041 
0042   coroutine_handle<Promise> self;
0043 
0044   std::optional<std::tuple<Args...>>& result;
0045 
0046   using promise_type = Promise;
0047 
0048   void operator()(Args... args)
0049   {
0050     result.emplace(std::move(args)...);
0051     self.resume();
0052   }
0053 
0054   using allocator_type = typename promise_type::allocator_type;
0055   allocator_type get_allocator() const noexcept
0056   {
0057     return self.promise().get_allocator();
0058   }
0059 
0060   using executor_type = typename promise_type::executor_type;
0061   executor_type get_executor() const noexcept
0062   {
0063     return self.promise().get_executor();
0064   }
0065 
0066   using cancellation_slot_type = typename promise_type::cancellation_slot_type;
0067   cancellation_slot_type get_cancellation_slot() const noexcept
0068   {
0069     return self.promise().get_cancellation_slot();
0070   }
0071 };
0072 
0073 template <typename Signature>
0074 struct coro_completion_handler_type;
0075 
0076 template <typename... Args>
0077 struct coro_completion_handler_type<void(Args...)>
0078 {
0079   using type = std::tuple<Args...>;
0080 
0081   template <typename Promise>
0082   using completion_handler = coro_completion_handler<Promise, Args...>;
0083 };
0084 
0085 template <typename Signature>
0086 using coro_completion_handler_type_t =
0087   typename coro_completion_handler_type<Signature>::type;
0088 
0089 inline void coro_interpret_result(std::tuple<>&&)
0090 {
0091 }
0092 
0093 template <typename... Args>
0094 inline auto coro_interpret_result(std::tuple<Args...>&& args)
0095 {
0096   return std::move(args);
0097 }
0098 
0099 template <typename... Args>
0100 auto coro_interpret_result(std::tuple<std::exception_ptr, Args...>&& args)
0101 {
0102   if (std::get<0>(args))
0103     std::rethrow_exception(std::get<0>(args));
0104 
0105   return std::apply(
0106       [](auto, auto&&... rest)
0107       {
0108         return std::make_tuple(std::move(rest)...);
0109       }, std::move(args));
0110 }
0111 
0112 template <typename... Args>
0113 auto coro_interpret_result(
0114     std::tuple<boost::system::error_code, Args...>&& args)
0115 {
0116   if (std::get<0>(args))
0117     boost::asio::detail::throw_exception(
0118         boost::system::system_error(std::get<0>(args)));
0119 
0120   return std::apply(
0121       [](auto, auto&&... rest)
0122       {
0123         return std::make_tuple(std::move(rest)...);
0124       }, std::move(args));
0125 }
0126 
0127 template <typename  Arg>
0128 inline auto coro_interpret_result(std::tuple<Arg>&& args)
0129 {
0130   return std::get<0>(std::move(args));
0131 }
0132 
0133 template <typename Arg>
0134 auto coro_interpret_result(std::tuple<std::exception_ptr, Arg>&& args)
0135 {
0136   if (std::get<0>(args))
0137     std::rethrow_exception(std::get<0>(args));
0138   return std::get<1>(std::move(args));
0139 }
0140 
0141 inline auto coro_interpret_result(
0142     std::tuple<boost::system::error_code>&& args)
0143 {
0144   if (std::get<0>(args))
0145     boost::asio::detail::throw_exception(
0146         boost::system::system_error(std::get<0>(args)));
0147 }
0148 
0149 inline auto coro_interpret_result(std::tuple<std::exception_ptr>&& args)
0150 {
0151   if (std::get<0>(args))
0152     std::rethrow_exception(std::get<0>(args));
0153 }
0154 
0155 template <typename Arg>
0156 auto coro_interpret_result(std::tuple<boost::system::error_code, Arg>&& args)
0157 {
0158   if (std::get<0>(args))
0159     boost::asio::detail::throw_exception(
0160         boost::system::system_error(std::get<0>(args)));
0161   return std::get<1>(std::move(args));
0162 }
0163 
0164 } // namespace detail
0165 } // namespace experimental
0166 } // namespace asio
0167 } // namespace boost
0168 
0169 #include <boost/asio/detail/pop_options.hpp>
0170 
0171 #endif // BOOST_ASIO_EXPERIMENTAL_DETAIL_CORO_COMPLETION_HANDLER_HPP