2 // experimental/impl/promise.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2021-2022 Klemens D. Morgenstern
6 // (klemens dot morgenstern at gmx dot net)
8 // Distributed under the Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11 #ifndef BOOST_ASIO_EXPERIMENTAL_IMPL_PROMISE_HPP
12 #define BOOST_ASIO_EXPERIMENTAL_IMPL_PROMISE_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/cancellation_signal.hpp>
19 #include <boost/asio/experimental/detail/completion_handler_erasure.hpp>
23 #include <boost/asio/detail/push_options.hpp>
27 namespace experimental {
29 template<typename Signature = void(), typename Executor = any_io_executor>
34 template<typename Signature, typename Executor>
37 template<typename ... Ts, typename Executor>
38 struct promise_impl<void(Ts...), Executor>
40 using result_type = std::tuple<Ts...>;
42 promise_impl(Executor executor = {})
43 : executor(std::move(executor))
47 std::optional<result_type> result;
49 detail::completion_handler_erasure<void(Ts...), Executor> completion;
50 cancellation_signal cancel;
54 template<typename Signature = void(), typename Executor = any_io_executor>
55 struct promise_handler;
57 template<typename Signature, typename Executor>
58 struct promise_handler;
60 template<typename ... Ts, typename Executor>
61 struct promise_handler<void(Ts...), Executor>
63 using promise_type = promise<void(Ts...), Executor>;
65 promise_handler(Executor executor) // get_associated_allocator(exec)
67 std::allocate_shared<promise_impl<void(Ts...), Executor>>(
68 get_associated_allocator(executor))}
70 impl_->executor = std::move(executor);
73 std::shared_ptr<promise_impl<void(Ts...), Executor>> impl_;
75 using cancellation_slot_type = cancellation_slot;
77 cancellation_slot_type get_cancellation_slot() const noexcept
79 return impl_->cancel.slot();
82 auto make_promise() -> promise<void(Ts...), Executor>
87 void operator()(std::remove_reference_t<Ts>... ts)
90 impl_->result.emplace(std::move(ts)...);
92 if (auto f = std::exchange(impl_->completion, nullptr); f != nullptr)
93 std::apply(std::move(f), std::move(*impl_->result));
98 } // namespace experimental
102 #include <boost/asio/detail/pop_options.hpp>
104 #endif // BOOST_ASIO_EXPERIMENTAL_IMPL_PROMISE_HPP