// // impl/prepend.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2023 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 ASIO_IMPL_PREPEND_HPP #define ASIO_IMPL_PREPEND_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include "asio/associator.hpp" #include "asio/async_result.hpp" #include "asio/detail/handler_alloc_helpers.hpp" #include "asio/detail/handler_cont_helpers.hpp" #include "asio/detail/handler_invoke_helpers.hpp" #include "asio/detail/type_traits.hpp" #include "asio/detail/utility.hpp" #include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Class to adapt a prepend_t as a completion handler. template class prepend_handler { public: typedef void result_type; template prepend_handler(ASIO_MOVE_ARG(H) handler, std::tuple values) : handler_(ASIO_MOVE_CAST(H)(handler)), values_(ASIO_MOVE_CAST(std::tuple)(values)) { } template void operator()(ASIO_MOVE_ARG(Args)... args) { this->invoke( index_sequence_for{}, ASIO_MOVE_CAST(Args)(args)...); } template void invoke(index_sequence, ASIO_MOVE_ARG(Args)... args) { ASIO_MOVE_OR_LVALUE(Handler)(handler_)( ASIO_MOVE_CAST(Values)(std::get(values_))..., ASIO_MOVE_CAST(Args)(args)...); } //private: Handler handler_; std::tuple values_; }; template inline asio_handler_allocate_is_deprecated asio_handler_allocate(std::size_t size, prepend_handler* this_handler) { #if defined(ASIO_NO_DEPRECATED) asio_handler_alloc_helpers::allocate(size, this_handler->handler_); return asio_handler_allocate_is_no_longer_used(); #else // defined(ASIO_NO_DEPRECATED) return asio_handler_alloc_helpers::allocate( size, this_handler->handler_); #endif // defined(ASIO_NO_DEPRECATED) } template inline asio_handler_deallocate_is_deprecated asio_handler_deallocate(void* pointer, std::size_t size, prepend_handler* this_handler) { asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); #if defined(ASIO_NO_DEPRECATED) return asio_handler_deallocate_is_no_longer_used(); #endif // defined(ASIO_NO_DEPRECATED) } template inline bool asio_handler_is_continuation( prepend_handler* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline asio_handler_invoke_is_deprecated asio_handler_invoke(Function& function, prepend_handler* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); #if defined(ASIO_NO_DEPRECATED) return asio_handler_invoke_is_no_longer_used(); #endif // defined(ASIO_NO_DEPRECATED) } template inline asio_handler_invoke_is_deprecated asio_handler_invoke(const Function& function, prepend_handler* this_handler) { asio_handler_invoke_helpers::invoke( function, this_handler->handler_); #if defined(ASIO_NO_DEPRECATED) return asio_handler_invoke_is_no_longer_used(); #endif // defined(ASIO_NO_DEPRECATED) } template struct prepend_signature; template struct prepend_signature { typedef R type(Values..., typename decay::type...); }; } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template struct async_result< prepend_t, Signature> : async_result::type> { typedef typename detail::prepend_signature< Signature, Values...>::type signature; template struct init_wrapper { init_wrapper(Initiation init) : initiation_(ASIO_MOVE_CAST(Initiation)(init)) { } template void operator()( ASIO_MOVE_ARG(Handler) handler, std::tuple values, ASIO_MOVE_ARG(Args)... args) { ASIO_MOVE_CAST(Initiation)(initiation_)( detail::prepend_handler< typename decay::type, Values...>( ASIO_MOVE_CAST(Handler)(handler), ASIO_MOVE_CAST(std::tuple)(values)), ASIO_MOVE_CAST(Args)(args)...); } Initiation initiation_; }; template static ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, signature, (async_initiate( declval::type> >(), declval(), declval >(), declval()...))) initiate( ASIO_MOVE_ARG(Initiation) initiation, ASIO_MOVE_ARG(RawCompletionToken) token, ASIO_MOVE_ARG(Args)... args) { return async_initiate( init_wrapper::type>( ASIO_MOVE_CAST(Initiation)(initiation)), token.token_, ASIO_MOVE_CAST(std::tuple)(token.values_), ASIO_MOVE_CAST(Args)(args)...); } }; template