// // impl/as_tuple.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_AS_TUPLE_HPP #define ASIO_IMPL_AS_TUPLE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" #include <tuple> #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/variadic_templates.hpp" #include "asio/detail/push_options.hpp" namespace asio { namespace detail { // Class to adapt a as_tuple_t as a completion handler. template <typename Handler> class as_tuple_handler { public: typedef void result_type; template <typename CompletionToken> as_tuple_handler(as_tuple_t<CompletionToken> e) : handler_(ASIO_MOVE_CAST(CompletionToken)(e.token_)) { } template <typename RedirectedHandler> as_tuple_handler(ASIO_MOVE_ARG(RedirectedHandler) h) : handler_(ASIO_MOVE_CAST(RedirectedHandler)(h)) { } template <typename... Args> void operator()(ASIO_MOVE_ARG(Args)... args) { ASIO_MOVE_OR_LVALUE(Handler)(handler_)( std::make_tuple(ASIO_MOVE_CAST(Args)(args)...)); } //private: Handler handler_; }; template <typename Handler> inline asio_handler_allocate_is_deprecated asio_handler_allocate(std::size_t size, as_tuple_handler<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 <typename Handler> inline asio_handler_deallocate_is_deprecated asio_handler_deallocate(void* pointer, std::size_t size, as_tuple_handler<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 <typename Handler> inline bool asio_handler_is_continuation( as_tuple_handler<Handler>* this_handler) { return asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template <typename Function, typename Handler> inline asio_handler_invoke_is_deprecated asio_handler_invoke(Function& function, as_tuple_handler<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 <typename Function, typename Handler> inline asio_handler_invoke_is_deprecated asio_handler_invoke(const Function& function, as_tuple_handler<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 <typename Signature> struct as_tuple_signature; template <typename R, typename... Args> struct as_tuple_signature<R(Args...)> { typedef R type(std::tuple<typename decay<Args>::type...>); }; #if defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) template <typename R, typename... Args> struct as_tuple_signature<R(Args...) &> { typedef R type(std::tuple<typename decay<Args>::type...>) &; }; template <typename R, typename... Args> struct as_tuple_signature<R(Args...) &&> { typedef R type(std::tuple<typename decay<Args>::type...>) &&; }; # if defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE) template <typename R, typename... Args> struct as_tuple_signature<R(Args...) noexcept> { typedef R type(std::tuple<typename decay<Args>::type...>) noexcept; }; template <typename R, typename... Args> struct as_tuple_signature<R(Args...) & noexcept> { typedef R type(std::tuple<typename decay<Args>::type...>) & noexcept; }; template <typename R, typename... Args> struct as_tuple_signature<R(Args...) && noexcept> { typedef R type(std::tuple<typename decay<Args>::type...>) && noexcept; }; # endif // defined(ASIO_HAS_NOEXCEPT_FUNCTION_TYPE) #endif // defined(ASIO_HAS_REF_QUALIFIED_FUNCTIONS) } // namespace detail #if !defined(GENERATING_DOCUMENTATION) template <typename CompletionToken, typename... Signatures> struct async_result<as_tuple_t<CompletionToken>, Signatures...> : async_result<CompletionToken, typename detail::as_tuple_signature<Signatures>::type...> { template <typename Initiation> struct init_wrapper { init_wrapper(Initiation init) : initiation_(ASIO_MOVE_CAST(Initiation)(init)) { } template <typename Handler, typename... Args> void operator()( ASIO_MOVE_ARG(Handler) handler, ASIO_MOVE_ARG(Args)... args) { ASIO_MOVE_CAST(Initiation)(initiation_)( detail::as_tuple_handler< typename decay<Handler>::type>( ASIO_MOVE_CAST(Handler)(handler)), ASIO_MOVE_CAST(Args)(args)...); } Initiation initiation_; }; template <typename Initiation, typename RawCompletionToken, typename... Args> static ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken, typename detail::as_tuple_signature<Signatures>::type...) initiate( ASIO_MOVE_ARG(Initiation) initiation, ASIO_MOVE_ARG(RawCompletionToken) token, ASIO_MOVE_ARG(Args)... args) ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate< typename conditional< is_const<typename remove_reference<RawCompletionToken>::type>::value, const CompletionToken, CompletionToken>::type, typename detail::as_tuple_signature<Signatures>::type...>( init_wrapper<typename decay<Initiation>::type>( ASIO_MOVE_CAST(Initiation)(initiation)), token.token_, ASIO_MOVE_CAST(Args)(args)...))) { return async_initiate< typename conditional< is_const<typename remove_reference<RawCompletionToken>::type>::value, const CompletionToken, CompletionToken>::type, typename detail::as_tuple_signature<Signatures>::type...>( init_wrapper<typename decay<Initiation>::type>( ASIO_MOVE_CAST(Initiation)(initiation)), token.token_, ASIO_MOVE_CAST(Args)(args)...); } }; #if defined(ASIO_MSVC) // Workaround for MSVC internal compiler error. template <typename CompletionToken, typename Signature> struct async_result<as_tuple_t<CompletionToken>, Signature> : async_result<CompletionToken, typename detail::as_tuple_signature<Signature>::type> { template <typename Initiation> struct init_wrapper { init_wrapper(Initiation init) : initiation_(ASIO_MOVE_CAST(Initiation)(init)) { } template <typename Handler, typename... Args> void operator()( ASIO_MOVE_ARG(Handler) handler, ASIO_MOVE_ARG(Args)... args) { ASIO_MOVE_CAST(Initiation)(initiation_)( detail::as_tuple_handler< typename decay<Handler>::type>( ASIO_MOVE_CAST(Handler)(handler)), ASIO_MOVE_CAST(Args)(args)...); } Initiation initiation_; }; template <typename Initiation, typename RawCompletionToken, typename... Args> static ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(CompletionToken, typename detail::as_tuple_signature<Signatures>::type...) initiate( ASIO_MOVE_ARG(Initiation) initiation, ASIO_MOVE_ARG(RawCompletionToken) token, ASIO_MOVE_ARG(Args)... args) ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX(( async_initiate< typename conditional< is_const<typename remove_reference<RawCompletionToken>::type>::value, const CompletionToken, CompletionToken>::type, typename detail::as_tuple_signature<Signature>::type>( init_wrapper<typename decay<Initiation>::type>( ASIO_MOVE_CAST(Initiation)(initiation)), token.token_, ASIO_MOVE_CAST(Args)(args)...))) { return async_initiate< typename conditional< is_const<typename remove_reference<RawCompletionToken>::type>::value, const CompletionToken, CompletionToken>::type, typename detail::as_tuple_signature<Signature>::type>( init_wrapper<typename decay<Initiation>::type>( ASIO_MOVE_CAST(Initiation)(initiation)), token.token_, ASIO_MOVE_CAST(Args)(args)...); } }; #endif // defined(ASIO_MSVC) template <template <typename, typename> class Associator, typename Handler, typename DefaultCandidate> struct associator<Associator, detail::as_tuple_handler<Handler>, DefaultCandidate> : Associator<Handler, DefaultCandidate> { static typename Associator<Handler, DefaultCandidate>::type get(const detail::as_tuple_handler<Handler>& h) ASIO_NOEXCEPT { return Associator<Handler, DefaultCandidate>::get(h.handler_); } static ASIO_AUTO_RETURN_TYPE_PREFIX2( typename Associator<Handler, DefaultCandidate>::type) get(const detail::as_tuple_handler<Handler>& h, const DefaultCandidate& c) ASIO_NOEXCEPT ASIO_AUTO_RETURN_TYPE_SUFFIX(( Associator<Handler, DefaultCandidate>::get(h.handler_, c))) { return Associator<Handler, DefaultCandidate>::get(h.handler_, c); } }; #endif // !defined(GENERATING_DOCUMENTATION) } // namespace asio #include "asio/detail/pop_options.hpp" #endif // ASIO_IMPL_AS_TUPLE_HPP