// // composed.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 BOOST_ASIO_COMPOSED_HPP #define BOOST_ASIO_COMPOSED_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include #include #include #include #include #include #include #include namespace boost { 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)...); } template auto complete(Args&&... args) -> decltype(declval()(static_cast(args)...)) { return 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 class composed_op : public composed_op { public: using composed_op::composed_op; template void operator()(T&&... t) { if (this->invocations_ < ~0u) ++this->invocations_; this->get_cancellation_state().slot().clear(); this->impl_(*this, static_cast(t)...); } void complete(Args... args) { this->work_.reset(); static_cast(this->handler_)(static_cast(args)...); } }; template class composed_op : public composed_op { public: using composed_op::composed_op; template void operator()(T&&... t) { if (this->invocations_ < ~0u) ++this->invocations_; this->get_cancellation_state().slot().clear(); this->impl_(*this, static_cast(t)...); } using composed_op::complete; void complete(Args... args) { this->work_.reset(); static_cast(this->handler_)(static_cast(args)...); } }; template inline bool asio_handler_is_continuation( composed_op* this_handler) { return this_handler->invocations_ > 1 ? true : boost_asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template class initiate_composed { public: typedef typename composed_io_executors::head_type executor_type; template initiate_composed(I&& impl, composed_io_executors&& executors) : implementation_(std::forward(impl)), executors_(std::move(executors)) { } executor_type get_executor() const noexcept { return executors_.head_; } template void operator()(Handler&& handler, Args&&... args) const & { composed_op, composed_work, decay_t, Signatures...>(implementation_, composed_work(executors_), static_cast(handler))(static_cast(args)...); } template void operator()(Handler&& handler, Args&&... args) && { composed_op, composed_work, decay_t, Signatures...>( static_cast(implementation_), composed_work(executors_), static_cast(handler))(static_cast(args)...); } private: Implementation implementation_; composed_io_executors executors_; }; template class initiate_composed { public: template initiate_composed(I&& impl, composed_io_executors&&) : implementation_(std::forward(impl)) { } template void operator()(Handler&& handler, Args&&... args) const & { composed_op, composed_work, decay_t, Signatures...>(implementation_, composed_work(composed_io_executors()), static_cast(handler))(static_cast(args)...); } template void operator()(Handler&& handler, Args&&... args) && { composed_op, composed_work, decay_t, Signatures...>( static_cast(implementation_), composed_work(composed_io_executors()), static_cast(handler))(static_cast(args)...); } private: Implementation implementation_; }; template inline initiate_composed make_initiate_composed(Implementation&& implementation, composed_io_executors&& executors) { return initiate_composed, Executors, Signatures...>( static_cast(implementation), static_cast&&>(executors)); } } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template