diff options
Diffstat (limited to 'boost/asio/async_result.hpp')
-rw-r--r-- | boost/asio/async_result.hpp | 169 |
1 files changed, 148 insertions, 21 deletions
diff --git a/boost/asio/async_result.hpp b/boost/asio/async_result.hpp index 6290b8462a..f49f2eb2e0 100644 --- a/boost/asio/async_result.hpp +++ b/boost/asio/async_result.hpp @@ -16,6 +16,7 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include <boost/asio/detail/config.hpp> +#include <boost/asio/detail/type_traits.hpp> #include <boost/asio/handler_type.hpp> #include <boost/asio/detail/push_options.hpp> @@ -25,10 +26,93 @@ 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 <typename CompletionToken, typename Signature> +#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION) +template <typename CompletionToken, typename Signature = void> +#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<CompletionToken, Signature>::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<completion_handler_type>::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<completion_handler_type> 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 <typename Handler> -class async_result +class async_result<Handler> { public: /// The return type of the initiating function. @@ -50,29 +134,65 @@ public: } }; -namespace detail { +#endif // !defined(BOOST_ASIO_NO_DEPRECATED) -// Helper template to deduce the true type of a handler, capture a local copy -// of the handler, and then create an async_result for the handler. -template <typename Handler, typename Signature> -struct async_result_init +/// 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 <typename CompletionToken, typename Signature> +struct async_completion { - explicit async_result_init(BOOST_ASIO_MOVE_ARG(Handler) orig_handler) - : handler(BOOST_ASIO_MOVE_CAST(Handler)(orig_handler)), - result(handler) + /// The real handler type to be used for the asynchronous operation. + typedef typename boost::asio::async_result< + typename decay<CompletionToken>::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<typename conditional< + is_same<CompletionToken, completion_handler_type>::value, + completion_handler_type&, CompletionToken&&>::type>(token)), + result(completion_handler) + { + } +#else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + explicit async_completion(typename decay<CompletionToken>::type& token) + : completion_handler(token), + result(completion_handler) { } - typename handler_type<Handler, Signature>::type handler; - async_result<typename handler_type<Handler, Signature>::type> result; + explicit async_completion(const typename decay<CompletionToken>::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<CompletionToken, completion_handler_type>::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<typename decay<CompletionToken>::type, Signature> result; }; -template <typename Handler, typename Signature> -struct async_result_type_helper +namespace detail { + +template <typename CompletionToken, typename Signature> +struct async_result_helper + : async_result<typename decay<CompletionToken>::type, Signature> { - typedef typename async_result< - typename handler_type<Handler, Signature>::type - >::type type; }; } // namespace detail @@ -82,15 +202,22 @@ struct async_result_type_helper #include <boost/asio/detail/pop_options.hpp> #if defined(GENERATING_DOCUMENTATION) -# define BOOST_ASIO_INITFN_RESULT_TYPE(h, sig) \ +# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \ void_or_deduced #elif defined(_MSC_VER) && (_MSC_VER < 1500) -# define BOOST_ASIO_INITFN_RESULT_TYPE(h, sig) \ - typename ::boost::asio::detail::async_result_type_helper<h, sig>::type +# 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(h, sig) \ +# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \ + typename ::boost::asio::async_result< \ + typename ::boost::asio::decay<ct>::type, sig>::return_type +#define BOOST_ASIO_HANDLER_TYPE(ct, sig) \ typename ::boost::asio::async_result< \ - typename ::boost::asio::handler_type<h, sig>::type>::type + typename ::boost::asio::decay<ct>::type, sig>::completion_handler_type #endif #endif // BOOST_ASIO_ASYNC_RESULT_HPP |