Chris@16: // Chris@16: // impl/use_future.hpp Chris@16: // ~~~~~~~~~~~~~~~~~~~ Chris@16: // Chris@101: // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: Chris@16: #ifndef BOOST_ASIO_IMPL_USE_FUTURE_HPP Chris@16: #define BOOST_ASIO_IMPL_USE_FUTURE_HPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace asio { Chris@16: namespace detail { Chris@16: Chris@16: // Completion handler to adapt a promise as a completion handler. Chris@16: template Chris@16: class promise_handler Chris@16: { Chris@16: public: Chris@16: // Construct from use_future special value. Chris@16: template Chris@16: promise_handler(use_future_t uf) Chris@16: : promise_(std::allocate_shared >( Chris@16: uf.get_allocator(), std::allocator_arg, uf.get_allocator())) Chris@16: { Chris@16: } Chris@16: Chris@16: void operator()(T t) Chris@16: { Chris@16: promise_->set_value(t); Chris@16: } Chris@16: Chris@16: void operator()(const boost::system::error_code& ec, T t) Chris@16: { Chris@16: if (ec) Chris@16: promise_->set_exception( Chris@16: std::make_exception_ptr( Chris@16: boost::system::system_error(ec))); Chris@16: else Chris@16: promise_->set_value(t); Chris@16: } Chris@16: Chris@16: //private: Chris@16: std::shared_ptr > promise_; Chris@16: }; Chris@16: Chris@16: // Completion handler to adapt a void promise as a completion handler. Chris@16: template <> Chris@16: class promise_handler Chris@16: { Chris@16: public: Chris@16: // Construct from use_future special value. Used during rebinding. Chris@16: template Chris@16: promise_handler(use_future_t uf) Chris@16: : promise_(std::allocate_shared >( Chris@16: uf.get_allocator(), std::allocator_arg, uf.get_allocator())) Chris@16: { Chris@16: } Chris@16: Chris@16: void operator()() Chris@16: { Chris@16: promise_->set_value(); Chris@16: } Chris@16: Chris@16: void operator()(const boost::system::error_code& ec) Chris@16: { Chris@16: if (ec) Chris@16: promise_->set_exception( Chris@16: std::make_exception_ptr( Chris@16: boost::system::system_error(ec))); Chris@16: else Chris@16: promise_->set_value(); Chris@16: } Chris@16: Chris@16: //private: Chris@16: std::shared_ptr > promise_; Chris@16: }; Chris@16: Chris@16: // Ensure any exceptions thrown from the handler are propagated back to the Chris@16: // caller via the future. Chris@16: template Chris@16: void asio_handler_invoke(Function f, promise_handler* h) Chris@16: { Chris@16: std::shared_ptr > p(h->promise_); Chris@16: try Chris@16: { Chris@16: f(); Chris@16: } Chris@16: catch (...) Chris@16: { Chris@16: p->set_exception(std::current_exception()); Chris@16: } Chris@16: } Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: #if !defined(GENERATING_DOCUMENTATION) Chris@16: Chris@16: // Handler traits specialisation for promise_handler. Chris@16: template Chris@16: class async_result > Chris@16: { Chris@16: public: Chris@16: // The initiating function will return a future. Chris@16: typedef std::future type; Chris@16: Chris@16: // Constructor creates a new promise for the async operation, and obtains the Chris@16: // corresponding future. Chris@16: explicit async_result(detail::promise_handler& h) Chris@16: { Chris@16: value_ = h.promise_->get_future(); Chris@16: } Chris@16: Chris@16: // Obtain the future to be returned from the initiating function. Chris@16: type get() { return std::move(value_); } Chris@16: Chris@16: private: Chris@16: type value_; Chris@16: }; Chris@16: Chris@16: // Handler type specialisation for use_future. Chris@16: template Chris@16: struct handler_type, ReturnType()> Chris@16: { Chris@16: typedef detail::promise_handler type; Chris@16: }; Chris@16: Chris@16: // Handler type specialisation for use_future. Chris@16: template Chris@16: struct handler_type, ReturnType(Arg1)> Chris@16: { Chris@16: typedef detail::promise_handler type; Chris@16: }; Chris@16: Chris@16: // Handler type specialisation for use_future. Chris@16: template Chris@16: struct handler_type, Chris@16: ReturnType(boost::system::error_code)> Chris@16: { Chris@16: typedef detail::promise_handler type; Chris@16: }; Chris@16: Chris@16: // Handler type specialisation for use_future. Chris@16: template Chris@16: struct handler_type, Chris@16: ReturnType(boost::system::error_code, Arg2)> Chris@16: { Chris@16: typedef detail::promise_handler type; Chris@16: }; Chris@16: Chris@16: #endif // !defined(GENERATING_DOCUMENTATION) Chris@16: Chris@16: } // namespace asio Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_ASIO_IMPL_USE_FUTURE_HPP