// // async_result.hpp // ~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2018 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_ASYNC_RESULT_HPP #define BOOST_ASIO_ASYNC_RESULT_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include #include #include #include namespace boost { namespace asio { /// An interface for customising the behaviour of an initiating function. /** * The async_result traits class is used for determining: * * @li the concrete completion handler type to be called at the end of the * asynchronous operation; * * @li the initiating function return type; and * * @li how the return value of the initiating function is obtained. * * The trait allows the handler and return types to be determined at the point * where the specific completion handler signature is known. * * This template may be specialised for user-defined completion token types. * The primary template assumes that the CompletionToken is the completion * handler. */ #if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) template #else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) template #endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) class async_result { public: #if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) /// The concrete completion handler type for the specific signature. typedef CompletionToken completion_handler_type; /// The return type of the initiating function. typedef void return_type; #else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) // For backward compatibility, determine the concrete completion handler type // by using the legacy handler_type trait. typedef typename handler_type::type completion_handler_type; // For backward compatibility, determine the initiating function return type // using the legacy single-parameter version of async_result. typedef typename async_result::type return_type; #endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) /// Construct an async result from a given handler. /** * When using a specalised async_result, the constructor has an opportunity * to initialise some state associated with the completion handler, which is * then returned from the initiating function. */ explicit async_result(completion_handler_type& h) #if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) // No data members to initialise. #else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) : legacy_result_(h) #endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) { (void)h; } /// Obtain the value to be returned from the initiating function. return_type get() { #if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) // Nothing to do. #else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) return legacy_result_.get(); #endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) } private: async_result(const async_result&) BOOST_ASIO_DELETED; async_result& operator=(const async_result&) BOOST_ASIO_DELETED; #if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) // No data members. #else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) async_result legacy_result_; #endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) }; #if !defined(BOOST_ASIO_NO_DEPRECATED) /// (Deprecated: Use two-parameter version of async_result.) An interface for /// customising the behaviour of an initiating function. /** * This template may be specialised for user-defined handler types. */ template class async_result { public: /// The return type of the initiating function. typedef void type; /// Construct an async result from a given handler. /** * When using a specalised async_result, the constructor has an opportunity * to initialise some state associated with the handler, which is then * returned from the initiating function. */ explicit async_result(Handler&) { } /// Obtain the value to be returned from the initiating function. type get() { } }; #endif // !defined(BOOST_ASIO_NO_DEPRECATED) /// Helper template to deduce the handler type from a CompletionToken, capture /// a local copy of the handler, and then create an async_result for the /// handler. template struct async_completion { /// The real handler type to be used for the asynchronous operation. typedef typename boost::asio::async_result< typename decay::type, Signature>::completion_handler_type completion_handler_type; #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Constructor. /** * The constructor creates the concrete completion handler and makes the link * between the handler and the asynchronous result. */ explicit async_completion(CompletionToken& token) : completion_handler(static_cast::value, completion_handler_type&, CompletionToken&&>::type>(token)), result(completion_handler) { } #else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) explicit async_completion(typename decay::type& token) : completion_handler(token), result(completion_handler) { } explicit async_completion(const typename decay::type& token) : completion_handler(token), result(completion_handler) { } #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// A copy of, or reference to, a real handler object. #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) typename conditional< is_same::value, completion_handler_type&, completion_handler_type>::type completion_handler; #else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) completion_handler_type completion_handler; #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// The result of the asynchronous operation's initiating function. async_result::type, Signature> result; }; namespace detail { template struct async_result_helper : async_result::type, Signature> { }; } // namespace detail } // namespace asio } // namespace boost #include #if defined(GENERATING_DOCUMENTATION) # define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \ void_or_deduced #elif defined(_MSC_VER) && (_MSC_VER < 1500) # define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \ typename ::boost::asio::detail::async_result_helper< \ ct, sig>::return_type #define BOOST_ASIO_HANDLER_TYPE(ct, sig) \ typename ::boost::asio::detail::async_result_helper< \ ct, sig>::completion_handler_type #else # define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \ typename ::boost::asio::async_result< \ typename ::boost::asio::decay::type, sig>::return_type #define BOOST_ASIO_HANDLER_TYPE(ct, sig) \ typename ::boost::asio::async_result< \ typename ::boost::asio::decay::type, sig>::completion_handler_type #endif #endif // BOOST_ASIO_ASYNC_RESULT_HPP