// // impl/cancel_after.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_IMPL_CANCEL_AFTER_HPP #define BOOST_ASIO_IMPL_CANCEL_AFTER_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include #include #include #include #include #include namespace boost { namespace asio { namespace detail { template struct initiate_cancel_after : initiation_base { using initiation_base::initiation_base; template void operator()(Handler&& handler, const chrono::duration& timeout, cancellation_type_t cancel_type, Args&&... args) && { using op = detail::timed_cancel_op, basic_waitable_timer, Signatures...>; non_const_lvalue handler2(handler); typename op::ptr p = { boost::asio::detail::addressof(handler2.value), op::ptr::allocate(handler2.value), 0 }; p.p = new (p.v) op(handler2.value, basic_waitable_timer(this->get_executor(), timeout), cancel_type); op* o = p.p; p.v = p.p = 0; o->start(static_cast(*this), static_cast(args)...); } template void operator()(Handler&& handler, const chrono::duration& timeout, cancellation_type_t cancel_type, Args&&... args) const & { using op = detail::timed_cancel_op, basic_waitable_timer, Signatures...>; non_const_lvalue handler2(handler); typename op::ptr p = { boost::asio::detail::addressof(handler2.value), op::ptr::allocate(handler2.value), 0 }; p.p = new (p.v) op(handler2.value, basic_waitable_timer(this->get_executor(), timeout), cancel_type); op* o = p.p; p.v = p.p = 0; o->start(static_cast(*this), static_cast(args)...); } }; template struct initiate_cancel_after_timer : initiation_base { using initiation_base::initiation_base; template void operator()(Handler&& handler, basic_waitable_timer* timer, const chrono::duration& timeout, cancellation_type_t cancel_type, Args&&... args) && { using op = detail::timed_cancel_op, basic_waitable_timer&, Signatures...>; non_const_lvalue handler2(handler); typename op::ptr p = { boost::asio::detail::addressof(handler2.value), op::ptr::allocate(handler2.value), 0 }; timer->expires_after(timeout); p.p = new (p.v) op(handler2.value, *timer, cancel_type); op* o = p.p; p.v = p.p = 0; o->start(static_cast(*this), static_cast(args)...); } template void operator()(Handler&& handler, basic_waitable_timer* timer, const chrono::duration& timeout, cancellation_type_t cancel_type, Args&&... args) const & { using op = detail::timed_cancel_op, basic_waitable_timer&, Signatures...>; non_const_lvalue handler2(handler); typename op::ptr p = { boost::asio::detail::addressof(handler2.value), op::ptr::allocate(handler2.value), 0 }; timer->expires_after(timeout); p.p = new (p.v) op(handler2.value, *timer, cancel_type); op* o = p.p; p.v = p.p = 0; o->start(static_cast(*this), static_cast(args)...); } }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct async_result< cancel_after_t, Signatures...> : async_result { template static auto initiate(Initiation&& initiation, RawCompletionToken&& token, Args&&... args) -> decltype( async_initiate< conditional_t< is_const>::value, const CompletionToken, CompletionToken>, Signatures...>( declval, Clock, WaitTraits, Signatures...>>(), token.token_, token.timeout_, token.cancel_type_, static_cast(args)...)) { return async_initiate< conditional_t< is_const>::value, const CompletionToken, CompletionToken>, Signatures...>( detail::initiate_cancel_after< decay_t, Clock, WaitTraits, Signatures...>( static_cast(initiation)), token.token_, token.timeout_, token.cancel_type_, static_cast(args)...); } }; template struct async_result< cancel_after_timer, Signatures...> : async_result { template static auto initiate(Initiation&& initiation, RawCompletionToken&& token, Args&&... args) -> decltype( async_initiate< conditional_t< is_const>::value, const CompletionToken, CompletionToken>, Signatures...>( declval, Clock, WaitTraits, Executor, Signatures...>>(), token.token_, &token.timer_, token.timeout_, token.cancel_type_, static_cast(args)...)) { return async_initiate< conditional_t< is_const>::value, const CompletionToken, CompletionToken>, Signatures...>( detail::initiate_cancel_after_timer< decay_t, Clock, WaitTraits, Executor, Signatures...>( static_cast(initiation)), token.token_, &token.timer_, token.timeout_, token.cancel_type_, static_cast(args)...); } }; template struct async_result, Signatures...> { template static auto initiate(Initiation&& initiation, RawCompletionToken&& token, Args&&... args) -> decltype( async_initiate< const cancel_after_t< default_completion_token_t>, Clock, WaitTraits>&, Signatures...>( static_cast(initiation), cancel_after_t< default_completion_token_t>, Clock, WaitTraits>( default_completion_token_t>{}, token.timeout_, token.cancel_type_), static_cast(args)...)) { return async_initiate< const cancel_after_t< default_completion_token_t>, Clock, WaitTraits>&, Signatures...>( static_cast(initiation), cancel_after_t< default_completion_token_t>, Clock, WaitTraits>( default_completion_token_t>{}, token.timeout_, token.cancel_type_), static_cast(args)...); } }; template struct async_result< partial_cancel_after_timer, Signatures...> { template static auto initiate(Initiation&& initiation, RawCompletionToken&& token, Args&&... args) -> decltype( async_initiate( static_cast(initiation), cancel_after_timer< default_completion_token_t>, Clock, WaitTraits, Executor>( default_completion_token_t>{}, token.timer_, token.timeout_, token.cancel_type_), static_cast(args)...)) { return async_initiate( static_cast(initiation), cancel_after_timer< default_completion_token_t>, Clock, WaitTraits, Executor>( default_completion_token_t>{}, token.timer_, token.timeout_, token.cancel_type_), static_cast(args)...); } }; #endif // !defined(GENERATING_DOCUMENTATION) } // namespace asio } // namespace boost #include #endif // BOOST_ASIO_IMPL_CANCEL_AFTER_HPP