// // experimental/impl/as_single.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2021 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_EXPERIMENTAL_AS_SINGLE_HPP #define BOOST_ASIO_IMPL_EXPERIMENTAL_AS_SINGLE_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 #include #include namespace boost { namespace asio { namespace experimental { namespace detail { // Class to adapt a as_single_t as a completion handler. template class as_single_handler { public: typedef void result_type; template as_single_handler(as_single_t e) : handler_(BOOST_ASIO_MOVE_CAST(CompletionToken)(e.token_)) { } template as_single_handler(BOOST_ASIO_MOVE_ARG(RedirectedHandler) h) : handler_(BOOST_ASIO_MOVE_CAST(RedirectedHandler)(h)) { } void operator()() { handler_(); } template void operator()(BOOST_ASIO_MOVE_ARG(Arg) arg) { handler_(BOOST_ASIO_MOVE_CAST(Arg)(arg)); } template void operator()(BOOST_ASIO_MOVE_ARG(Args)... args) { handler_(std::make_tuple(BOOST_ASIO_MOVE_CAST(Args)(args)...)); } //private: Handler handler_; }; template inline asio_handler_allocate_is_deprecated asio_handler_allocate(std::size_t size, as_single_handler* this_handler) { #if defined(BOOST_ASIO_NO_DEPRECATED) boost_asio_handler_alloc_helpers::allocate(size, this_handler->handler_); return asio_handler_allocate_is_no_longer_used(); #else // defined(BOOST_ASIO_NO_DEPRECATED) return boost_asio_handler_alloc_helpers::allocate( size, this_handler->handler_); #endif // defined(BOOST_ASIO_NO_DEPRECATED) } template inline asio_handler_deallocate_is_deprecated asio_handler_deallocate(void* pointer, std::size_t size, as_single_handler* this_handler) { boost_asio_handler_alloc_helpers::deallocate( pointer, size, this_handler->handler_); #if defined(BOOST_ASIO_NO_DEPRECATED) return asio_handler_deallocate_is_no_longer_used(); #endif // defined(BOOST_ASIO_NO_DEPRECATED) } template inline bool asio_handler_is_continuation( as_single_handler* this_handler) { return boost_asio_handler_cont_helpers::is_continuation( this_handler->handler_); } template inline asio_handler_invoke_is_deprecated asio_handler_invoke(Function& function, as_single_handler* this_handler) { boost_asio_handler_invoke_helpers::invoke( function, this_handler->handler_); #if defined(BOOST_ASIO_NO_DEPRECATED) return asio_handler_invoke_is_no_longer_used(); #endif // defined(BOOST_ASIO_NO_DEPRECATED) } template inline asio_handler_invoke_is_deprecated asio_handler_invoke(const Function& function, as_single_handler* this_handler) { boost_asio_handler_invoke_helpers::invoke( function, this_handler->handler_); #if defined(BOOST_ASIO_NO_DEPRECATED) return asio_handler_invoke_is_no_longer_used(); #endif // defined(BOOST_ASIO_NO_DEPRECATED) } template struct as_single_signature { typedef Signature type; }; template struct as_single_signature { typedef R type(); }; template struct as_single_signature { typedef R type(Arg); }; template struct as_single_signature { typedef R type(std::tuple::type...>); }; } // namespace detail } // namespace experimental #if !defined(GENERATING_DOCUMENTATION) template struct async_result, Signature> { typedef typename async_result::type> ::return_type return_type; template struct init_wrapper { init_wrapper(Initiation init) : initiation_(BOOST_ASIO_MOVE_CAST(Initiation)(init)) { } template void operator()( BOOST_ASIO_MOVE_ARG(Handler) handler, BOOST_ASIO_MOVE_ARG(Args)... args) { BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)( experimental::detail::as_single_handler< typename decay::type>( BOOST_ASIO_MOVE_CAST(Handler)(handler)), BOOST_ASIO_MOVE_CAST(Args)(args)...); } Initiation initiation_; }; template static return_type initiate( BOOST_ASIO_MOVE_ARG(Initiation) initiation, BOOST_ASIO_MOVE_ARG(RawCompletionToken) token, BOOST_ASIO_MOVE_ARG(Args)... args) { return async_initiate::type>( init_wrapper::type>( BOOST_ASIO_MOVE_CAST(Initiation)(initiation)), token.token_, BOOST_ASIO_MOVE_CAST(Args)(args)...); } }; template struct associated_executor< experimental::detail::as_single_handler, Executor> : detail::associated_executor_forwarding_base { typedef typename associated_executor::type type; static type get( const experimental::detail::as_single_handler& h, const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT { return associated_executor::get(h.handler_, ex); } }; template struct associated_allocator< experimental::detail::as_single_handler, Allocator> { typedef typename associated_allocator::type type; static type get( const experimental::detail::as_single_handler& h, const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT { return associated_allocator::get(h.handler_, a); } }; #endif // !defined(GENERATING_DOCUMENTATION) } // namespace asio } // namespace boost #include #endif // BOOST_ASIO_IMPL_EXPERIMENTAL_AS_SINGLE_HPP