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