// impl/redirect_error.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_ERROR_HPP #define BOOST_ASIO_IMPL_REDIRECT_ERROR_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 #include namespace boost { namespace asio { BOOST_ASIO_INLINE_NAMESPACE_BEGIN namespace detail { // Class to adapt a redirect_error_t as a completion handler. template class redirect_error_handler { public: typedef void result_type; template redirect_error_handler(redirect_error_t e) : ec_(e.ec_), handler_(static_cast(e.token_)) { } template redirect_error_handler(boost::system::error_code& ec, RedirectedHandler&& h) : ec_(ec), handler_(static_cast(h)) { } void operator()() { static_cast(handler_)(); } template enable_if_t< !is_same, boost::system::error_code>::value > operator()(Arg&& arg, Args&&... args) { static_cast(handler_)( static_cast(arg), static_cast(args)...); } template void operator()(const boost::system::error_code& ec, Args&&... args) { ec_ = ec; static_cast(handler_)(static_cast(args)...); } //private: boost::system::error_code& ec_; Handler handler_; }; template inline bool asio_handler_is_continuation( redirect_error_handler* this_handler) { return BOOST_ASIO_VERSIONED_NAME(handler_cont_helpers)::is_continuation( this_handler->handler_); } template struct redirect_error_signature { typedef Signature type; }; template struct redirect_error_signature { typedef R type(Args...); }; template struct redirect_error_signature { typedef R type(Args...); }; template struct redirect_error_signature { typedef R type(Args...) &; }; template struct redirect_error_signature { typedef R type(Args...) &; }; template struct redirect_error_signature { typedef R type(Args...) &&; }; template struct redirect_error_signature { typedef R type(Args...) &&; }; #if defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE) template struct redirect_error_signature< R(boost::system::error_code, Args...) noexcept> { typedef R type(Args...) & noexcept; }; template struct redirect_error_signature< R(const boost::system::error_code&, Args...) noexcept> { typedef R type(Args...) & noexcept; }; template struct redirect_error_signature< R(boost::system::error_code, Args...) & noexcept> { typedef R type(Args...) & noexcept; }; template struct redirect_error_signature< R(const boost::system::error_code&, Args...) & noexcept> { typedef R type(Args...) & noexcept; }; template struct redirect_error_signature< R(boost::system::error_code, Args...) && noexcept> { typedef R type(Args...) && noexcept; }; template struct redirect_error_signature< R(const boost::system::error_code&, Args...) && noexcept> { typedef R type(Args...) && noexcept; }; #endif // defined(BOOST_ASIO_HAS_NOEXCEPT_FUNCTION_TYPE) } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct async_result, Signature> : async_result::type> { template struct init_wrapper : detail::initiation_base { using detail::initiation_base::initiation_base; template void operator()(Handler&& handler, boost::system::error_code* ec, Args&&... args) && { static_cast(*this)( detail::redirect_error_handler>( *ec, static_cast(handler)), static_cast(args)...); } template void operator()(Handler&& handler, boost::system::error_code* ec, Args&&... args) const & { static_cast(*this)( detail::redirect_error_handler>( *ec, 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_error_signature::type>( declval>>(), token.token_, &token.ec_, static_cast(args)...)) { return async_initiate< conditional_t< is_const>::value, const CompletionToken, CompletionToken>, typename detail::redirect_error_signature::type>( init_wrapper>( static_cast(initiation)), token.token_, &token.ec_, static_cast(args)...); } }; template