File indexing completed on 2025-01-18 09:28:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
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
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 }
0165 }
0166 }
0167 }
0168
0169 #include <boost/asio/detail/pop_options.hpp>
0170
0171 #endif