// impl/redirect_disposition.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2026 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_REDIRECT_DISPOSITION_HPP #define BOOST_ASIO_IMPL_REDIRECT_DISPOSITION_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 { BOOST_ASIO_INLINE_NAMESPACE_BEGIN namespace detail { // Class to adapt a redirect_disposition_t as a completion handler. template class redirect_disposition_handler { public: typedef void result_type; template redirect_disposition_handler( redirect_disposition_t e) : d_(e.d_), handler_(static_cast(e.token_)) { } template redirect_disposition_handler(Disposition& d, RedirectedHandler&& h) : d_(d), handler_(static_cast(h)) { } void operator()() { static_cast(handler_)(); } template enable_if_t< !is_same, Disposition>::value > operator()(Arg&& arg, Args&&... args) { static_cast(handler_)( static_cast(arg), static_cast(args)...); } template void operator()(const Disposition& d, Args&&... args) { d_ = d; static_cast(handler_)(static_cast(args)...); } //private: Disposition& d_; Handler handler_; }; template class redirect_disposition_handler { public: typedef void result_type; template redirect_disposition_handler( redirect_disposition_t e) : d_(e.d_), handler_(static_cast(e.token_)) { } template redirect_disposition_handler(std::exception_ptr& d, RedirectedHandler&& h) : d_(d), handler_(static_cast(h)) { } void operator()() { static_cast(handler_)(); } template enable_if_t< !is_disposition>::value > operator()(Arg&& arg, Args&&... args) { static_cast(handler_)( static_cast(arg), static_cast(args)...); } template enable_if_t< is_disposition::value > operator()(const Disposition& d, Args&&... args) { d_ = disposition_traits::to_exception_ptr(d); static_cast(handler_)(static_cast(args)...); } //private: std::exception_ptr& d_; Handler handler_; }; template inline bool asio_handler_is_continuation( redirect_disposition_handler* this_handler) { return BOOST_ASIO_VERSIONED_NAME(handler_cont_helpers)::is_continuation( this_handler->handler_); } template struct redirect_disposition_signature { typedef Signature type; }; template struct redirect_disposition_signature< Disposition, R(Disposition, Args...)> { typedef R type(Args...); }; template struct redirect_disposition_signature< Disposition, R(const Disposition&, Args...)> { typedef R type(Args...); }; template struct redirect_disposition_signature< Disposition, R(Disposition, Args...) &> { typedef R type(Args...) &; }; template struct redirect_disposition_signature< Disposition, R(const Disposition&, Args...) &> { typedef R type(Args...) &; }; template struct redirect_disposition_signature< Disposition, R(Disposition, Args...) &&> { typedef R type(Args...) &&; }; template struct redirect_disposition_signature< Disposition, R(const Disposition&, Args...) &&> { typedef R type(Args...) &&; }; #if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE) template struct redirect_disposition_signature< Disposition, R(Disposition, Args...) noexcept> { typedef R type(Args...) & noexcept; }; template struct redirect_disposition_signature< Disposition, R(const Disposition&, Args...) noexcept> { typedef R type(Args...) & noexcept; }; template struct redirect_disposition_signature< Disposition, R(Disposition, Args...) & noexcept> { typedef R type(Args...) & noexcept; }; template struct redirect_disposition_signature< Disposition, R(const Disposition&, Args...) & noexcept> { typedef R type(Args...) & noexcept; }; template struct redirect_disposition_signature< Disposition, R(Disposition, Args...) && noexcept> { typedef R type(Args...) && noexcept; }; template struct redirect_disposition_signature< Disposition, R(const Disposition&, Args...) && noexcept> { typedef R type(Args...) && noexcept; }; #endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE) template struct redirect_disposition_signature< std::exception_ptr, R(Disposition, Args...), enable_if_t::value>> { typedef R type(Args...); }; template struct redirect_disposition_signature< std::exception_ptr, R(const Disposition&, Args...), enable_if_t::value>> { typedef R type(Args...); }; template struct redirect_disposition_signature< std::exception_ptr, R(Disposition, Args...) &, enable_if_t::value>> { typedef R type(Args...) &; }; template struct redirect_disposition_signature< std::exception_ptr, R(const Disposition&, Args...) &, enable_if_t::value>> { typedef R type(Args...) &; }; template struct redirect_disposition_signature< std::exception_ptr, R(Disposition, Args...) &&, enable_if_t::value>> { typedef R type(Args...) &&; }; template struct redirect_disposition_signature< std::exception_ptr, R(const Disposition&, Args...) &&, enable_if_t::value>> { typedef R type(Args...) &&; }; #if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE) template struct redirect_disposition_signature< std::exception_ptr, R(Disposition, Args...) noexcept, enable_if_t::value>> { typedef R type(Args...) & noexcept; }; template struct redirect_disposition_signature< std::exception_ptr, R(const Disposition&, Args...) noexcept, enable_if_t::value>> { typedef R type(Args...) & noexcept; }; template struct redirect_disposition_signature< std::exception_ptr, R(Disposition, Args...) & noexcept, enable_if_t::value>> { typedef R type(Args...) & noexcept; }; template struct redirect_disposition_signature< std::exception_ptr, R(const Disposition&, Args...) & noexcept, enable_if_t::value>> { typedef R type(Args...) & noexcept; }; template struct redirect_disposition_signature< std::exception_ptr, R(Disposition, Args...) && noexcept, enable_if_t::value>> { typedef R type(Args...) && noexcept; }; template struct redirect_disposition_signature< std::exception_ptr, R(const Disposition&, Args...) && noexcept, enable_if_t::value>> { typedef R type(Args...) && noexcept; }; #endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE) } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct async_result< redirect_disposition_t, Signature> : async_result::type> { template struct init_wrapper : detail::initiation_base { using detail::initiation_base::initiation_base; template void operator()(Handler&& handler, Disposition* d, Args&&... args) && { static_cast(*this)( detail::redirect_disposition_handler>( *d, static_cast(handler)), static_cast(args)...); } template void operator()(Handler&& handler, Disposition* d, Args&&... args) const & { static_cast(*this)( detail::redirect_disposition_handler>( *d, static_cast(handler)), static_cast(args)...); } }; template static auto initiate(Initiation&& initiation, RawCompletionToken&& token, Args&&... args) -> decltype( async_initiate< conditional_t< is_const>::value, const CompletionToken, CompletionToken>, typename detail::redirect_disposition_signature< Disposition, Signature>::type>( declval>>(), token.token_, &token.d_, static_cast(args)...)) { return async_initiate< conditional_t< is_const>::value, const CompletionToken, CompletionToken>, typename detail::redirect_disposition_signature< Disposition, Signature>::type>( init_wrapper>( static_cast(initiation)), token.token_, &token.d_, static_cast(args)...); } }; template