| // |
| // impl/use_future.hpp |
| // ~~~~~~~~~~~~~~~~~~~ |
| // |
| // Copyright (c) 2003-2016 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_USE_FUTURE_HPP |
| #define ASIO_IMPL_USE_FUTURE_HPP |
| |
| #if defined(_MSC_VER) && (_MSC_VER >= 1200) |
| # pragma once |
| #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) |
| |
| #include "asio/detail/config.hpp" |
| #include <future> |
| #include <tuple> |
| #include "asio/async_result.hpp" |
| #include "asio/detail/memory.hpp" |
| #include "asio/error_code.hpp" |
| #include "asio/packaged_task.hpp" |
| #include "asio/system_error.hpp" |
| #include "asio/system_executor.hpp" |
| |
| #include "asio/detail/push_options.hpp" |
| |
| namespace asio { |
| namespace detail { |
| |
| #if defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| |
| template <typename T, typename F, typename... Args> |
| inline void promise_invoke_and_set(std::promise<T>& p, |
| F& f, ASIO_MOVE_ARG(Args)... args) |
| { |
| #if !defined(ASIO_NO_EXCEPTIONS) |
| try |
| #endif // !defined(ASIO_NO_EXCEPTIONS) |
| { |
| p.set_value(f(ASIO_MOVE_CAST(Args)(args)...)); |
| } |
| #if !defined(ASIO_NO_EXCEPTIONS) |
| catch (...) |
| { |
| p.set_exception(std::current_exception()); |
| } |
| #endif // !defined(ASIO_NO_EXCEPTIONS) |
| } |
| |
| template <typename F, typename... Args> |
| inline void promise_invoke_and_set(std::promise<void>& p, |
| F& f, ASIO_MOVE_ARG(Args)... args) |
| { |
| #if !defined(ASIO_NO_EXCEPTIONS) |
| try |
| #endif // !defined(ASIO_NO_EXCEPTIONS) |
| { |
| f(ASIO_MOVE_CAST(Args)(args)...); |
| p.set_value(); |
| } |
| #if !defined(ASIO_NO_EXCEPTIONS) |
| catch (...) |
| { |
| p.set_exception(std::current_exception()); |
| } |
| #endif // !defined(ASIO_NO_EXCEPTIONS) |
| } |
| |
| #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| |
| template <typename T, typename F> |
| inline void promise_invoke_and_set(std::promise<T>& p, F& f) |
| { |
| #if !defined(ASIO_NO_EXCEPTIONS) |
| try |
| #endif // !defined(ASIO_NO_EXCEPTIONS) |
| { |
| p.set_value(f()); |
| } |
| #if !defined(ASIO_NO_EXCEPTIONS) |
| catch (...) |
| { |
| p.set_exception(std::current_exception()); |
| } |
| #endif // !defined(ASIO_NO_EXCEPTIONS) |
| } |
| |
| template <typename F, typename Args> |
| inline void promise_invoke_and_set(std::promise<void>& p, F& f) |
| { |
| #if !defined(ASIO_NO_EXCEPTIONS) |
| try |
| #endif // !defined(ASIO_NO_EXCEPTIONS) |
| { |
| f(); |
| p.set_value(); |
| #if !defined(ASIO_NO_EXCEPTIONS) |
| } |
| catch (...) |
| { |
| p.set_exception(std::current_exception()); |
| } |
| #endif // !defined(ASIO_NO_EXCEPTIONS) |
| } |
| |
| #if defined(ASIO_NO_EXCEPTIONS) |
| |
| #define ASIO_PRIVATE_PROMISE_INVOKE_DEF(n) \ |
| template <typename T, typename F, ASIO_VARIADIC_TPARAMS(n)> \ |
| inline void promise_invoke_and_set(std::promise<T>& p, \ |
| F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \ |
| { \ |
| p.set_value(f(ASIO_VARIADIC_MOVE_ARGS(n))); \ |
| } \ |
| \ |
| template <typename F, ASIO_VARIADIC_TPARAMS(n)> \ |
| inline void promise_invoke_and_set(std::promise<void>& p, \ |
| F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \ |
| { \ |
| f(ASIO_VARIADIC_MOVE_ARGS(n)); \ |
| p.set_value(); \ |
| } \ |
| /**/ |
| ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_PROMISE_INVOKE_DEF) |
| #undef ASIO_PRIVATE_PROMISE_INVOKE_DEF |
| |
| #else // defined(ASIO_NO_EXCEPTIONS) |
| |
| #define ASIO_PRIVATE_PROMISE_INVOKE_DEF(n) \ |
| template <typename T, typename F, ASIO_VARIADIC_TPARAMS(n)> \ |
| inline void promise_invoke_and_set(std::promise<T>& p, \ |
| F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \ |
| { \ |
| try \ |
| { \ |
| p.set_value(f(ASIO_VARIADIC_MOVE_ARGS(n))); \ |
| } \ |
| catch (...) \ |
| { \ |
| p.set_exception(std::current_exception()); \ |
| } \ |
| } \ |
| \ |
| template <typename F, ASIO_VARIADIC_TPARAMS(n)> \ |
| inline void promise_invoke_and_set(std::promise<void>& p, \ |
| F& f, ASIO_VARIADIC_MOVE_PARAMS(n)) \ |
| { \ |
| try \ |
| { \ |
| f(ASIO_VARIADIC_MOVE_ARGS(n)); \ |
| p.set_value(); \ |
| } \ |
| catch (...) \ |
| { \ |
| p.set_exception(std::current_exception()); \ |
| } \ |
| } \ |
| /**/ |
| ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_PROMISE_INVOKE_DEF) |
| #undef ASIO_PRIVATE_PROMISE_INVOKE_DEF |
| |
| #endif // defined(ASIO_NO_EXCEPTIONS) |
| |
| #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| |
| // A function object adapter to invoke a nullary function object and capture |
| // any exception thrown into a promise. |
| template <typename T, typename F> |
| class promise_invoker |
| { |
| public: |
| promise_invoker(const shared_ptr<std::promise<T> >& p, |
| ASIO_MOVE_ARG(F) f) |
| : p_(p), f_(f) |
| { |
| } |
| |
| void operator()() |
| { |
| #if !defined(ASIO_NO_EXCEPTIONS) |
| try |
| #endif // !defined(ASIO_NO_EXCEPTIONS) |
| { |
| f_(); |
| } |
| #if !defined(ASIO_NO_EXCEPTIONS) |
| catch (...) |
| { |
| p_->set_exception(std::current_exception()); |
| } |
| #endif // !defined(ASIO_NO_EXCEPTIONS) |
| } |
| |
| private: |
| shared_ptr<std::promise<T> > p_; |
| typename decay<F>::type f_; |
| }; |
| |
| // An executor that adapts the system_executor to capture any exeption thrown |
| // by a submitted function object and save it into a promise. |
| template <typename T> |
| class promise_executor |
| { |
| public: |
| explicit promise_executor(const shared_ptr<std::promise<T> >& p) |
| : p_(p) |
| { |
| } |
| |
| execution_context& context() const ASIO_NOEXCEPT |
| { |
| return system_executor().context(); |
| } |
| |
| void on_work_started() const ASIO_NOEXCEPT {} |
| void on_work_finished() const ASIO_NOEXCEPT {} |
| |
| template <typename F, typename A> |
| void dispatch(ASIO_MOVE_ARG(F) f, const A&) const |
| { |
| promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f))(); |
| } |
| |
| template <typename F, typename A> |
| void post(ASIO_MOVE_ARG(F) f, const A& a) const |
| { |
| system_executor().post( |
| promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f)), a); |
| } |
| |
| template <typename F, typename A> |
| void defer(ASIO_MOVE_ARG(F) f, const A& a) const |
| { |
| system_executor().defer( |
| promise_invoker<T, F>(p_, ASIO_MOVE_CAST(F)(f)), a); |
| } |
| |
| friend bool operator==(const promise_executor& a, |
| const promise_executor& b) ASIO_NOEXCEPT |
| { |
| return a.p_ == b.p_; |
| } |
| |
| friend bool operator!=(const promise_executor& a, |
| const promise_executor& b) ASIO_NOEXCEPT |
| { |
| return a.p_ != b.p_; |
| } |
| |
| private: |
| shared_ptr<std::promise<T> > p_; |
| }; |
| |
| // The base class for all completion handlers that create promises. |
| template <typename T> |
| class promise_creator |
| { |
| public: |
| typedef promise_executor<T> executor_type; |
| |
| executor_type get_executor() const ASIO_NOEXCEPT |
| { |
| return executor_type(p_); |
| } |
| |
| typedef std::future<T> future_type; |
| |
| future_type get_future() |
| { |
| return p_->get_future(); |
| } |
| |
| protected: |
| template <typename Allocator> |
| void create_promise(const Allocator& a) |
| { |
| p_ = std::allocate_shared<std::promise<T>>( |
| typename Allocator::template rebind<char>::other(a), |
| std::allocator_arg, |
| typename Allocator::template rebind<char>::other(a)); |
| } |
| |
| shared_ptr<std::promise<T> > p_; |
| }; |
| |
| // For completion signature void(). |
| class promise_handler_0 |
| : public promise_creator<void> |
| { |
| public: |
| void operator()() |
| { |
| this->p_->set_value(); |
| } |
| }; |
| |
| // For completion signature void(error_code). |
| class promise_handler_ec_0 |
| : public promise_creator<void> |
| { |
| public: |
| void operator()(const asio::error_code& ec) |
| { |
| if (ec) |
| { |
| this->p_->set_exception( |
| std::make_exception_ptr( |
| asio::system_error(ec))); |
| } |
| else |
| { |
| this->p_->set_value(); |
| } |
| } |
| }; |
| |
| // For completion signature void(exception_ptr). |
| class promise_handler_ex_0 |
| : public promise_creator<void> |
| { |
| public: |
| void operator()(const std::exception_ptr& ex) |
| { |
| if (ex) |
| { |
| this->p_->set_exception(ex); |
| } |
| else |
| { |
| this->p_->set_value(); |
| } |
| } |
| }; |
| |
| // For completion signature void(T). |
| template <typename T> |
| class promise_handler_1 |
| : public promise_creator<T> |
| { |
| public: |
| template <typename Arg> |
| void operator()(ASIO_MOVE_ARG(Arg) arg) |
| { |
| this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg)); |
| } |
| }; |
| |
| // For completion signature void(error_code, T). |
| template <typename T> |
| class promise_handler_ec_1 |
| : public promise_creator<T> |
| { |
| public: |
| template <typename Arg> |
| void operator()(const asio::error_code& ec, |
| ASIO_MOVE_ARG(Arg) arg) |
| { |
| if (ec) |
| { |
| this->p_->set_exception( |
| std::make_exception_ptr( |
| asio::system_error(ec))); |
| } |
| else |
| this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg)); |
| } |
| }; |
| |
| // For completion signature void(exception_ptr, T). |
| template <typename T> |
| class promise_handler_ex_1 |
| : public promise_creator<T> |
| { |
| public: |
| template <typename Arg> |
| void operator()(const std::exception_ptr& ex, |
| ASIO_MOVE_ARG(Arg) arg) |
| { |
| if (ex) |
| this->p_->set_exception(ex); |
| else |
| this->p_->set_value(ASIO_MOVE_CAST(Arg)(arg)); |
| } |
| }; |
| |
| // For completion signature void(T1, ..., Tn); |
| template <typename T> |
| class promise_handler_n |
| : public promise_creator<T> |
| { |
| public: |
| #if defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| |
| template <typename... Args> |
| void operator()(ASIO_MOVE_ARG(Args)... args) |
| { |
| this->p_->set_value( |
| std::forward_as_tuple( |
| ASIO_MOVE_CAST(Args)(args)...)); |
| } |
| |
| #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| |
| #define ASIO_PRIVATE_CALL_OP_DEF(n) \ |
| template <ASIO_VARIADIC_TPARAMS(n)> \ |
| void operator()(ASIO_VARIADIC_MOVE_PARAMS(n)) \ |
| {\ |
| this->p_->set_value( \ |
| std::forward_as_tuple( \ |
| ASIO_VARIADIC_MOVE_ARGS(n))); \ |
| } \ |
| /**/ |
| ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF) |
| #undef ASIO_PRIVATE_CALL_OP_DEF |
| |
| #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| }; |
| |
| // For completion signature void(error_code, T1, ..., Tn); |
| template <typename T> |
| class promise_handler_ec_n |
| : public promise_creator<T> |
| { |
| public: |
| #if defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| |
| template <typename... Args> |
| void operator()(const asio::error_code& ec, |
| ASIO_MOVE_ARG(Args)... args) |
| { |
| if (ec) |
| { |
| this->p_->set_exception( |
| std::make_exception_ptr( |
| asio::system_error(ec))); |
| } |
| else |
| { |
| this->p_->set_value( |
| std::forward_as_tuple( |
| ASIO_MOVE_CAST(Args)(args)...)); |
| } |
| } |
| |
| #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| |
| #define ASIO_PRIVATE_CALL_OP_DEF(n) \ |
| template <ASIO_VARIADIC_TPARAMS(n)> \ |
| void operator()(const asio::error_code& ec, \ |
| ASIO_VARIADIC_MOVE_PARAMS(n)) \ |
| {\ |
| if (ec) \ |
| { \ |
| this->p_->set_exception( \ |
| std::make_exception_ptr( \ |
| asio::system_error(ec))); \ |
| } \ |
| else \ |
| { \ |
| this->p_->set_value( \ |
| std::forward_as_tuple( \ |
| ASIO_VARIADIC_MOVE_ARGS(n))); \ |
| } \ |
| } \ |
| /**/ |
| ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF) |
| #undef ASIO_PRIVATE_CALL_OP_DEF |
| |
| #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| }; |
| |
| // For completion signature void(exception_ptr, T1, ..., Tn); |
| template <typename T> |
| class promise_handler_ex_n |
| : public promise_creator<T> |
| { |
| public: |
| #if defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| |
| template <typename... Args> |
| void operator()(const std::exception_ptr& ex, |
| ASIO_MOVE_ARG(Args)... args) |
| { |
| if (ex) |
| this->p_->set_exception(ex); |
| else |
| { |
| this->p_->set_value( |
| std::forward_as_tuple( |
| ASIO_MOVE_CAST(Args)(args)...)); |
| } |
| } |
| |
| #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| |
| #define ASIO_PRIVATE_CALL_OP_DEF(n) \ |
| template <ASIO_VARIADIC_TPARAMS(n)> \ |
| void operator()(const std::exception_ptr& ex, \ |
| ASIO_VARIADIC_MOVE_PARAMS(n)) \ |
| {\ |
| if (ex) \ |
| this->p_->set_exception(ex); \ |
| else \ |
| { \ |
| this->p_->set_value( \ |
| std::forward_as_tuple( \ |
| ASIO_VARIADIC_MOVE_ARGS(n))); \ |
| } \ |
| } \ |
| /**/ |
| ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF) |
| #undef ASIO_PRIVATE_CALL_OP_DEF |
| |
| #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| }; |
| |
| // Helper template to choose the appropriate concrete promise handler |
| // implementation based on the supplied completion signature. |
| template <typename> class promise_handler_selector; |
| |
| template <> |
| class promise_handler_selector<void()> |
| : public promise_handler_0 {}; |
| |
| template <> |
| class promise_handler_selector<void(asio::error_code)> |
| : public promise_handler_ec_0 {}; |
| |
| template <> |
| class promise_handler_selector<void(std::exception_ptr)> |
| : public promise_handler_ex_0 {}; |
| |
| template <typename Arg> |
| class promise_handler_selector<void(Arg)> |
| : public promise_handler_1<Arg> {}; |
| |
| template <typename Arg> |
| class promise_handler_selector<void(asio::error_code, Arg)> |
| : public promise_handler_ec_1<Arg> {}; |
| |
| template <typename Arg> |
| class promise_handler_selector<void(std::exception_ptr, Arg)> |
| : public promise_handler_ex_1<Arg> {}; |
| |
| template <typename... Arg> |
| class promise_handler_selector<void(Arg...)> |
| : public promise_handler_n<std::tuple<Arg...> > {}; |
| |
| template <typename... Arg> |
| class promise_handler_selector<void(asio::error_code, Arg...)> |
| : public promise_handler_ec_n<std::tuple<Arg...> > {}; |
| |
| template <typename... Arg> |
| class promise_handler_selector<void(std::exception_ptr, Arg...)> |
| : public promise_handler_ex_n<std::tuple<Arg...> > {}; |
| |
| // Completion handlers produced from the use_future completion token, when not |
| // using use_future::operator(). |
| template <typename Signature, typename Allocator> |
| class promise_handler |
| : public promise_handler_selector<Signature> |
| { |
| public: |
| typedef Allocator allocator_type; |
| typedef void result_type; |
| |
| promise_handler(use_future_t<Allocator> u) |
| : allocator_(u.get_allocator()) |
| { |
| this->create_promise(allocator_); |
| } |
| |
| allocator_type get_allocator() const ASIO_NOEXCEPT |
| { |
| return allocator_; |
| } |
| |
| private: |
| Allocator allocator_; |
| }; |
| |
| template <typename Function, typename Signature, typename Allocator> |
| inline void asio_handler_invoke(Function& f, |
| promise_handler<Signature, Allocator>* h) |
| { |
| typename promise_handler<Signature, Allocator>::executor_type |
| ex(h->get_executor()); |
| ex.dispatch(ASIO_MOVE_CAST(Function)(f), std::allocator<void>()); |
| } |
| |
| template <typename Function, typename Signature, typename Allocator> |
| inline void asio_handler_invoke(const Function& f, |
| promise_handler<Signature, Allocator>* h) |
| { |
| typename promise_handler<Signature, Allocator>::executor_type |
| ex(h->get_executor()); |
| ex.dispatch(f, std::allocator<void>()); |
| } |
| |
| // Helper base class for async_result specialisation. |
| template <typename Signature, typename Allocator> |
| class promise_async_result |
| { |
| public: |
| typedef promise_handler<Signature, Allocator> completion_handler_type; |
| typedef typename completion_handler_type::future_type return_type; |
| |
| explicit promise_async_result(completion_handler_type& h) |
| : future_(h.get_future()) |
| { |
| } |
| |
| return_type get() |
| { |
| return ASIO_MOVE_CAST(return_type)(future_); |
| } |
| |
| private: |
| return_type future_; |
| }; |
| |
| // Return value from use_future::operator(). |
| template <typename Function, typename Allocator> |
| class packaged_token |
| { |
| public: |
| packaged_token(Function f, const Allocator& a) |
| : function_(ASIO_MOVE_CAST(Function)(f)), |
| allocator_(a) |
| { |
| } |
| |
| //private: |
| Function function_; |
| Allocator allocator_; |
| }; |
| |
| // Completion handlers produced from the use_future completion token, when |
| // using use_future::operator(). |
| template <typename Function, typename Allocator, typename Result> |
| class packaged_handler |
| : public promise_creator<Result> |
| { |
| public: |
| typedef Allocator allocator_type; |
| typedef void result_type; |
| |
| packaged_handler(packaged_token<Function, Allocator> t) |
| : function_(ASIO_MOVE_CAST(Function)(t.function_)), |
| allocator_(t.allocator_) |
| { |
| this->create_promise(allocator_); |
| } |
| |
| allocator_type get_allocator() const ASIO_NOEXCEPT |
| { |
| return allocator_; |
| } |
| |
| #if defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| |
| template <typename... Args> |
| void operator()(ASIO_MOVE_ARG(Args)... args) |
| { |
| (promise_invoke_and_set)(*this->p_, |
| function_, ASIO_MOVE_CAST(Args)(args)...); |
| } |
| |
| #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| |
| void operator()() |
| { |
| (promise_invoke_and_set)(*this->p_, function_); |
| } |
| |
| #define ASIO_PRIVATE_CALL_OP_DEF(n) \ |
| template <ASIO_VARIADIC_TPARAMS(n)> \ |
| void operator()(ASIO_VARIADIC_MOVE_PARAMS(n)) \ |
| {\ |
| (promise_invoke_and_set)(*this->p_, \ |
| function_, ASIO_VARIADIC_MOVE_ARGS(n)); \ |
| } \ |
| /**/ |
| ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CALL_OP_DEF) |
| #undef ASIO_PRIVATE_CALL_OP_DEF |
| |
| #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| |
| private: |
| Function function_; |
| Allocator allocator_; |
| }; |
| |
| template <typename Function, |
| typename Function1, typename Allocator, typename Result> |
| inline void asio_handler_invoke(Function& f, |
| packaged_handler<Function1, Allocator, Result>* h) |
| { |
| typename packaged_handler<Function1, Allocator, Result>::executor_type |
| ex(h->get_executor()); |
| ex.dispatch(ASIO_MOVE_CAST(Function)(f), std::allocator<void>()); |
| } |
| |
| template <typename Function, |
| typename Function1, typename Allocator, typename Result> |
| inline void asio_handler_invoke(const Function& f, |
| packaged_handler<Function1, Allocator, Result>* h) |
| { |
| typename packaged_handler<Function1, Allocator, Result>::executor_type |
| ex(h->get_executor()); |
| ex.dispatch(f, std::allocator<void>()); |
| } |
| |
| // Helper base class for async_result specialisation. |
| template <typename Function, typename Allocator, typename Result> |
| class packaged_async_result |
| { |
| public: |
| typedef packaged_handler<Function, Allocator, Result> completion_handler_type; |
| typedef typename completion_handler_type::future_type return_type; |
| |
| explicit packaged_async_result(completion_handler_type& h) |
| : future_(h.get_future()) |
| { |
| } |
| |
| return_type get() |
| { |
| return ASIO_MOVE_CAST(return_type)(future_); |
| } |
| |
| private: |
| return_type future_; |
| }; |
| |
| } // namespace detail |
| |
| template <typename Allocator> template <typename Function> |
| inline detail::packaged_token<typename decay<Function>::type, Allocator> |
| use_future_t<Allocator>::operator()(ASIO_MOVE_ARG(Function) f) const |
| { |
| return detail::packaged_token<typename decay<Function>::type, Allocator>( |
| ASIO_MOVE_CAST(Function)(f), allocator_); |
| } |
| |
| #if !defined(GENERATING_DOCUMENTATION) |
| |
| #if defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| |
| template <typename Allocator, typename Result, typename... Args> |
| class async_result<use_future_t<Allocator>, Result(Args...)> |
| : public detail::promise_async_result< |
| void(typename decay<Args>::type...), Allocator> |
| { |
| public: |
| explicit async_result( |
| typename detail::promise_async_result<void(typename decay<Args>::type...), |
| Allocator>::completion_handler_type& h) |
| : detail::promise_async_result< |
| void(typename decay<Args>::type...), Allocator>(h) |
| { |
| } |
| }; |
| |
| template <typename Function, typename Allocator, |
| typename Result, typename... Args> |
| class async_result<detail::packaged_token<Function, Allocator>, Result(Args...)> |
| : public detail::packaged_async_result<Function, Allocator, |
| typename result_of<Function(Args...)>::type> |
| { |
| public: |
| explicit async_result( |
| typename detail::packaged_async_result<Function, Allocator, |
| typename result_of<Function(Args...)>::type>::completion_handler_type& h) |
| : detail::packaged_async_result<Function, Allocator, |
| typename result_of<Function(Args...)>::type>(h) |
| { |
| } |
| }; |
| |
| #else // defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| |
| template <typename Allocator, typename Result> |
| class async_result<use_future_t<Allocator>, Result()> |
| : public detail::promise_async_result<void(), Allocator> |
| { |
| public: |
| explicit async_result( |
| typename detail::promise_async_result< |
| void(), Allocator>::completion_handler_type& h) |
| : detail::promise_async_result<void(), Allocator>(h) |
| { |
| } |
| }; |
| |
| template <typename Function, typename Allocator, typename Result> |
| class async_result<detail::packaged_token<Function, Allocator>, Result()> |
| : public detail::packaged_async_result<Function, Allocator, |
| typename result_of<Function()>::type> |
| { |
| public: |
| explicit async_result( |
| typename detail::packaged_async_result<Function, Allocator, |
| typename result_of<Function()>::type>::completion_handler_type& h) |
| : detail::packaged_async_result<Function, Allocator, |
| typename result_of<Function()>::type>(h) |
| { |
| } |
| }; |
| |
| #define ASIO_PRIVATE_ASYNC_RESULT_DEF(n) \ |
| template <typename Allocator, \ |
| typename Result, ASIO_VARIADIC_TPARAMS(n)> \ |
| class async_result<use_future_t<Allocator>, \ |
| Result(ASIO_VARIADIC_TARGS(n))> \ |
| : public detail::promise_async_result< \ |
| void(ASIO_VARIADIC_DECAY(n)), Allocator> \ |
| { \ |
| public: \ |
| explicit async_result( \ |
| typename detail::promise_async_result< \ |
| void(ASIO_VARIADIC_DECAY(n)), \ |
| Allocator>::completion_handler_type& h) \ |
| : detail::promise_async_result< \ |
| void(ASIO_VARIADIC_DECAY(n)), Allocator>(h) \ |
| { \ |
| } \ |
| }; \ |
| \ |
| template <typename Function, typename Allocator, \ |
| typename Result, ASIO_VARIADIC_TPARAMS(n)> \ |
| class async_result<detail::packaged_token<Function, Allocator>, \ |
| Result(ASIO_VARIADIC_TARGS(n))> \ |
| : public detail::packaged_async_result<Function, Allocator, \ |
| typename result_of<Function(ASIO_VARIADIC_TARGS(n))>::type> \ |
| { \ |
| public: \ |
| explicit async_result( \ |
| typename detail::packaged_async_result<Function, Allocator, \ |
| typename result_of<Function(ASIO_VARIADIC_TARGS(n))>::type \ |
| >::completion_handler_type& h) \ |
| : detail::packaged_async_result<Function, Allocator, \ |
| typename result_of<Function(ASIO_VARIADIC_TARGS(n))>::type>(h) \ |
| { \ |
| } \ |
| }; \ |
| /**/ |
| ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ASYNC_RESULT_DEF) |
| #undef ASIO_PRIVATE_ASYNC_RESULT_DEF |
| |
| #endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) |
| |
| #if !defined(ASIO_NO_DEPRECATED) |
| |
| template <typename Allocator, typename Signature> |
| struct handler_type<use_future_t<Allocator>, Signature> |
| { |
| typedef typename async_result<use_future_t<Allocator>, |
| Signature>::completion_handler_type type; |
| }; |
| |
| template <typename Signature, typename Allocator> |
| class async_result<detail::promise_handler<Signature, Allocator> > |
| : public detail::promise_async_result<Signature, Allocator> |
| { |
| public: |
| typedef typename detail::promise_async_result< |
| Signature, Allocator>::return_type type; |
| |
| explicit async_result( |
| typename detail::promise_async_result< |
| Signature, Allocator>::completion_handler_type& h) |
| : detail::promise_async_result<Signature, Allocator>(h) |
| { |
| } |
| }; |
| |
| template <typename Function, typename Allocator, typename Signature> |
| struct handler_type<detail::packaged_token<Function, Allocator>, Signature> |
| { |
| typedef typename async_result<detail::packaged_token<Function, Allocator>, |
| Signature>::completion_handler_type type; |
| }; |
| |
| template <typename Function, typename Allocator, typename Result> |
| class async_result<detail::packaged_handler<Function, Allocator, Result> > |
| : public detail::packaged_async_result<Function, Allocator, Result> |
| { |
| public: |
| typedef typename detail::packaged_async_result< |
| Function, Allocator, Result>::return_type type; |
| |
| explicit async_result( |
| typename detail::packaged_async_result< |
| Function, Allocator, Result>::completion_handler_type& h) |
| : detail::packaged_async_result<Function, Allocator, Result>(h) |
| { |
| } |
| }; |
| |
| #endif // !defined(ASIO_NO_DEPRECATED) |
| |
| #endif // !defined(GENERATING_DOCUMENTATION) |
| |
| } // namespace asio |
| |
| #include "asio/detail/pop_options.hpp" |
| |
| #endif // ASIO_IMPL_USE_FUTURE_HPP |