// // compose.hpp // ~~~~~~~~~~~ // // Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef ASIO_COMPOSE_HPP #define ASIO_COMPOSE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/associated_executor.hpp" #include "asio/async_result.hpp" #include "asio/detail/base_from_cancellation_state.hpp" #include "asio/detail/composed_work.hpp" #include "asio/detail/handler_cont_helpers.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { template class composed_op; template class composed_op : public base_from_cancellation_state { public: template composed_op(I&& impl, W&& work, H&& handler) : base_from_cancellation_state( handler, enable_terminal_cancellation()), impl_(static_cast(impl)), work_(static_cast(work)), handler_(static_cast(handler)), invocations_(0) { } composed_op(composed_op&& other) : base_from_cancellation_state( static_cast&&>(other)), impl_(static_cast(other.impl_)), work_(static_cast(other.work_)), handler_(static_cast(other.handler_)), invocations_(other.invocations_) { } typedef typename composed_work_guard< typename Work::head_type>::executor_type io_executor_type; io_executor_type get_io_executor() const noexcept { return work_.head_.get_executor(); } typedef associated_executor_t executor_type; executor_type get_executor() const noexcept { return (get_associated_executor)(handler_, work_.head_.get_executor()); } typedef associated_allocator_t> allocator_type; allocator_type get_allocator() const noexcept { return (get_associated_allocator)(handler_, std::allocator()); } template void operator()(T&&... t) { if (invocations_ < ~0u) ++invocations_; this->get_cancellation_state().slot().clear(); impl_(*this, static_cast(t)...); } void complete(Args... args) { this->work_.reset(); static_cast(this->handler_)(static_cast(args)...); } void reset_cancellation_state() { base_from_cancellation_state::reset_cancellation_state(handler_); } template void reset_cancellation_state(Filter&& filter) { base_from_cancellation_state::reset_cancellation_state(handler_, static_cast(filter)); } template void reset_cancellation_state(InFilter&& in_filter, OutFilter&& out_filter) { base_from_cancellation_state::reset_cancellation_state(handler_, static_cast(in_filter), static_cast(out_filter)); } cancellation_type_t cancelled() const noexcept { return base_from_cancellation_state::cancelled(); } //private: Impl impl_; Work work_; Handler handler_; unsigned invocations_; }; template inline bool asio_handler_is_continuation( composed_op* this_handler) { return this_handler->invocations_ > 1 ? true : asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template class initiate_composed_op { public: typedef typename composed_io_executors::head_type executor_type; template explicit initiate_composed_op(int, T&& executors) : executors_(static_cast(executors)) { } executor_type get_executor() const noexcept { return executors_.head_; } template void operator()(Handler&& handler, Impl&& impl) const { composed_op, composed_work, decay_t, Signature>( static_cast(impl), composed_work(executors_), static_cast(handler))(); } private: composed_io_executors executors_; }; template inline initiate_composed_op make_initiate_composed_op( composed_io_executors&& executors) { return initiate_composed_op(0, static_cast&&>(executors)); } } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template