#include <tuple>
#include <boost/asio/async_result.hpp>
#include <boost/asio/detail/memory.hpp>
+#include <boost/asio/dispatch.hpp>
#include <boost/system/error_code.hpp>
+#include <boost/asio/execution.hpp>
#include <boost/asio/packaged_task.hpp>
#include <boost/system/system_error.hpp>
#include <boost/asio/system_executor.hpp>
// 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>
+template <typename T, typename Blocking = execution::blocking_t::possibly_t>
class promise_executor
{
public:
{
}
+ static BOOST_ASIO_CONSTEXPR Blocking query(execution::blocking_t)
+ {
+ return Blocking();
+ }
+
+ promise_executor<T, execution::blocking_t::possibly_t>
+ require(execution::blocking_t::possibly_t) const
+ {
+ return promise_executor<T, execution::blocking_t::possibly_t>(p_);
+ }
+
+ promise_executor<T, execution::blocking_t::never_t>
+ require(execution::blocking_t::never_t) const
+ {
+ return promise_executor<T, execution::blocking_t::never_t>(p_);
+ }
+
+ template <typename F>
+ void execute(BOOST_ASIO_MOVE_ARG(F) f) const
+ {
+ execution::execute(
+ boost::asio::require(system_executor(), Blocking()),
+ promise_invoker<T, F>(p_, BOOST_ASIO_MOVE_CAST(F)(f)));
+ }
+
+#if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
execution_context& context() const BOOST_ASIO_NOEXCEPT
{
return system_executor().context();
system_executor().defer(
promise_invoker<T, F>(p_, BOOST_ASIO_MOVE_CAST(F)(f)), a);
}
+#endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
friend bool operator==(const promise_executor& a,
const promise_executor& b) BOOST_ASIO_NOEXCEPT
: public promise_handler_ex_n< \
std::tuple<Arg, BOOST_ASIO_VARIADIC_TARGS(n)> > {}; \
/**/
- BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_PROMISE_SELECTOR_DEF)
+ BOOST_ASIO_VARIADIC_GENERATE_5(BOOST_ASIO_PRIVATE_PROMISE_SELECTOR_DEF)
#undef BOOST_ASIO_PRIVATE_PROMISE_SELECTOR_DEF
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
Allocator allocator_;
};
+template <typename Function>
+struct promise_function_wrapper
+{
+ explicit promise_function_wrapper(Function& f)
+ : function_(BOOST_ASIO_MOVE_CAST(Function)(f))
+ {
+ }
+
+ explicit promise_function_wrapper(const Function& f)
+ : function_(f)
+ {
+ }
+
+ void operator()()
+ {
+ function_();
+ }
+
+ Function function_;
+};
+
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+
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(BOOST_ASIO_MOVE_CAST(Function)(f), std::allocator<void>());
+ boost::asio::dispatch(ex, promise_function_wrapper<Function>(f));
}
template <typename Function, typename Signature, typename Allocator>
{
typename promise_handler<Signature, Allocator>::executor_type
ex(h->get_executor());
- ex.dispatch(f, std::allocator<void>());
+ boost::asio::dispatch(ex, promise_function_wrapper<Function>(f));
}
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
// Helper base class for async_result specialisation.
template <typename Signature, typename Allocator>
class promise_async_result
Allocator allocator_;
};
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+
template <typename Function,
typename Function1, typename Allocator, typename Result>
inline void asio_handler_invoke(Function& f,
{
typename packaged_handler<Function1, Allocator, Result>::executor_type
ex(h->get_executor());
- ex.dispatch(BOOST_ASIO_MOVE_CAST(Function)(f), std::allocator<void>());
+ boost::asio::dispatch(ex, promise_function_wrapper<Function>(f));
}
template <typename Function,
{
typename packaged_handler<Function1, Allocator, Result>::executor_type
ex(h->get_executor());
- ex.dispatch(f, std::allocator<void>());
+ boost::asio::dispatch(ex, promise_function_wrapper<Function>(f));
}
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
// Helper base class for async_result specialisation.
template <typename Function, typename Allocator, typename Result>
class packaged_async_result
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+namespace traits {
+
+#if !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
+
+template <typename T, typename Blocking>
+struct equality_comparable<
+ boost::asio::detail::promise_executor<T, Blocking> >
+{
+ BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
+ BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
+};
+
+#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT)
+
+#if !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
+
+template <typename T, typename Blocking, typename Function>
+struct execute_member<
+ boost::asio::detail::promise_executor<T, Blocking>, Function>
+{
+ BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
+ BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = false);
+ typedef void result_type;
+};
+
+#endif // !defined(BOOST_ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT)
+
+#if !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_TRAIT)
+
+template <typename T, typename Blocking, typename Property>
+struct query_static_constexpr_member<
+ boost::asio::detail::promise_executor<T, Blocking>,
+ Property,
+ typename boost::asio::enable_if<
+ boost::asio::is_convertible<
+ Property,
+ boost::asio::execution::blocking_t
+ >::value
+ >::type
+ >
+{
+ BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
+ BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
+ typedef Blocking result_type;
+
+ static BOOST_ASIO_CONSTEXPR result_type value() BOOST_ASIO_NOEXCEPT
+ {
+ return Blocking();
+ }
+};
+
+#endif // !defined(BOOST_ASIO_HAS_DEDUCED_QUERY_STATIC_CONSTEXPR_TRAIT)
+
+#if !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
+
+template <typename T, typename Blocking>
+struct require_member<
+ boost::asio::detail::promise_executor<T, Blocking>,
+ execution::blocking_t::possibly_t
+ >
+{
+ BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
+ BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
+ typedef boost::asio::detail::promise_executor<T,
+ execution::blocking_t::possibly_t> result_type;
+};
+
+template <typename T, typename Blocking>
+struct require_member<
+ boost::asio::detail::promise_executor<T, Blocking>,
+ execution::blocking_t::never_t
+ >
+{
+ BOOST_ASIO_STATIC_CONSTEXPR(bool, is_valid = true);
+ BOOST_ASIO_STATIC_CONSTEXPR(bool, is_noexcept = true);
+ typedef boost::asio::detail::promise_executor<T,
+ execution::blocking_t::never_t> result_type;
+};
+
+#endif // !defined(BOOST_ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT)
+
+} // namespace traits
+
#endif // !defined(GENERATING_DOCUMENTATION)
} // namespace asio