// impl/post.hpp
// ~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
namespace boost {
namespace asio {
+namespace detail {
-template <typename CompletionToken>
-BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post(
- BOOST_ASIO_MOVE_ARG(CompletionToken) token)
+class initiate_post
{
- typedef BOOST_ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
+public:
+ template <typename CompletionHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const
+ {
+ typedef typename decay<CompletionHandler>::type DecayedHandler;
- async_completion<CompletionToken, void()> init(token);
+ typename associated_executor<DecayedHandler>::type ex(
+ (get_associated_executor)(handler));
- typename associated_executor<handler>::type ex(
- (get_associated_executor)(init.completion_handler));
+ typename associated_allocator<DecayedHandler>::type alloc(
+ (get_associated_allocator)(handler));
- typename associated_allocator<handler>::type alloc(
- (get_associated_allocator)(init.completion_handler));
+ ex.post(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
+ }
+};
- ex.post(BOOST_ASIO_MOVE_CAST(handler)(init.completion_handler), alloc);
+template <typename Executor>
+class initiate_post_with_executor
+{
+public:
+ typedef Executor executor_type;
- return init.result.get();
-}
+ explicit initiate_post_with_executor(const Executor& ex)
+ : ex_(ex)
+ {
+ }
-template <typename Executor, typename CompletionToken>
-BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post(
- const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
- typename enable_if<is_executor<Executor>::value>::type*)
-{
- typedef BOOST_ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
+ executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+ {
+ return ex_;
+ }
+
+ template <typename CompletionHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const
+ {
+ typedef typename decay<CompletionHandler>::type DecayedHandler;
+
+ typename associated_allocator<DecayedHandler>::type alloc(
+ (get_associated_allocator)(handler));
- async_completion<CompletionToken, void()> init(token);
+ ex_.post(detail::work_dispatcher<DecayedHandler>(
+ BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
+ }
- typename associated_allocator<handler>::type alloc(
- (get_associated_allocator)(init.completion_handler));
+private:
+ Executor ex_;
+};
- ex.post(detail::work_dispatcher<handler>(init.completion_handler), alloc);
+} // namespace detail
- return init.result.get();
+template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
+BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) post(
+ BOOST_ASIO_MOVE_ARG(CompletionToken) token)
+{
+ return async_initiate<CompletionToken, void()>(
+ detail::initiate_post(), token);
+}
+
+template <typename Executor,
+ BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
+BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) post(
+ const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
+ typename enable_if<is_executor<Executor>::value>::type*)
+{
+ return async_initiate<CompletionToken, void()>(
+ detail::initiate_post_with_executor<Executor>(ex), token);
}
-template <typename ExecutionContext, typename CompletionToken>
-inline BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post(
+template <typename ExecutionContext,
+ BOOST_ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
+inline BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) post(
ExecutionContext& ctx, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
typename enable_if<is_convertible<
ExecutionContext&, execution_context&>::value>::type*)