New async_result form with initiate() static member function.

The `async_result` template now supports a new form:

    template <typename CompletionToken, typename Signature>
    struct async_result
    {
      typedef /* ... */ return_type;

      template <typename Initiation,
          typename RawCompletionToken,
          typename... Args>
      static return_type initiate(
          Initiation&& initiation,
          RawCompletionToken&& token,
          Args&&... args);
    };

The `initiate()` function must:

* Transform the token into a completion handler object `handler`.

* Cause the invocation of the function object `initiation` as if
  by calling:

    std::forward<Initiation>(initiation)(
        std::move(handler),
        std::forward<Args>(args)...);

The invocation of `initiation` may be deferred (e.g. lazily evaluated),
in which case `initiation` and `args` must be decay-copied and moved
as required.

A helper function template `async_initiate` has also been added as a
wrapper for the invocation of `async_result<>::initiate`. For backward
compatibility, this function supports both the old and new async_result
forms.
This commit is contained in:
Christopher Kohlhoff 2019-02-15 20:07:10 +11:00
parent fc05ce407c
commit 62c4488abc
35 changed files with 1758 additions and 1232 deletions

View File

@ -142,6 +142,7 @@ nobase_include_HEADERS = \
asio/detail/macos_fenced_block.hpp \
asio/detail/memory.hpp \
asio/detail/mutex.hpp \
asio/detail/non_const_lvalue.hpp \
asio/detail/noncopyable.hpp \
asio/detail/null_event.hpp \
asio/detail/null_fenced_block.hpp \

View File

@ -17,6 +17,7 @@
#include "asio/detail/config.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/detail/variadic_templates.hpp"
#include "asio/detail/push_options.hpp"
@ -66,6 +67,53 @@ public:
{
}
#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \
|| defined(GENERATING_DOCUMENTATION)
/// Initiate the asynchronous operation that will produce the result, and
/// obtain the value to be returned from the initiating function.
template <typename Initiation, typename RawCompletionToken, typename... Args>
static return_type initiate(
ASIO_MOVE_ARG(Initiation) initiation,
ASIO_MOVE_ARG(RawCompletionToken) token,
ASIO_MOVE_ARG(Args)... args)
{
ASIO_MOVE_CAST(Initiation)(initiation)(
ASIO_MOVE_CAST(RawCompletionToken)(token),
ASIO_MOVE_CAST(Args)(args)...);
}
#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
// || defined(GENERATING_DOCUMENTATION)
template <typename Initiation, typename RawCompletionToken>
static return_type initiate(
ASIO_MOVE_ARG(Initiation) initiation,
ASIO_MOVE_ARG(RawCompletionToken) token)
{
ASIO_MOVE_CAST(Initiation)(initiation)(
ASIO_MOVE_CAST(RawCompletionToken)(token));
}
#define ASIO_PRIVATE_INITIATE_DEF(n) \
template <typename Initiation, typename RawCompletionToken, \
ASIO_VARIADIC_TPARAMS(n)> \
static return_type initiate( \
ASIO_MOVE_ARG(Initiation) initiation, \
ASIO_MOVE_ARG(RawCompletionToken) token, \
ASIO_VARIADIC_MOVE_PARAMS(n)) \
{ \
ASIO_MOVE_CAST(Initiation)(initiation)( \
ASIO_MOVE_CAST(RawCompletionToken)(token), \
ASIO_VARIADIC_MOVE_ARGS(n)); \
} \
/**/
ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)
#undef ASIO_PRIVATE_INITIATE_DEF
#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
// || defined(GENERATING_DOCUMENTATION)
private:
async_result(const async_result&) ASIO_DELETED;
async_result& operator=(const async_result&) ASIO_DELETED;
@ -130,10 +178,40 @@ struct async_result_helper
{
};
} // namespace detail
} // namespace asio
struct async_result_memfns_base
{
void initiate();
};
#include "asio/detail/pop_options.hpp"
template <typename T>
struct async_result_memfns_derived
: T, async_result_memfns_base
{
};
template <typename T, T>
struct async_result_memfns_check
{
};
template <typename>
char (&async_result_initiate_memfn_helper(...))[2];
template <typename T>
char async_result_initiate_memfn_helper(
async_result_memfns_check<
void (async_result_memfns_base::*)(),
&async_result_memfns_derived<T>::initiate>*);
template <typename CompletionToken, typename Signature>
struct async_result_has_initiate_memfn
: integral_constant<bool, sizeof(async_result_initiate_memfn_helper<
async_result<typename decay<CompletionToken>::type, Signature>
>(0)) != 1>
{
};
} // namespace detail
#if defined(GENERATING_DOCUMENTATION)
# define ASIO_INITFN_RESULT_TYPE(ct, sig) \
@ -154,4 +232,125 @@ struct async_result_helper
typename ::asio::decay<ct>::type, sig>::completion_handler_type
#endif
#if defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature,
typename Initiation, typename... Args>
ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
ASIO_NONDEDUCED_MOVE_ARG(CompletionToken),
ASIO_MOVE_ARG(Args)... args);
#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)
template <typename CompletionToken, typename Signature,
typename Initiation, typename... Args>
inline typename enable_if<
detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
ASIO_MOVE_ARG(Args)... args)
{
return async_result<typename decay<CompletionToken>::type,
Signature>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),
ASIO_MOVE_CAST(CompletionToken)(token),
ASIO_MOVE_CAST(Args)(args)...);
}
template <typename CompletionToken, typename Signature,
typename Initiation, typename... Args>
inline typename enable_if<
!detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
ASIO_MOVE_ARG(Args)... args)
{
async_completion<CompletionToken, Signature> completion(token);
ASIO_MOVE_CAST(Initiation)(initiation)(
ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken,
Signature))(completion.completion_handler),
ASIO_MOVE_CAST(Args)(args)...);
return completion.result.get();
}
#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
template <typename CompletionToken, typename Signature, typename Initiation>
inline typename enable_if<
detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
{
return async_result<typename decay<CompletionToken>::type,
Signature>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),
ASIO_MOVE_CAST(CompletionToken)(token));
}
template <typename CompletionToken, typename Signature, typename Initiation>
inline typename enable_if<
!detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
{
async_completion<CompletionToken, Signature> completion(token);
ASIO_MOVE_CAST(Initiation)(initiation)(
ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken,
Signature))(completion.completion_handler));
return completion.result.get();
}
#define ASIO_PRIVATE_INITIATE_DEF(n) \
template <typename CompletionToken, typename Signature, \
typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \
inline typename enable_if< \
detail::async_result_has_initiate_memfn< \
CompletionToken, Signature>::value, \
ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \
async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \
ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
ASIO_VARIADIC_MOVE_PARAMS(n)) \
{ \
return async_result<typename decay<CompletionToken>::type, \
Signature>::initiate(ASIO_MOVE_CAST(Initiation)(initiation), \
ASIO_MOVE_CAST(CompletionToken)(token), \
ASIO_VARIADIC_MOVE_ARGS(n)); \
} \
\
template <typename CompletionToken, typename Signature, \
typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \
inline typename enable_if< \
!detail::async_result_has_initiate_memfn< \
CompletionToken, Signature>::value, \
ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \
async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \
ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
ASIO_VARIADIC_MOVE_PARAMS(n)) \
{ \
async_completion<CompletionToken, Signature> completion(token); \
\
ASIO_MOVE_CAST(Initiation)(initiation)( \
ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken, \
Signature))(completion.completion_handler), \
ASIO_VARIADIC_MOVE_ARGS(n)); \
\
return completion.result.get(); \
} \
/**/
ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF)
#undef ASIO_PRIVATE_INITIATE_DEF
#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_ASYNC_RESULT_HPP

View File

@ -19,6 +19,7 @@
#include <cstddef>
#include "asio/basic_socket.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/error.hpp"
@ -452,18 +453,10 @@ public:
async_send(const ConstBufferSequence& buffers,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_send(this->impl_.get_implementation(),
buffers, 0, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous send on a connected socket.
@ -501,18 +494,9 @@ public:
socket_base::message_flags flags,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_send(this->impl_.get_implementation(),
buffers, flags, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags);
}
/// Send a datagram to the specified endpoint.
@ -647,18 +631,10 @@ public:
const endpoint_type& destination,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_send_to(this->impl_.get_implementation(),
buffers, destination, 0, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers,
destination, socket_base::message_flags(0));
}
/// Start an asynchronous send.
@ -695,18 +671,9 @@ public:
const endpoint_type& destination, socket_base::message_flags flags,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_send_to(
this->impl_.get_implementation(), buffers, destination, flags,
init.completion_handler, this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers, destination, flags);
}
/// Receive some data on a connected socket.
@ -840,18 +807,10 @@ public:
async_receive(const MutableBufferSequence& buffers,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_receive(this->impl_.get_implementation(),
buffers, 0, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous receive on a connected socket.
@ -889,18 +848,9 @@ public:
socket_base::message_flags flags,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_receive(this->impl_.get_implementation(),
buffers, flags, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive(), handler, this, buffers, flags);
}
/// Receive a datagram with the endpoint of the sender.
@ -1035,19 +985,10 @@ public:
endpoint_type& sender_endpoint,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_receive_from(
this->impl_.get_implementation(), buffers,
sender_endpoint, 0, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive_from(), handler, this, buffers,
&sender_endpoint, socket_base::message_flags(0));
}
/// Start an asynchronous receive.
@ -1086,20 +1027,85 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_receive_from(
this->impl_.get_implementation(), buffers,
sender_endpoint, flags, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive_from(), handler,
this, buffers, &sender_endpoint, flags);
}
private:
struct initiate_async_send
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
basic_datagram_socket* self, const ConstBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_send_to
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
basic_datagram_socket* self, const ConstBufferSequence& buffers,
const endpoint_type& destination,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send_to(
self->impl_.get_implementation(), buffers, destination, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
basic_datagram_socket* self, const MutableBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive_from
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
basic_datagram_socket* self, const MutableBufferSequence& buffers,
endpoint_type* sender_endpoint, socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive_from(
self->impl_.get_implementation(), buffers, *sender_endpoint, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
};
} // namespace asio

View File

@ -24,6 +24,7 @@
#include "asio/detail/deadline_timer_service.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/io_object_impl.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/execution_context.hpp"
@ -624,17 +625,8 @@ public:
void (asio::error_code))
async_wait(ASIO_MOVE_ARG(WaitHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WaitHandler.
ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
async_completion<WaitHandler,
void (asio::error_code)> init(handler);
impl_.get_service().async_wait(impl_.get_implementation(),
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WaitHandler, void (asio::error_code)>(
initiate_async_wait(), handler, this);
}
private:
@ -643,6 +635,23 @@ private:
basic_deadline_timer& operator=(
const basic_deadline_timer&) ASIO_DELETED;
struct initiate_async_wait
{
template <typename WaitHandler>
void operator()(ASIO_MOVE_ARG(WaitHandler) handler,
basic_deadline_timer* self) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WaitHandler.
ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
detail::non_const_lvalue<WaitHandler> handler2(handler);
self->impl_.get_service().async_wait(
self->impl_.get_implementation(), handler2.value,
self->impl_.get_implementation_executor());
}
};
detail::io_object_impl<
detail::deadline_timer_service<TimeTraits>, Executor> impl_;
};

View File

@ -19,6 +19,7 @@
#include <cstddef>
#include "asio/basic_socket.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/error.hpp"
@ -444,18 +445,10 @@ public:
async_send(const ConstBufferSequence& buffers,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_send(this->impl_.get_implementation(),
buffers, 0, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous send on a connected socket.
@ -493,18 +486,9 @@ public:
socket_base::message_flags flags,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_send(this->impl_.get_implementation(),
buffers, flags, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags);
}
/// Send raw data to the specified endpoint.
@ -639,18 +623,10 @@ public:
const endpoint_type& destination,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_send_to(this->impl_.get_implementation(),
buffers, destination, 0, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers,
destination, socket_base::message_flags(0));
}
/// Start an asynchronous send.
@ -687,18 +663,9 @@ public:
const endpoint_type& destination, socket_base::message_flags flags,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_send_to(
this->impl_.get_implementation(), buffers, destination, flags,
init.completion_handler, this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers, destination, flags);
}
/// Receive some data on a connected socket.
@ -832,18 +799,10 @@ public:
async_receive(const MutableBufferSequence& buffers,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_receive(this->impl_.get_implementation(),
buffers, 0, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous receive on a connected socket.
@ -881,18 +840,9 @@ public:
socket_base::message_flags flags,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_receive(this->impl_.get_implementation(),
buffers, flags, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive(), handler, this, buffers, flags);
}
/// Receive raw data with the endpoint of the sender.
@ -1027,19 +977,10 @@ public:
endpoint_type& sender_endpoint,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_receive_from(
this->impl_.get_implementation(), buffers,
sender_endpoint, 0, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive_from(), handler, this, buffers,
&sender_endpoint, socket_base::message_flags(0));
}
/// Start an asynchronous receive.
@ -1078,20 +1019,85 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_receive_from(
this->impl_.get_implementation(), buffers,
sender_endpoint, flags, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive_from(), handler,
this, buffers, &sender_endpoint, flags);
}
private:
struct initiate_async_send
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
basic_raw_socket* self, const ConstBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_send_to
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
basic_raw_socket* self, const ConstBufferSequence& buffers,
const endpoint_type& destination,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send_to(
self->impl_.get_implementation(), buffers, destination, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
basic_raw_socket* self, const MutableBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive_from
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
basic_raw_socket* self, const MutableBufferSequence& buffers,
endpoint_type* sender_endpoint, socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive_from(
self->impl_.get_implementation(), buffers, *sender_endpoint, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
};
} // namespace asio

View File

@ -435,18 +435,9 @@ public:
socket_base::message_flags flags,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_send(this->impl_.get_implementation(),
buffers, flags, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags);
}
/// Receive some data on the socket.
@ -613,19 +604,10 @@ public:
socket_base::message_flags& out_flags,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_receive_with_flags(
this->impl_.get_implementation(), buffers,
0, out_flags, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive_with_flags(), handler, this,
buffers, socket_base::message_flags(0), &out_flags);
}
/// Start an asynchronous receive.
@ -678,20 +660,49 @@ public:
socket_base::message_flags& out_flags,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_receive_with_flags(
this->impl_.get_implementation(), buffers,
in_flags, out_flags, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive_with_flags(), handler,
this, buffers, in_flags, &out_flags);
}
private:
struct initiate_async_send
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
basic_seq_packet_socket* self, const ConstBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive_with_flags
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
basic_seq_packet_socket* self, const MutableBufferSequence& buffers,
socket_base::message_flags in_flags,
socket_base::message_flags* out_flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive_with_flags(
self->impl_.get_implementation(), buffers, in_flags, *out_flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
};
} // namespace asio

View File

@ -25,6 +25,7 @@
#include "asio/async_result.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/io_object_impl.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/error.hpp"
@ -685,17 +686,9 @@ public:
async_write_some(const ConstBufferSequence& buffers,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
impl_.get_service().async_write_some(impl_.get_implementation(), buffers,
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_write_some(), handler, this, buffers);
}
/// Read some data from the serial port.
@ -804,17 +797,9 @@ public:
async_read_some(const MutableBufferSequence& buffers,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
impl_.get_service().async_read_some(impl_.get_implementation(), buffers,
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_read_some(), handler, this, buffers);
}
private:
@ -822,6 +807,40 @@ private:
basic_serial_port(const basic_serial_port&) ASIO_DELETED;
basic_serial_port& operator=(const basic_serial_port&) ASIO_DELETED;
struct initiate_async_write_some
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
basic_serial_port* self, const ConstBufferSequence& buffers) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_write_some(
self->impl_.get_implementation(), buffers, handler2.value,
self->impl_.get_implementation_executor());
}
};
struct initiate_async_read_some
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
basic_serial_port* self, const MutableBufferSequence& buffers) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_read_some(
self->impl_.get_implementation(), buffers, handler2.value,
self->impl_.get_implementation_executor());
}
};
#if defined(ASIO_HAS_IOCP)
detail::io_object_impl<detail::win_iocp_serial_port_service, Executor> impl_;
#else

View File

@ -20,6 +20,7 @@
#include "asio/async_result.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/io_object_impl.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/signal_set_service.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/detail/type_traits.hpp"
@ -506,17 +507,8 @@ public:
void (asio::error_code, int))
async_wait(ASIO_MOVE_ARG(SignalHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a SignalHandler.
ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check;
async_completion<SignalHandler,
void (asio::error_code, int)> init(handler);
impl_.get_service().async_wait(impl_.get_implementation(),
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return async_initiate<SignalHandler, void (asio::error_code, int)>(
initiate_async_wait(), handler, this);
}
private:
@ -524,6 +516,23 @@ private:
basic_signal_set(const basic_signal_set&) ASIO_DELETED;
basic_signal_set& operator=(const basic_signal_set&) ASIO_DELETED;
struct initiate_async_wait
{
template <typename SignalHandler>
void operator()(ASIO_MOVE_ARG(SignalHandler) handler,
basic_signal_set* self) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a SignalHandler.
ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check;
detail::non_const_lvalue<SignalHandler> handler2(handler);
self->impl_.get_service().async_wait(
self->impl_.get_implementation(), handler2.value,
self->impl_.get_implementation_executor());
}
};
detail::io_object_impl<detail::signal_set_service, Executor> impl_;
};

View File

@ -19,6 +19,7 @@
#include "asio/async_result.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/io_object_impl.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/error.hpp"
@ -944,37 +945,15 @@ public:
async_connect(const endpoint_type& peer_endpoint,
ASIO_MOVE_ARG(ConnectHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ConnectHandler.
ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check;
asio::error_code open_ec;
if (!is_open())
{
asio::error_code ec;
const protocol_type protocol = peer_endpoint.protocol();
impl_.get_service().open(impl_.get_implementation(), protocol, ec);
if (ec)
{
async_completion<ConnectHandler,
void (asio::error_code)> init(handler);
asio::post(impl_.get_executor(),
asio::detail::bind_handler(
ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(
ConnectHandler, void (asio::error_code)))(
init.completion_handler), ec));
return init.result.get();
}
impl_.get_service().open(impl_.get_implementation(), protocol, open_ec);
}
async_completion<ConnectHandler,
void (asio::error_code)> init(handler);
impl_.get_service().async_connect(impl_.get_implementation(), peer_endpoint,
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ConnectHandler, void (asio::error_code)>(
initiate_async_connect(), handler, this, peer_endpoint, open_ec);
}
/// Set an option on the socket.
@ -1795,17 +1774,8 @@ public:
void (asio::error_code))
async_wait(wait_type w, ASIO_MOVE_ARG(WaitHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WaitHandler.
ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
async_completion<WaitHandler,
void (asio::error_code)> init(handler);
impl_.get_service().async_wait(impl_.get_implementation(), w,
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WaitHandler, void (asio::error_code)>(
initiate_async_wait(), handler, this, w);
}
protected:
@ -1833,6 +1803,50 @@ private:
// Disallow copying and assignment.
basic_socket(const basic_socket&) ASIO_DELETED;
basic_socket& operator=(const basic_socket&) ASIO_DELETED;
struct initiate_async_connect
{
template <typename ConnectHandler>
void operator()(ASIO_MOVE_ARG(ConnectHandler) handler,
basic_socket* self, const endpoint_type& peer_endpoint,
const asio::error_code& open_ec) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ConnectHandler.
ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check;
if (open_ec)
{
asio::post(self->impl_.get_executor(),
asio::detail::bind_handler(
ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec));
}
else
{
detail::non_const_lvalue<ConnectHandler> handler2(handler);
self->impl_.get_service().async_connect(
self->impl_.get_implementation(), peer_endpoint,
handler2.value, self->impl_.get_implementation_executor());
}
}
};
struct initiate_async_wait
{
template <typename WaitHandler>
void operator()(ASIO_MOVE_ARG(WaitHandler) handler,
basic_socket* self, wait_type w) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WaitHandler.
ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
detail::non_const_lvalue<WaitHandler> handler2(handler);
self->impl_.get_service().async_wait(
self->impl_.get_implementation(), w, handler2.value,
self->impl_.get_implementation_executor());
}
};
};
} // namespace asio

View File

@ -19,6 +19,7 @@
#include "asio/basic_socket.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/io_object_impl.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/error.hpp"
@ -1214,17 +1215,8 @@ public:
void (asio::error_code))
async_wait(wait_type w, ASIO_MOVE_ARG(WaitHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WaitHandler.
ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
async_completion<WaitHandler,
void (asio::error_code)> init(handler);
impl_.get_service().async_wait(impl_.get_implementation(), w,
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WaitHandler, void (asio::error_code)>(
initiate_async_wait(), handler, this, w);
}
#if !defined(ASIO_NO_EXTENSIONS)
@ -1340,18 +1332,9 @@ public:
is_convertible<Protocol, Protocol1>::value
>::type* = 0)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a AcceptHandler.
ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
async_completion<AcceptHandler,
void (asio::error_code)> init(handler);
impl_.get_service().async_accept(
impl_.get_implementation(), peer, static_cast<endpoint_type*>(0),
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return async_initiate<AcceptHandler, void (asio::error_code)>(
initiate_async_accept(), handler, this,
&peer, static_cast<endpoint_type*>(0));
}
/// Accept a new connection and obtain the endpoint of the peer
@ -1456,18 +1439,8 @@ public:
async_accept(basic_socket<protocol_type, Executor1>& peer,
endpoint_type& peer_endpoint, ASIO_MOVE_ARG(AcceptHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a AcceptHandler.
ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
async_completion<AcceptHandler,
void (asio::error_code)> init(handler);
impl_.get_service().async_accept(
impl_.get_implementation(), peer, &peer_endpoint,
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return async_initiate<AcceptHandler, void (asio::error_code)>(
initiate_async_accept(), handler, this, &peer, &peer_endpoint);
}
#endif // !defined(ASIO_NO_EXTENSIONS)
@ -1576,20 +1549,11 @@ public:
void (asio::error_code, typename Protocol::socket))
async_accept(ASIO_MOVE_ARG(MoveAcceptHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a MoveAcceptHandler.
ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
handler, typename Protocol::socket) type_check;
async_completion<MoveAcceptHandler,
void (asio::error_code,
typename Protocol::socket)> init(handler);
impl_.get_service().async_move_accept(impl_.get_implementation(),
return async_initiate<MoveAcceptHandler,
void (asio::error_code, typename Protocol::socket)>(
initiate_async_move_accept(), handler, this,
impl_.get_executor(), static_cast<endpoint_type*>(0),
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
static_cast<typename Protocol::socket*>(0));
}
/// Accept a new connection.
@ -1805,22 +1769,14 @@ public:
is_executor<Executor1>::value
>::type* = 0)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a MoveAcceptHandler.
ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
handler, typename Protocol::socket::template rebind_executor<
Executor1>::other) type_check;
typedef typename Protocol::socket::template rebind_executor<
Executor1>::other other_socket_type;
async_completion<MoveAcceptHandler,
void (asio::error_code,
typename Protocol::socket::template rebind_executor<
Executor1>::other)> init(handler);
impl_.get_service().async_move_accept(
impl_.get_implementation(), ex, static_cast<endpoint_type*>(0),
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return async_initiate<MoveAcceptHandler,
void (asio::error_code, other_socket_type)>(
initiate_async_move_accept(), handler, this,
ex, static_cast<endpoint_type*>(0),
static_cast<other_socket_type*>(0));
}
/// Start an asynchronous accept.
@ -1877,22 +1833,14 @@ public:
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a MoveAcceptHandler.
ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
handler, typename Protocol::socket::template rebind_executor<
typename ExecutionContext::executor_type>::other) type_check;
typedef typename Protocol::socket::template rebind_executor<
typename ExecutionContext::executor_type>::other other_socket_type;
async_completion<MoveAcceptHandler,
void (asio::error_code,
typename Protocol::socket::template rebind_executor<
typename ExecutionContext::executor_type>::other)> init(handler);
impl_.get_service().async_move_accept(impl_.get_implementation(),
return async_initiate<MoveAcceptHandler,
void (asio::error_code, other_socket_type)>(
initiate_async_move_accept(), handler, this,
context.get_executor(), static_cast<endpoint_type*>(0),
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
static_cast<other_socket_type*>(0));
}
/// Accept a new connection.
@ -2017,20 +1965,11 @@ public:
async_accept(endpoint_type& peer_endpoint,
ASIO_MOVE_ARG(MoveAcceptHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a MoveAcceptHandler.
ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
handler, typename Protocol::socket) type_check;
async_completion<MoveAcceptHandler,
void (asio::error_code,
typename Protocol::socket)> init(handler);
impl_.get_service().async_move_accept(
impl_.get_implementation(), impl_.get_executor(), &peer_endpoint,
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return async_initiate<MoveAcceptHandler,
void (asio::error_code, typename Protocol::socket)>(
initiate_async_move_accept(), handler, this,
impl_.get_executor(), &peer_endpoint,
static_cast<typename Protocol::socket*>(0));
}
/// Accept a new connection.
@ -2278,22 +2217,14 @@ public:
is_executor<Executor1>::value
>::type* = 0)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a MoveAcceptHandler.
ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
handler, typename Protocol::socket::template rebind_executor<
Executor1>::other) type_check;
typedef typename Protocol::socket::template rebind_executor<
Executor1>::other other_socket_type;
async_completion<MoveAcceptHandler,
void (asio::error_code,
typename Protocol::socket::template rebind_executor<
Executor1>::other)> init(handler);
impl_.get_service().async_move_accept(
impl_.get_implementation(), ex, &peer_endpoint,
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return async_initiate<MoveAcceptHandler,
void (asio::error_code, other_socket_type)>(
initiate_async_move_accept(), handler, this,
ex, &peer_endpoint,
static_cast<other_socket_type*>(0));
}
/// Start an asynchronous accept.
@ -2357,22 +2288,14 @@ public:
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a MoveAcceptHandler.
ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
handler, typename Protocol::socket::template rebind_executor<
typename ExecutionContext::executor_type>::other) type_check;
typedef typename Protocol::socket::template rebind_executor<
typename ExecutionContext::executor_type>::other other_socket_type;
async_completion<MoveAcceptHandler,
void (asio::error_code,
typename Protocol::socket::template rebind_executor<
typename ExecutionContext::executor_type>::other)> init(handler);
impl_.get_service().async_move_accept(impl_.get_implementation(),
return async_initiate<MoveAcceptHandler,
void (asio::error_code, other_socket_type)>(
initiate_async_move_accept(), handler, this,
context.get_executor(), &peer_endpoint,
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
static_cast<other_socket_type*>(0));
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@ -2382,6 +2305,60 @@ private:
basic_socket_acceptor& operator=(
const basic_socket_acceptor&) ASIO_DELETED;
struct initiate_async_wait
{
template <typename WaitHandler>
void operator()(ASIO_MOVE_ARG(WaitHandler) handler,
basic_socket_acceptor* self, wait_type w) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WaitHandler.
ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
detail::non_const_lvalue<WaitHandler> handler2(handler);
self->impl_.get_service().async_wait(
self->impl_.get_implementation(), w, handler2.value,
self->impl_.get_implementation_executor());
}
};
struct initiate_async_accept
{
template <typename AcceptHandler, typename Protocol1, typename Executor1>
void operator()(ASIO_MOVE_ARG(AcceptHandler) handler,
basic_socket_acceptor* self, basic_socket<Protocol1, Executor1>* peer,
endpoint_type* peer_endpoint) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a AcceptHandler.
ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
detail::non_const_lvalue<AcceptHandler> handler2(handler);
self->impl_.get_service().async_accept(
self->impl_.get_implementation(), *peer, peer_endpoint,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_move_accept
{
template <typename MoveAcceptHandler, typename Executor1, typename Socket>
void operator()(ASIO_MOVE_ARG(MoveAcceptHandler) handler,
basic_socket_acceptor* self, const Executor1& peer_ex,
endpoint_type* peer_endpoint, Socket*) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a MoveAcceptHandler.
ASIO_MOVE_ACCEPT_HANDLER_CHECK(
MoveAcceptHandler, handler, Socket) type_check;
detail::non_const_lvalue<MoveAcceptHandler> handler2(handler);
self->impl_.get_service().async_move_accept(
self->impl_.get_implementation(), peer_ex, peer_endpoint,
handler2.value, self->impl_.get_implementation_executor());
}
};
#if defined(ASIO_WINDOWS_RUNTIME)
detail::io_object_impl<
detail::null_socket_service<Protocol>, Executor> impl_;

View File

@ -20,6 +20,7 @@
#include "asio/async_result.hpp"
#include "asio/basic_socket.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
@ -468,18 +469,10 @@ public:
async_send(const ConstBufferSequence& buffers,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_send(this->impl_.get_implementation(),
buffers, 0, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous send.
@ -526,18 +519,9 @@ public:
socket_base::message_flags flags,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_send(this->impl_.get_implementation(),
buffers, flags, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags);
}
/// Receive some data on the socket.
@ -688,18 +672,10 @@ public:
async_receive(const MutableBufferSequence& buffers,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_receive(this->impl_.get_implementation(),
buffers, 0, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous receive.
@ -748,18 +724,9 @@ public:
socket_base::message_flags flags,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_receive(this->impl_.get_implementation(),
buffers, flags, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive(), handler, this, buffers, flags);
}
/// Write some data to the socket.
@ -864,18 +831,10 @@ public:
async_write_some(const ConstBufferSequence& buffers,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_send(this->impl_.get_implementation(),
buffers, 0, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Read some data from the socket.
@ -983,19 +942,48 @@ public:
async_read_some(const MutableBufferSequence& buffers,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_receive(this->impl_.get_implementation(),
buffers, 0, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
}
private:
struct initiate_async_send
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
basic_stream_socket* self, const ConstBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
basic_stream_socket* self, const MutableBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
};
} // namespace asio

View File

@ -21,6 +21,7 @@
#include "asio/detail/deadline_timer_service.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/io_object_impl.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/executor.hpp"
@ -695,17 +696,8 @@ public:
void (asio::error_code))
async_wait(ASIO_MOVE_ARG(WaitHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WaitHandler.
ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
async_completion<WaitHandler,
void (asio::error_code)> init(handler);
impl_.get_service().async_wait(impl_.get_implementation(),
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WaitHandler, void (asio::error_code)>(
initiate_async_wait(), handler, this);
}
private:
@ -714,6 +706,23 @@ private:
basic_waitable_timer& operator=(
const basic_waitable_timer&) ASIO_DELETED;
struct initiate_async_wait
{
template <typename WaitHandler>
void operator()(ASIO_MOVE_ARG(WaitHandler) handler,
basic_waitable_timer* self) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WaitHandler.
ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
detail::non_const_lvalue<WaitHandler> handler2(handler);
self->impl_.get_service().async_wait(
self->impl_.get_implementation(), handler2.value,
self->impl_.get_implementation_executor());
}
};
detail::io_object_impl<
detail::deadline_timer_service<
detail::chrono_time_traits<Clock, WaitTraits> >,

View File

@ -120,11 +120,14 @@
#endif // !defined(ASIO_HAS_MOVE)
// If ASIO_MOVE_CAST isn't defined, and move support is available, define
// ASIO_MOVE_ARG and ASIO_MOVE_CAST to take advantage of rvalue
// references and perfect forwarding.
// * ASIO_MOVE_ARG,
// * ASIO_NONDEDUCED_MOVE_ARG, and
// * ASIO_MOVE_CAST
// to take advantage of rvalue references and perfect forwarding.
#if defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST)
# define ASIO_MOVE_ARG(type) type&&
# define ASIO_MOVE_ARG2(type1, type2) type1, type2&&
# define ASIO_NONDEDUCED_MOVE_ARG(type) type&
# define ASIO_MOVE_CAST(type) static_cast<type&&>
# define ASIO_MOVE_CAST2(type1, type2) static_cast<type1, type2&&>
#endif // defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST)
@ -150,6 +153,7 @@
# else
# define ASIO_MOVE_ARG(type) type
# endif
# define ASIO_NONDEDUCED_MOVE_ARG(type) const type&
# define ASIO_MOVE_CAST(type) static_cast<const type&>
# define ASIO_MOVE_CAST2(type1, type2) static_cast<const type1, type2&>
#endif // !defined(ASIO_MOVE_CAST)

View File

@ -0,0 +1,54 @@
//
// detail/non_const_lvalue.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// 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)
//
#ifndef ASIO_DETAIL_NON_CONST_LVALUE_HPP
#define ASIO_DETAIL_NON_CONST_LVALUE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
template <typename T>
struct non_const_lvalue
{
#if defined(ASIO_HAS_MOVE)
explicit non_const_lvalue(T& t)
: value(static_cast<typename conditional<
is_same<T, typename decay<T>::type>::value,
typename decay<T>::type&, T&&>::type>(t))
{
}
typename conditional<is_same<T, typename decay<T>::type>::value,
typename decay<T>::type&, typename decay<T>::type>::type value;
#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
explicit non_const_lvalue(const typename decay<T>::type& t)
: value(t)
{
}
typename decay<T>::type value;
#endif // defined(ASIO_HAS_MOVE)
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_NON_CONST_LVALUE_HPP

View File

@ -29,9 +29,10 @@ template <typename Handler>
class work_dispatcher
{
public:
work_dispatcher(Handler& handler)
template <typename CompletionHandler>
explicit work_dispatcher(ASIO_MOVE_ARG(CompletionHandler) handler)
: work_((get_associated_executor)(handler)),
handler_(ASIO_MOVE_CAST(Handler)(handler))
handler_(ASIO_MOVE_CAST(CompletionHandler)(handler))
{
}

View File

@ -21,6 +21,7 @@
#include "asio/detail/handler_cont_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/push_options.hpp"
@ -137,6 +138,28 @@ namespace detail
asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
struct initiate_async_buffered_fill
{
template <typename ReadHandler, typename Stream>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
buffered_stream_storage* storage, Stream* next_layer) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
non_const_lvalue<ReadHandler> handler2(handler);
std::size_t previous_size = storage->size();
storage->resize(storage->capacity());
next_layer->async_read_some(
buffer(
storage->data() + previous_size,
storage->size() - previous_size),
buffered_fill_handler<typename decay<ReadHandler>::type>(
*storage, previous_size, handler2.value));
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -176,24 +199,9 @@ ASIO_INITFN_RESULT_TYPE(ReadHandler,
buffered_read_stream<Stream>::async_fill(
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
std::size_t previous_size = storage_.size();
storage_.resize(storage_.capacity());
next_layer_.async_read_some(
buffer(
storage_.data() + previous_size,
storage_.size() - previous_size),
detail::buffered_fill_handler<ASIO_HANDLER_TYPE(
ReadHandler, void (asio::error_code, std::size_t))>(
storage_, previous_size, init.completion_handler));
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_buffered_fill(), handler, &storage_, &next_layer_);
}
template <typename Stream>
@ -326,6 +334,38 @@ namespace detail
asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
struct initiate_async_buffered_read_some
{
template <typename ReadHandler, typename Stream,
typename MutableBufferSequence>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
buffered_stream_storage* storage, Stream* next_layer,
const MutableBufferSequence& buffers) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
using asio::buffer_size;
non_const_lvalue<ReadHandler> handler2(handler);
if (buffer_size(buffers) == 0 || !storage->empty())
{
next_layer->async_read_some(ASIO_MUTABLE_BUFFER(0, 0),
buffered_read_some_handler<MutableBufferSequence,
typename decay<ReadHandler>::type>(
*storage, buffers, handler2.value));
}
else
{
initiate_async_buffered_fill()(
buffered_read_some_handler<MutableBufferSequence,
typename decay<ReadHandler>::type>(
*storage, buffers, handler2.value),
storage, next_layer);
}
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -374,31 +414,10 @@ buffered_read_stream<Stream>::async_read_some(
const MutableBufferSequence& buffers,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
using asio::buffer_size;
if (buffer_size(buffers) == 0 || !storage_.empty())
{
next_layer_.async_read_some(ASIO_MUTABLE_BUFFER(0, 0),
detail::buffered_read_some_handler<
MutableBufferSequence, ASIO_HANDLER_TYPE(
ReadHandler, void (asio::error_code, std::size_t))>(
storage_, buffers, init.completion_handler));
}
else
{
this->async_fill(detail::buffered_read_some_handler<
MutableBufferSequence, ASIO_HANDLER_TYPE(
ReadHandler, void (asio::error_code, std::size_t))>(
storage_, buffers, init.completion_handler));
}
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_buffered_read_some(),
handler, &storage_, &next_layer_, buffers);
}
template <typename Stream>

View File

@ -21,6 +21,7 @@
#include "asio/detail/handler_cont_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/push_options.hpp"
@ -123,6 +124,23 @@ namespace detail
asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
struct initiate_async_buffered_flush
{
template <typename WriteHandler, typename Stream>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
buffered_stream_storage* storage, Stream* next_layer) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
non_const_lvalue<WriteHandler> handler2(handler);
async_write(*next_layer, buffer(storage->data(), storage->size()),
buffered_flush_handler<typename decay<WriteHandler>::type>(
*storage, handler2.value));
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -162,19 +180,10 @@ ASIO_INITFN_RESULT_TYPE(WriteHandler,
buffered_write_stream<Stream>::async_flush(
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
async_write(next_layer_, buffer(storage_.data(), storage_.size()),
detail::buffered_flush_handler<ASIO_HANDLER_TYPE(
WriteHandler, void (asio::error_code, std::size_t))>(
storage_, init.completion_handler));
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_buffered_flush(),
handler, &storage_, &next_layer_);
}
template <typename Stream>
@ -313,6 +322,38 @@ namespace detail
asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
struct initiate_async_buffered_write_some
{
template <typename WriteHandler, typename Stream,
typename ConstBufferSequence>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
buffered_stream_storage* storage, Stream* next_layer,
const ConstBufferSequence& buffers) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
using asio::buffer_size;
non_const_lvalue<WriteHandler> handler2(handler);
if (buffer_size(buffers) == 0 || storage->size() < storage->capacity())
{
next_layer->async_write_some(ASIO_CONST_BUFFER(0, 0),
buffered_write_some_handler<ConstBufferSequence,
typename decay<WriteHandler>::type>(
*storage, buffers, handler2.value));
}
else
{
initiate_async_buffered_flush()(
buffered_write_some_handler<ConstBufferSequence,
typename decay<WriteHandler>::type>(
*storage, buffers, handler2.value),
storage, next_layer);
}
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -361,32 +402,10 @@ buffered_write_stream<Stream>::async_write_some(
const ConstBufferSequence& buffers,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
using asio::buffer_size;
if (buffer_size(buffers) == 0
|| storage_.size() < storage_.capacity())
{
next_layer_.async_write_some(ASIO_CONST_BUFFER(0, 0),
detail::buffered_write_some_handler<
ConstBufferSequence, ASIO_HANDLER_TYPE(
WriteHandler, void (asio::error_code, std::size_t))>(
storage_, buffers, init.completion_handler));
}
else
{
this->async_flush(detail::buffered_write_some_handler<
ConstBufferSequence, ASIO_HANDLER_TYPE(
WriteHandler, void (asio::error_code, std::size_t))>(
storage_, buffers, init.completion_handler));
}
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_buffered_write_some(),
handler, &storage_, &next_layer_, buffers);
}
template <typename Stream>

View File

@ -23,6 +23,7 @@
#include "asio/detail/handler_cont_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/post.hpp"
@ -446,6 +447,27 @@ namespace detail
function, this_handler->handler_);
}
struct initiate_async_range_connect
{
template <typename RangeConnectHandler, typename Protocol,
typename Executor, typename EndpointSequence, typename ConnectCondition>
void operator()(ASIO_MOVE_ARG(RangeConnectHandler) handler,
basic_socket<Protocol, Executor>* s, const EndpointSequence& endpoints,
const ConnectCondition& connect_condition) const
{
// If you get an error on the following line it means that your
// handler does not meet the documented type requirements for an
// RangeConnectHandler.
ASIO_RANGE_CONNECT_HANDLER_CHECK(RangeConnectHandler,
handler, typename Protocol::endpoint) type_check;
non_const_lvalue<RangeConnectHandler> handler2(handler);
range_connect_op<Protocol, Executor, EndpointSequence, ConnectCondition,
typename decay<RangeConnectHandler>::type>(*s, endpoints,
connect_condition, handler2.value)(asio::error_code(), 1);
}
};
template <typename Protocol, typename Executor, typename Iterator,
typename ConnectCondition, typename IteratorConnectHandler>
class iterator_connect_op : base_from_connect_condition<ConnectCondition>
@ -593,6 +615,27 @@ namespace detail
asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
struct initiate_async_iterator_connect
{
template <typename IteratorConnectHandler, typename Protocol,
typename Executor, typename Iterator, typename ConnectCondition>
void operator()(ASIO_MOVE_ARG(IteratorConnectHandler) handler,
basic_socket<Protocol, Executor>* s, Iterator begin,
Iterator end, const ConnectCondition& connect_condition) const
{
// If you get an error on the following line it means that your
// handler does not meet the documented type requirements for an
// IteratorConnectHandler.
ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
IteratorConnectHandler, handler, Iterator) type_check;
non_const_lvalue<IteratorConnectHandler> handler2(handler);
iterator_connect_op<Protocol, Executor, Iterator, ConnectCondition,
typename decay<IteratorConnectHandler>::type>(*s, begin, end,
connect_condition, handler2.value)(asio::error_code(), 1);
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -689,23 +732,10 @@ async_connect(basic_socket<Protocol, Executor>& s,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type*)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a RangeConnectHandler.
ASIO_RANGE_CONNECT_HANDLER_CHECK(
RangeConnectHandler, handler, typename Protocol::endpoint) type_check;
async_completion<RangeConnectHandler,
void (asio::error_code, typename Protocol::endpoint)>
init(handler);
detail::range_connect_op<Protocol, Executor,
EndpointSequence, detail::default_connect_condition,
ASIO_HANDLER_TYPE(RangeConnectHandler,
void (asio::error_code, typename Protocol::endpoint))>(s,
endpoints, detail::default_connect_condition(),
init.completion_handler)(asio::error_code(), 1);
return init.result.get();
return async_initiate<RangeConnectHandler,
void (asio::error_code, typename Protocol::endpoint)>(
detail::initiate_async_range_connect(), handler,
&s, endpoints, detail::default_connect_condition());
}
#if !defined(ASIO_NO_DEPRECATED)
@ -717,21 +747,10 @@ async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
ASIO_MOVE_ARG(IteratorConnectHandler) handler,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a IteratorConnectHandler.
ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
IteratorConnectHandler, handler, Iterator) type_check;
async_completion<IteratorConnectHandler,
void (asio::error_code, Iterator)> init(handler);
detail::iterator_connect_op<Protocol, Executor, Iterator,
detail::default_connect_condition, ASIO_HANDLER_TYPE(
IteratorConnectHandler, void (asio::error_code, Iterator))>(s,
begin, Iterator(), detail::default_connect_condition(),
init.completion_handler)(asio::error_code(), 1);
return init.result.get();
return async_initiate<IteratorConnectHandler,
void (asio::error_code, Iterator)>(
detail::initiate_async_iterator_connect(), handler,
&s, begin, Iterator(), detail::default_connect_condition());
}
#endif // !defined(ASIO_NO_DEPRECATED)
@ -742,21 +761,10 @@ inline ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
ASIO_MOVE_ARG(IteratorConnectHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a IteratorConnectHandler.
ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
IteratorConnectHandler, handler, Iterator) type_check;
async_completion<IteratorConnectHandler,
void (asio::error_code, Iterator)> init(handler);
detail::iterator_connect_op<Protocol, Executor, Iterator,
detail::default_connect_condition, ASIO_HANDLER_TYPE(
IteratorConnectHandler, void (asio::error_code, Iterator))>(s,
begin, end, detail::default_connect_condition(),
init.completion_handler)(asio::error_code(), 1);
return init.result.get();
return async_initiate<IteratorConnectHandler,
void (asio::error_code, Iterator)>(
detail::initiate_async_iterator_connect(), handler,
&s, begin, end, detail::default_connect_condition());
}
template <typename Protocol, typename Executor, typename EndpointSequence,
@ -769,22 +777,10 @@ async_connect(basic_socket<Protocol, Executor>& s,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type*)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a RangeConnectHandler.
ASIO_RANGE_CONNECT_HANDLER_CHECK(
RangeConnectHandler, handler, typename Protocol::endpoint) type_check;
async_completion<RangeConnectHandler,
void (asio::error_code, typename Protocol::endpoint)>
init(handler);
detail::range_connect_op<Protocol, Executor, EndpointSequence,
ConnectCondition, ASIO_HANDLER_TYPE(RangeConnectHandler,
void (asio::error_code, typename Protocol::endpoint))>(s,
endpoints, connect_condition, init.completion_handler)(
asio::error_code(), 1);
return init.result.get();
return async_initiate<RangeConnectHandler,
void (asio::error_code, typename Protocol::endpoint)>(
detail::initiate_async_range_connect(),
handler, &s, endpoints, connect_condition);
}
#if !defined(ASIO_NO_DEPRECATED)
@ -797,21 +793,10 @@ async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
ASIO_MOVE_ARG(IteratorConnectHandler) handler,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a IteratorConnectHandler.
ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
IteratorConnectHandler, handler, Iterator) type_check;
async_completion<IteratorConnectHandler,
void (asio::error_code, Iterator)> init(handler);
detail::iterator_connect_op<Protocol, Executor,
Iterator, ConnectCondition, ASIO_HANDLER_TYPE(
IteratorConnectHandler, void (asio::error_code, Iterator))>(s,
begin, Iterator(), connect_condition, init.completion_handler)(
asio::error_code(), 1);
return init.result.get();
return async_initiate<IteratorConnectHandler,
void (asio::error_code, Iterator)>(
detail::initiate_async_iterator_connect(),
handler, &s, begin, Iterator(), connect_condition);
}
#endif // !defined(ASIO_NO_DEPRECATED)
@ -823,21 +808,10 @@ async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
Iterator end, ConnectCondition connect_condition,
ASIO_MOVE_ARG(IteratorConnectHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a IteratorConnectHandler.
ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
IteratorConnectHandler, handler, Iterator) type_check;
async_completion<IteratorConnectHandler,
void (asio::error_code, Iterator)> init(handler);
detail::iterator_connect_op<Protocol, Executor,
Iterator, ConnectCondition, ASIO_HANDLER_TYPE(
IteratorConnectHandler, void (asio::error_code, Iterator))>(s,
begin, end, connect_condition, init.completion_handler)(
asio::error_code(), 1);
return init.result.get();
return async_initiate<IteratorConnectHandler,
void (asio::error_code, Iterator)>(
detail::initiate_async_iterator_connect(),
handler, &s, begin, end, connect_condition);
}
} // namespace asio

View File

@ -23,24 +23,46 @@
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
struct initiate_defer
{
template <typename CompletionHandler>
void operator()(ASIO_MOVE_ARG(CompletionHandler) handler) const
{
typedef typename decay<CompletionHandler>::type DecayedHandler;
typename associated_executor<DecayedHandler>::type ex(
(get_associated_executor)(handler));
typename associated_allocator<DecayedHandler>::type alloc(
(get_associated_allocator)(handler));
ex.defer(ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
}
template <typename CompletionHandler, typename Executor>
void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,
ASIO_MOVE_ARG(Executor) ex) const
{
typedef typename decay<CompletionHandler>::type DecayedHandler;
typename associated_allocator<DecayedHandler>::type alloc(
(get_associated_allocator)(handler));
ex.defer(detail::work_dispatcher<DecayedHandler>(
ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
}
};
} // namespace detail
template <typename CompletionToken>
ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
ASIO_MOVE_ARG(CompletionToken) token)
{
typedef ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
async_completion<CompletionToken, void()> init(token);
typename associated_executor<handler>::type ex(
(get_associated_executor)(init.completion_handler));
typename associated_allocator<handler>::type alloc(
(get_associated_allocator)(init.completion_handler));
ex.defer(ASIO_MOVE_CAST(handler)(init.completion_handler), alloc);
return init.result.get();
return async_initiate<CompletionToken, void()>(
detail::initiate_defer(), token);
}
template <typename Executor, typename CompletionToken>
@ -48,16 +70,8 @@ ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token,
typename enable_if<is_executor<Executor>::value>::type*)
{
typedef ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
async_completion<CompletionToken, void()> init(token);
typename associated_allocator<handler>::type alloc(
(get_associated_allocator)(init.completion_handler));
ex.defer(detail::work_dispatcher<handler>(init.completion_handler), alloc);
return init.result.get();
return async_initiate<CompletionToken, void()>(
detail::initiate_defer(), token, ex);
}
template <typename ExecutionContext, typename CompletionToken>

View File

@ -23,24 +23,46 @@
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
struct initiate_dispatch
{
template <typename CompletionHandler>
void operator()(ASIO_MOVE_ARG(CompletionHandler) handler) const
{
typedef typename decay<CompletionHandler>::type DecayedHandler;
typename associated_executor<DecayedHandler>::type ex(
(get_associated_executor)(handler));
typename associated_allocator<DecayedHandler>::type alloc(
(get_associated_allocator)(handler));
ex.dispatch(ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
}
template <typename CompletionHandler, typename Executor>
void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,
ASIO_MOVE_ARG(Executor) ex) const
{
typedef typename decay<CompletionHandler>::type DecayedHandler;
typename associated_allocator<DecayedHandler>::type alloc(
(get_associated_allocator)(handler));
ex.dispatch(detail::work_dispatcher<DecayedHandler>(
ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
}
};
} // namespace detail
template <typename CompletionToken>
ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch(
ASIO_MOVE_ARG(CompletionToken) token)
{
typedef ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
async_completion<CompletionToken, void()> init(token);
typename associated_executor<handler>::type ex(
(get_associated_executor)(init.completion_handler));
typename associated_allocator<handler>::type alloc(
(get_associated_allocator)(init.completion_handler));
ex.dispatch(ASIO_MOVE_CAST(handler)(init.completion_handler), alloc);
return init.result.get();
return async_initiate<CompletionToken, void()>(
detail::initiate_dispatch(), token);
}
template <typename Executor, typename CompletionToken>
@ -48,17 +70,8 @@ ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch(
const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token,
typename enable_if<is_executor<Executor>::value>::type*)
{
typedef ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
async_completion<CompletionToken, void()> init(token);
typename associated_allocator<handler>::type alloc(
(get_associated_allocator)(init.completion_handler));
ex.dispatch(detail::work_dispatcher<handler>(
init.completion_handler), alloc);
return init.result.get();
return async_initiate<CompletionToken, void()>(
detail::initiate_dispatch(), token, ex);
}
template <typename ExecutionContext, typename CompletionToken>

View File

@ -19,6 +19,7 @@
#include "asio/detail/executor_op.hpp"
#include "asio/detail/fenced_block.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/recycling_allocator.hpp"
#include "asio/detail/service_registry.hpp"
#include "asio/detail/throw_error.hpp"
@ -127,72 +128,87 @@ inline void io_context::reset()
restart();
}
struct io_context::initiate_dispatch
{
template <typename LegacyCompletionHandler>
void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler,
io_context* self) const
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a LegacyCompletionHandler.
ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
LegacyCompletionHandler, handler) type_check;
detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);
if (self->impl_.can_dispatch())
{
detail::fenced_block b(detail::fenced_block::full);
asio_handler_invoke_helpers::invoke(
handler2.value, handler2.value);
}
else
{
// Allocate and construct an operation to wrap the handler.
typedef detail::completion_handler<
typename decay<LegacyCompletionHandler>::type> op;
typename op::ptr p = { detail::addressof(handler2.value),
op::ptr::allocate(handler2.value), 0 };
p.p = new (p.v) op(handler2.value);
ASIO_HANDLER_CREATION((*self, *p.p,
"io_context", this, 0, "dispatch"));
self->impl_.do_dispatch(p.p);
p.v = p.p = 0;
}
}
};
template <typename LegacyCompletionHandler>
ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ())
io_context::dispatch(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a LegacyCompletionHandler.
ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
LegacyCompletionHandler, handler) type_check;
return async_initiate<LegacyCompletionHandler, void ()>(
initiate_dispatch(), handler, this);
}
async_completion<LegacyCompletionHandler, void ()> init(handler);
struct io_context::initiate_post
{
template <typename LegacyCompletionHandler>
void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler,
io_context* self) const
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a LegacyCompletionHandler.
ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
LegacyCompletionHandler, handler) type_check;
detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);
bool is_continuation =
asio_handler_cont_helpers::is_continuation(handler2.value);
if (impl_.can_dispatch())
{
detail::fenced_block b(detail::fenced_block::full);
asio_handler_invoke_helpers::invoke(
init.completion_handler, init.completion_handler);
}
else
{
// Allocate and construct an operation to wrap the handler.
typedef detail::completion_handler<
typename async_completion<LegacyCompletionHandler,
void ()>::completion_handler_type> op;
typename op::ptr p = { detail::addressof(init.completion_handler),
op::ptr::allocate(init.completion_handler), 0 };
p.p = new (p.v) op(init.completion_handler);
typename decay<LegacyCompletionHandler>::type> op;
typename op::ptr p = { detail::addressof(handler2.value),
op::ptr::allocate(handler2.value), 0 };
p.p = new (p.v) op(handler2.value);
ASIO_HANDLER_CREATION((*this, *p.p,
"io_context", this, 0, "dispatch"));
ASIO_HANDLER_CREATION((*self, *p.p,
"io_context", this, 0, "post"));
impl_.do_dispatch(p.p);
self->impl_.post_immediate_completion(p.p, is_continuation);
p.v = p.p = 0;
}
return init.result.get();
}
};
template <typename LegacyCompletionHandler>
ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ())
io_context::post(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a LegacyCompletionHandler.
ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
LegacyCompletionHandler, handler) type_check;
async_completion<LegacyCompletionHandler, void ()> init(handler);
bool is_continuation =
asio_handler_cont_helpers::is_continuation(init.completion_handler);
// Allocate and construct an operation to wrap the handler.
typedef detail::completion_handler<
typename async_completion<LegacyCompletionHandler,
void ()>::completion_handler_type> op;
typename op::ptr p = { detail::addressof(init.completion_handler),
op::ptr::allocate(init.completion_handler), 0 };
p.p = new (p.v) op(init.completion_handler);
ASIO_HANDLER_CREATION((*this, *p.p,
"io_context", this, 0, "post"));
impl_.post_immediate_completion(p.p, is_continuation);
p.v = p.p = 0;
return init.result.get();
return async_initiate<LegacyCompletionHandler, void ()>(
initiate_post(), handler, this);
}
template <typename Handler>

View File

@ -23,24 +23,46 @@
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
struct initiate_post
{
template <typename CompletionHandler>
void operator()(ASIO_MOVE_ARG(CompletionHandler) handler) const
{
typedef typename decay<CompletionHandler>::type DecayedHandler;
typename associated_executor<DecayedHandler>::type ex(
(get_associated_executor)(handler));
typename associated_allocator<DecayedHandler>::type alloc(
(get_associated_allocator)(handler));
ex.post(ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
}
template <typename CompletionHandler, typename Executor>
void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,
ASIO_MOVE_ARG(Executor) ex) const
{
typedef typename decay<CompletionHandler>::type DecayedHandler;
typename associated_allocator<DecayedHandler>::type alloc(
(get_associated_allocator)(handler));
ex.post(detail::work_dispatcher<DecayedHandler>(
ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
}
};
} // namespace detail
template <typename CompletionToken>
ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post(
ASIO_MOVE_ARG(CompletionToken) token)
{
typedef ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
async_completion<CompletionToken, void()> init(token);
typename associated_executor<handler>::type ex(
(get_associated_executor)(init.completion_handler));
typename associated_allocator<handler>::type alloc(
(get_associated_allocator)(init.completion_handler));
ex.post(ASIO_MOVE_CAST(handler)(init.completion_handler), alloc);
return init.result.get();
return async_initiate<CompletionToken, void()>(
detail::initiate_post(), token);
}
template <typename Executor, typename CompletionToken>
@ -48,16 +70,8 @@ ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post(
const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token,
typename enable_if<is_executor<Executor>::value>::type*)
{
typedef ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
async_completion<CompletionToken, void()> init(token);
typename associated_allocator<handler>::type alloc(
(get_associated_allocator)(init.completion_handler));
ex.post(detail::work_dispatcher<handler>(init.completion_handler), alloc);
return init.result.get();
return async_initiate<CompletionToken, void()>(
detail::initiate_post(), token, ex);
}
template <typename ExecutionContext, typename CompletionToken>

View File

@ -29,6 +29,7 @@
#include "asio/detail/handler_cont_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
@ -361,6 +362,25 @@ namespace detail
stream, buffers, completion_condition, handler)(
asio::error_code(), 0, 1);
}
struct initiate_async_read_buffer_sequence
{
template <typename ReadHandler, typename AsyncReadStream,
typename MutableBufferSequence, typename CompletionCondition>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, const MutableBufferSequence& buffers,
CompletionCondition completion_condition) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
non_const_lvalue<ReadHandler> handler2(handler);
start_read_buffer_sequence_op(*s, buffers,
asio::buffer_sequence_begin(buffers),
completion_condition, handler2.value);
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -416,18 +436,10 @@ async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
is_mutable_buffer_sequence<MutableBufferSequence>::value
>::type*)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::start_read_buffer_sequence_op(s, buffers,
asio::buffer_sequence_begin(buffers), completion_condition,
init.completion_handler);
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_read_buffer_sequence(),
handler, &s, buffers, completion_condition);
}
template <typename AsyncReadStream, typename MutableBufferSequence,
@ -440,18 +452,10 @@ async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
is_mutable_buffer_sequence<MutableBufferSequence>::value
>::type*)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::start_read_buffer_sequence_op(s, buffers,
asio::buffer_sequence_begin(buffers), transfer_all(),
init.completion_handler);
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_read_buffer_sequence(),
handler, &s, buffers, transfer_all());
}
namespace detail
@ -592,6 +596,27 @@ namespace detail
asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
struct initiate_async_read_dynbuf
{
template <typename ReadHandler, typename AsyncReadStream,
typename DynamicBuffer, typename CompletionCondition>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, ASIO_MOVE_ARG(DynamicBuffer) buffers,
CompletionCondition completion_condition) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
non_const_lvalue<ReadHandler> handler2(handler);
read_dynbuf_op<AsyncReadStream, typename decay<DynamicBuffer>::type,
CompletionCondition, typename decay<ReadHandler>::type>(
*s, ASIO_MOVE_CAST(DynamicBuffer)(buffers),
completion_condition, handler2.value)(
asio::error_code(), 0, 1);
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -666,18 +691,10 @@ async_read(AsyncReadStream& s,
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::read_dynbuf_op<AsyncReadStream,
typename decay<DynamicBuffer>::type,
CompletionCondition, ASIO_HANDLER_TYPE(
ReadHandler, void (asio::error_code, std::size_t))>(
s, ASIO_MOVE_CAST(DynamicBuffer)(buffers),
completion_condition, init.completion_handler)(
asio::error_code(), 0, 1);
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_read_dynbuf(), handler, &s,
ASIO_MOVE_CAST(DynamicBuffer)(buffers), completion_condition);
}
#if !defined(ASIO_NO_EXTENSIONS)

View File

@ -29,6 +29,7 @@
#include "asio/detail/handler_cont_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
@ -313,6 +314,26 @@ namespace detail
d, offset, buffers, completion_condition, handler)(
asio::error_code(), 0, 1);
}
struct initiate_async_read_at_buffer_sequence
{
template <typename ReadHandler, typename AsyncRandomAccessReadDevice,
typename MutableBufferSequence, typename CompletionCondition>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
AsyncRandomAccessReadDevice* d, uint64_t offset,
const MutableBufferSequence& buffers,
CompletionCondition completion_condition) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
non_const_lvalue<ReadHandler> handler2(handler);
start_read_at_buffer_sequence_op(*d, offset, buffers,
asio::buffer_sequence_begin(buffers),
completion_condition, handler2.value);
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -368,18 +389,10 @@ async_read_at(AsyncRandomAccessReadDevice& d,
CompletionCondition completion_condition,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::start_read_at_buffer_sequence_op(d, offset, buffers,
asio::buffer_sequence_begin(buffers), completion_condition,
init.completion_handler);
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_read_at_buffer_sequence(),
handler, &d, offset, buffers, completion_condition);
}
template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
@ -390,18 +403,10 @@ async_read_at(AsyncRandomAccessReadDevice& d,
uint64_t offset, const MutableBufferSequence& buffers,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::start_read_at_buffer_sequence_op(d, offset, buffers,
asio::buffer_sequence_begin(buffers), transfer_all(),
init.completion_handler);
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_read_at_buffer_sequence(),
handler, &d, offset, buffers, transfer_all());
}
#if !defined(ASIO_NO_EXTENSIONS)
@ -539,6 +544,27 @@ namespace detail
asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
struct initiate_async_read_at_streambuf
{
template <typename ReadHandler, typename AsyncRandomAccessReadDevice,
typename Allocator, typename CompletionCondition>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
AsyncRandomAccessReadDevice* d, uint64_t offset,
basic_streambuf<Allocator>* b,
CompletionCondition completion_condition) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
non_const_lvalue<ReadHandler> handler2(handler);
read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
CompletionCondition, typename decay<ReadHandler>::type>(
*d, offset, *b, completion_condition, handler2.value)(
asio::error_code(), 0, 1);
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -590,20 +616,10 @@ async_read_at(AsyncRandomAccessReadDevice& d,
CompletionCondition completion_condition,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
CompletionCondition, ASIO_HANDLER_TYPE(ReadHandler,
void (asio::error_code, std::size_t))>(
d, offset, b, completion_condition, init.completion_handler)(
asio::error_code(), 0, 1);
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_read_at_streambuf(),
handler, &d, offset, &b, completion_condition);
}
template <typename AsyncRandomAccessReadDevice, typename Allocator,
@ -614,20 +630,10 @@ async_read_at(AsyncRandomAccessReadDevice& d,
uint64_t offset, asio::basic_streambuf<Allocator>& b,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
detail::transfer_all_t, ASIO_HANDLER_TYPE(ReadHandler,
void (asio::error_code, std::size_t))>(
d, offset, b, transfer_all(), init.completion_handler)(
asio::error_code(), 0, 1);
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_read_at_streambuf(),
handler, &d, offset, &b, transfer_all());
}
#endif // !defined(ASIO_NO_IOSTREAM)

View File

@ -29,6 +29,7 @@
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/limits.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/detail/push_options.hpp"
@ -599,6 +600,26 @@ namespace detail
asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
struct initiate_async_read_until_delim
{
template <typename ReadHandler, typename AsyncReadStream,
typename DynamicBuffer>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, ASIO_MOVE_ARG(DynamicBuffer) buffers,
char delim) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
non_const_lvalue<ReadHandler> handler2(handler);
read_until_delim_op<AsyncReadStream,
typename decay<DynamicBuffer>::type, typename decay<ReadHandler>::type>(
*s, ASIO_MOVE_CAST(DynamicBuffer)(buffers),
delim, handler2.value)(asio::error_code(), 0, 1);
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -649,21 +670,10 @@ async_read_until(AsyncReadStream& s,
ASIO_MOVE_ARG(DynamicBuffer) buffers,
char delim, ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::read_until_delim_op<AsyncReadStream,
typename decay<DynamicBuffer>::type,
ASIO_HANDLER_TYPE(ReadHandler,
void (asio::error_code, std::size_t))>(
s, ASIO_MOVE_CAST(DynamicBuffer)(buffers),
delim, init.completion_handler)(asio::error_code(), 0, 1);
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_read_until_delim(), handler,
&s, ASIO_MOVE_CAST(DynamicBuffer)(buffers), delim);
}
namespace detail
@ -852,6 +862,26 @@ namespace detail
asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
struct initiate_async_read_until_delim_string
{
template <typename ReadHandler, typename AsyncReadStream,
typename DynamicBuffer>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, ASIO_MOVE_ARG(DynamicBuffer) buffers,
const std::string& delim) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
non_const_lvalue<ReadHandler> handler2(handler);
read_until_delim_string_op<AsyncReadStream,
typename decay<DynamicBuffer>::type, typename decay<ReadHandler>::type>(
*s, ASIO_MOVE_CAST(DynamicBuffer)(buffers),
delim, handler2.value)(asio::error_code(), 0, 1);
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -903,22 +933,11 @@ async_read_until(AsyncReadStream& s,
ASIO_STRING_VIEW_PARAM delim,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::read_until_delim_string_op<AsyncReadStream,
typename decay<DynamicBuffer>::type,
ASIO_HANDLER_TYPE(ReadHandler,
void (asio::error_code, std::size_t))>(
s, ASIO_MOVE_CAST(DynamicBuffer)(buffers),
static_cast<std::string>(delim),
init.completion_handler)(asio::error_code(), 0, 1);
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_read_until_delim_string(),
handler, &s, ASIO_MOVE_CAST(DynamicBuffer)(buffers),
static_cast<std::string>(delim));
}
#if !defined(ASIO_NO_EXTENSIONS)
@ -1113,6 +1132,26 @@ namespace detail
asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
struct initiate_async_read_until_expr
{
template <typename ReadHandler, typename AsyncReadStream,
typename DynamicBuffer, typename RegEx>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, ASIO_MOVE_ARG(DynamicBuffer) buffers,
const RegEx& expr) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
non_const_lvalue<ReadHandler> handler2(handler);
read_until_expr_op<AsyncReadStream, typename decay<DynamicBuffer>::type,
RegEx, typename decay<ReadHandler>::type>(
*s, ASIO_MOVE_CAST(DynamicBuffer)(buffers),
expr, handler2.value)(asio::error_code(), 0, 1);
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -1164,21 +1203,10 @@ async_read_until(AsyncReadStream& s,
const boost::regex& expr,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::read_until_expr_op<AsyncReadStream,
typename decay<DynamicBuffer>::type,
boost::regex, ASIO_HANDLER_TYPE(ReadHandler,
void (asio::error_code, std::size_t))>(
s, ASIO_MOVE_CAST(DynamicBuffer)(buffers),
expr, init.completion_handler)(asio::error_code(), 0, 1);
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_read_until_expr(), handler,
&s, ASIO_MOVE_CAST(DynamicBuffer)(buffers), expr);
}
#endif // defined(ASIO_HAS_BOOST_REGEX)
@ -1370,6 +1398,26 @@ namespace detail
asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
struct initiate_async_read_until_match
{
template <typename ReadHandler, typename AsyncReadStream,
typename DynamicBuffer, typename MatchCondition>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
AsyncReadStream* s, ASIO_MOVE_ARG(DynamicBuffer) buffers,
MatchCondition match_condition) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
non_const_lvalue<ReadHandler> handler2(handler);
read_until_match_op<AsyncReadStream, typename decay<DynamicBuffer>::type,
MatchCondition, typename decay<ReadHandler>::type>(
*s, ASIO_MOVE_CAST(DynamicBuffer)(buffers),
match_condition, handler2.value)(asio::error_code(), 0, 1);
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -1421,22 +1469,10 @@ async_read_until(AsyncReadStream& s,
MatchCondition match_condition, ASIO_MOVE_ARG(ReadHandler) handler,
typename enable_if<is_match_condition<MatchCondition>::value>::type*)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::read_until_match_op<AsyncReadStream,
typename decay<DynamicBuffer>::type,
MatchCondition, ASIO_HANDLER_TYPE(ReadHandler,
void (asio::error_code, std::size_t))>(
s, ASIO_MOVE_CAST(DynamicBuffer)(buffers),
match_condition, init.completion_handler)(
asio::error_code(), 0, 1);
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_read_until_match(), handler,
&s, ASIO_MOVE_CAST(DynamicBuffer)(buffers), match_condition);
}
#if !defined(ASIO_NO_IOSTREAM)

View File

@ -28,6 +28,7 @@
#include "asio/detail/handler_cont_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/detail/push_options.hpp"
@ -345,6 +346,24 @@ namespace detail
asio::error_code(), 0, 1);
}
struct initiate_async_write_buffer_sequence
{
template <typename WriteHandler, typename AsyncWriteStream,
typename ConstBufferSequence, typename CompletionCondition>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
AsyncWriteStream* s, const ConstBufferSequence& buffers,
CompletionCondition completion_condition) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
non_const_lvalue<WriteHandler> handler2(handler);
start_write_buffer_sequence_op(*s, buffers,
asio::buffer_sequence_begin(buffers),
completion_condition, handler2.value);
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -400,18 +419,10 @@ async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
is_const_buffer_sequence<ConstBufferSequence>::value
>::type*)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::start_write_buffer_sequence_op(s, buffers,
asio::buffer_sequence_begin(buffers), completion_condition,
init.completion_handler);
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_write_buffer_sequence(),
handler, &s, buffers, completion_condition);
}
template <typename AsyncWriteStream, typename ConstBufferSequence,
@ -424,18 +435,10 @@ async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
is_const_buffer_sequence<ConstBufferSequence>::value
>::type*)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::start_write_buffer_sequence_op(s, buffers,
asio::buffer_sequence_begin(buffers), transfer_all(),
init.completion_handler);
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_write_buffer_sequence(),
handler, &s, buffers, transfer_all());
}
namespace detail
@ -549,6 +552,27 @@ namespace detail
asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
struct initiate_async_write_dynbuf
{
template <typename WriteHandler, typename AsyncWriteStream,
typename DynamicBuffer, typename CompletionCondition>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
AsyncWriteStream* s, ASIO_MOVE_ARG(DynamicBuffer) buffers,
CompletionCondition completion_condition) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
non_const_lvalue<WriteHandler> handler2(handler);
write_dynbuf_op<AsyncWriteStream, typename decay<DynamicBuffer>::type,
CompletionCondition, typename decay<WriteHandler>::type>(
*s, ASIO_MOVE_CAST(DynamicBuffer)(buffers),
completion_condition, handler2.value)(
asio::error_code(), 0, 1);
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -619,22 +643,10 @@ async_write(AsyncWriteStream& s,
is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
>::type*)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::write_dynbuf_op<AsyncWriteStream,
typename decay<DynamicBuffer>::type,
CompletionCondition, ASIO_HANDLER_TYPE(
WriteHandler, void (asio::error_code, std::size_t))>(
s, ASIO_MOVE_CAST(DynamicBuffer)(buffers),
completion_condition, init.completion_handler)(
asio::error_code(), 0, 1);
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_write_dynbuf(), handler, &s,
ASIO_MOVE_CAST(DynamicBuffer)(buffers), completion_condition);
}
#if !defined(ASIO_NO_EXTENSIONS)

View File

@ -28,6 +28,7 @@
#include "asio/detail/handler_cont_helpers.hpp"
#include "asio/detail/handler_invoke_helpers.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/detail/push_options.hpp"
@ -298,6 +299,26 @@ namespace detail
d, offset, buffers, completion_condition, handler)(
asio::error_code(), 0, 1);
}
struct initiate_async_write_at_buffer_sequence
{
template <typename WriteHandler, typename AsyncRandomAccessWriteDevice,
typename ConstBufferSequence, typename CompletionCondition>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
AsyncRandomAccessWriteDevice* d, uint64_t offset,
const ConstBufferSequence& buffers,
CompletionCondition completion_condition) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
non_const_lvalue<WriteHandler> handler2(handler);
start_write_at_buffer_sequence_op(*d, offset, buffers,
asio::buffer_sequence_begin(buffers),
completion_condition, handler2.value);
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -353,18 +374,10 @@ async_write_at(AsyncRandomAccessWriteDevice& d,
CompletionCondition completion_condition,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::start_write_at_buffer_sequence_op(d, offset, buffers,
asio::buffer_sequence_begin(buffers), completion_condition,
init.completion_handler);
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_write_at_buffer_sequence(),
handler, &d, offset, buffers, completion_condition);
}
template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
@ -375,18 +388,10 @@ async_write_at(AsyncRandomAccessWriteDevice& d,
uint64_t offset, const ConstBufferSequence& buffers,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::start_write_at_buffer_sequence_op(d, offset, buffers,
asio::buffer_sequence_begin(buffers), transfer_all(),
init.completion_handler);
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_write_at_buffer_sequence(),
handler, &d, offset, buffers, transfer_all());
}
#if !defined(ASIO_NO_EXTENSIONS)
@ -472,13 +477,25 @@ namespace detail
function, this_handler->handler_);
}
template <typename Allocator, typename WriteHandler>
inline write_at_streambuf_op<Allocator, WriteHandler>
make_write_at_streambuf_op(
asio::basic_streambuf<Allocator>& b, WriteHandler handler)
struct initiate_async_write_at_streambuf
{
return write_at_streambuf_op<Allocator, WriteHandler>(b, handler);
}
template <typename WriteHandler, typename AsyncRandomAccessWriteDevice,
typename Allocator, typename CompletionCondition>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
AsyncRandomAccessWriteDevice* d, uint64_t offset,
basic_streambuf<Allocator>* b,
CompletionCondition completion_condition) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
non_const_lvalue<WriteHandler> handler2(handler);
async_write_at(*d, offset, b->data(), completion_condition,
write_at_streambuf_op<Allocator, typename decay<WriteHandler>::type>(
*b, handler2.value));
}
};
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@ -524,19 +541,10 @@ async_write_at(AsyncRandomAccessWriteDevice& d,
CompletionCondition completion_condition,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
async_write_at(d, offset, b.data(), completion_condition,
detail::write_at_streambuf_op<Allocator, ASIO_HANDLER_TYPE(
WriteHandler, void (asio::error_code, std::size_t))>(
b, init.completion_handler));
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_write_at_streambuf(),
handler, &d, offset, &b, completion_condition);
}
template <typename AsyncRandomAccessWriteDevice, typename Allocator,
@ -547,19 +555,10 @@ async_write_at(AsyncRandomAccessWriteDevice& d,
uint64_t offset, asio::basic_streambuf<Allocator>& b,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
async_write_at(d, offset, b.data(), transfer_all(),
detail::write_at_streambuf_op<Allocator, ASIO_HANDLER_TYPE(
WriteHandler, void (asio::error_code, std::size_t))>(
b, init.completion_handler));
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
detail::initiate_async_write_at_streambuf(),
handler, &d, offset, &b, transfer_all());
}
#endif // !defined(ASIO_NO_IOSTREAM)

View File

@ -594,6 +594,11 @@ public:
#endif // !defined(ASIO_NO_DEPRECATED)
private:
#if !defined(ASIO_NO_DEPRECATED)
struct initiate_dispatch;
struct initiate_post;
#endif // !defined(ASIO_NO_DEPRECATED)
// Helper function to add the implementation.
ASIO_DECL impl_type& add_impl(impl_type* impl);

View File

@ -185,16 +185,8 @@ public:
ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ())
dispatch(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a LegacyCompletionHandler.
ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
LegacyCompletionHandler, handler) type_check;
async_completion<LegacyCompletionHandler, void ()> init(handler);
service_.dispatch(impl_, init.completion_handler);
return init.result.get();
return async_initiate<LegacyCompletionHandler, void ()>(
initiate_dispatch(), handler, this);
}
#endif // !defined(ASIO_NO_DEPRECATED)
@ -240,16 +232,8 @@ public:
ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ())
post(ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a LegacyCompletionHandler.
ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
LegacyCompletionHandler, handler) type_check;
async_completion<LegacyCompletionHandler, void ()> init(handler);
service_.post(impl_, init.completion_handler);
return init.result.get();
return async_initiate<LegacyCompletionHandler, void ()>(
initiate_post(), handler, this);
}
#endif // !defined(ASIO_NO_DEPRECATED)
@ -341,6 +325,42 @@ public:
}
private:
#if !defined(ASIO_NO_DEPRECATED)
struct initiate_dispatch
{
template <typename LegacyCompletionHandler>
void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler,
strand* self) const
{
// If you get an error on the following line it means that your
// handler does not meet the documented type requirements for a
// LegacyCompletionHandler.
ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
LegacyCompletionHandler, handler) type_check;
detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);
self->service_.dispatch(self->impl_, handler2.value);
}
};
struct initiate_post
{
template <typename LegacyCompletionHandler>
void operator()(ASIO_MOVE_ARG(LegacyCompletionHandler) handler,
strand* self) const
{
// If you get an error on the following line it means that your
// handler does not meet the documented type requirements for a
// LegacyCompletionHandler.
ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
LegacyCompletionHandler, handler) type_check;
detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);
self->service_.post(self->impl_, handler2.value);
}
};
#endif // !defined(ASIO_NO_DEPRECATED)
asio::detail::strand_service& service_;
mutable asio::detail::strand_service::implementation_type impl_;
};

View File

@ -20,6 +20,7 @@
#include "asio/async_result.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/io_object_impl.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/string_view.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
@ -613,18 +614,9 @@ public:
async_resolve(const query& q,
ASIO_MOVE_ARG(ResolveHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ResolveHandler.
ASIO_RESOLVE_HANDLER_CHECK(
ResolveHandler, handler, results_type) type_check;
asio::async_completion<ResolveHandler,
void (asio::error_code, results_type)> init(handler);
impl_.get_service().async_resolve(impl_.get_implementation(), q,
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return asio::async_initiate<ResolveHandler,
void (asio::error_code, results_type)>(
initiate_async_resolve(), handler, this, q);
}
#endif // !defined(ASIO_NO_DEPRECATED)
@ -735,21 +727,12 @@ public:
resolver_base::flags resolve_flags,
ASIO_MOVE_ARG(ResolveHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ResolveHandler.
ASIO_RESOLVE_HANDLER_CHECK(
ResolveHandler, handler, results_type) type_check;
basic_resolver_query<protocol_type> q(static_cast<std::string>(host),
static_cast<std::string>(service), resolve_flags);
asio::async_completion<ResolveHandler,
void (asio::error_code, results_type)> init(handler);
impl_.get_service().async_resolve(impl_.get_implementation(), q,
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return asio::async_initiate<ResolveHandler,
void (asio::error_code, results_type)>(
initiate_async_resolve(), handler, this, q);
}
/// Asynchronously perform forward resolution of a query to a list of entries.
@ -865,22 +848,13 @@ public:
resolver_base::flags resolve_flags,
ASIO_MOVE_ARG(ResolveHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ResolveHandler.
ASIO_RESOLVE_HANDLER_CHECK(
ResolveHandler, handler, results_type) type_check;
basic_resolver_query<protocol_type> q(
protocol, static_cast<std::string>(host),
static_cast<std::string>(service), resolve_flags);
asio::async_completion<ResolveHandler,
void (asio::error_code, results_type)> init(handler);
impl_.get_service().async_resolve(impl_.get_implementation(), q,
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return asio::async_initiate<ResolveHandler,
void (asio::error_code, results_type)>(
initiate_async_resolve(), handler, this, q);
}
/// Perform reverse resolution of an endpoint to a list of entries.
@ -955,18 +929,9 @@ public:
async_resolve(const endpoint_type& e,
ASIO_MOVE_ARG(ResolveHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ResolveHandler.
ASIO_RESOLVE_HANDLER_CHECK(
ResolveHandler, handler, results_type) type_check;
asio::async_completion<ResolveHandler,
void (asio::error_code, results_type)> init(handler);
impl_.get_service().async_resolve(impl_.get_implementation(), e,
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return asio::async_initiate<ResolveHandler,
void (asio::error_code, results_type)>(
initiate_async_resolve(), handler, this, e);
}
private:
@ -974,6 +939,24 @@ private:
basic_resolver(const basic_resolver&) ASIO_DELETED;
basic_resolver& operator=(const basic_resolver&) ASIO_DELETED;
struct initiate_async_resolve
{
template <typename ResolveHandler, typename Query>
void operator()(ASIO_MOVE_ARG(ResolveHandler) handler,
basic_resolver* self, const Query& q) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ResolveHandler.
ASIO_RESOLVE_HANDLER_CHECK(
ResolveHandler, handler, results_type) type_check;
asio::detail::non_const_lvalue<ResolveHandler> handler2(handler);
self->impl_.get_service().async_resolve(
self->impl_.get_implementation(), q, handler2.value,
self->impl_.get_implementation_executor());
}
};
# if defined(ASIO_WINDOWS_RUNTIME)
asio::detail::io_object_impl<
asio::detail::winrt_resolver_service<InternetProtocol>,

View File

@ -23,6 +23,7 @@
#include "asio/async_result.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/io_object_impl.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/reactive_descriptor_service.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
@ -618,17 +619,8 @@ public:
void (asio::error_code))
async_wait(wait_type w, ASIO_MOVE_ARG(WaitHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WaitHandler.
ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
async_completion<WaitHandler,
void (asio::error_code)> init(handler);
impl_.get_service().async_wait(impl_.get_implementation(), w,
init.completion_handler, impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WaitHandler, void (asio::error_code)>(
initiate_async_wait(), handler, this, w);
}
protected:
@ -648,6 +640,23 @@ private:
// Disallow copying and assignment.
basic_descriptor(const basic_descriptor&) ASIO_DELETED;
basic_descriptor& operator=(const basic_descriptor&) ASIO_DELETED;
struct initiate_async_wait
{
template <typename WaitHandler>
void operator()(ASIO_MOVE_ARG(WaitHandler) handler,
basic_descriptor* self, wait_type w) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WaitHandler.
ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
detail::non_const_lvalue<WaitHandler> handler2(handler);
self->impl_.get_service().async_wait(
self->impl_.get_implementation(), w, handler2.value,
self->impl_.get_implementation_executor());
}
};
};
} // namespace posix

View File

@ -262,19 +262,9 @@ public:
async_write_some(const ConstBufferSequence& buffers,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
asio::async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_write_some(
this->impl_.get_implementation(),
buffers, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_write_some(), handler, this, buffers);
}
/// Read some data from the descriptor.
@ -382,20 +372,47 @@ public:
async_read_some(const MutableBufferSequence& buffers,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
asio::async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->impl_.get_service().async_read_some(
this->impl_.get_implementation(),
buffers, init.completion_handler,
this->impl_.get_implementation_executor());
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_read_some(), handler, this, buffers);
}
private:
struct initiate_async_write_some
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
basic_stream_descriptor* self,
const ConstBufferSequence& buffers) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_write_some(
self->impl_.get_implementation(), buffers, handler2.value,
self->impl_.get_implementation_executor());
}
};
struct initiate_async_read_some
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
basic_stream_descriptor* self,
const MutableBufferSequence& buffers) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_read_some(
self->impl_.get_implementation(), buffers, handler2.value,
self->impl_.get_implementation_executor());
}
};
};
} // namespace posix

View File

@ -20,6 +20,7 @@
#include "asio/async_result.hpp"
#include "asio/detail/buffer_sequence_adapter.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/non_const_lvalue.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/ssl/context.hpp"
@ -435,17 +436,9 @@ public:
async_handshake(handshake_type type,
ASIO_MOVE_ARG(HandshakeHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a HandshakeHandler.
ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check;
asio::async_completion<HandshakeHandler,
void (asio::error_code)> init(handler);
detail::async_io(next_layer_, core_,
detail::handshake_op(type), init.completion_handler);
return init.result.get();
return async_initiate<HandshakeHandler,
void (asio::error_code, std::size_t)>(
initiate_async_handshake(), handler, this, type);
}
/// Start an asynchronous SSL handshake.
@ -475,19 +468,9 @@ public:
async_handshake(handshake_type type, const ConstBufferSequence& buffers,
ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a BufferedHandshakeHandler.
ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK(
BufferedHandshakeHandler, handler) type_check;
asio::async_completion<BufferedHandshakeHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::async_io(next_layer_, core_,
detail::buffered_handshake_op<ConstBufferSequence>(type, buffers),
init.completion_handler);
return init.result.get();
return async_initiate<BufferedHandshakeHandler,
void (asio::error_code, std::size_t)>(
initiate_async_buffered_handshake(), handler, this, type, buffers);
}
/// Shut down SSL on the stream.
@ -534,17 +517,9 @@ public:
void (asio::error_code))
async_shutdown(ASIO_MOVE_ARG(ShutdownHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ShutdownHandler.
ASIO_SHUTDOWN_HANDLER_CHECK(ShutdownHandler, handler) type_check;
asio::async_completion<ShutdownHandler,
void (asio::error_code)> init(handler);
detail::async_io(next_layer_, core_, detail::shutdown_op(),
init.completion_handler);
return init.result.get();
return async_initiate<ShutdownHandler,
void (asio::error_code, std::size_t)>(
initiate_async_shutdown(), handler, this);
}
/// Write some data to the stream.
@ -625,18 +600,9 @@ public:
async_write_some(const ConstBufferSequence& buffers,
ASIO_MOVE_ARG(WriteHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
asio::async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::async_io(next_layer_, core_,
detail::write_op<ConstBufferSequence>(buffers),
init.completion_handler);
return init.result.get();
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_write_some(), handler, this, buffers);
}
/// Read some data from the stream.
@ -717,21 +683,97 @@ public:
async_read_some(const MutableBufferSequence& buffers,
ASIO_MOVE_ARG(ReadHandler) handler)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
asio::async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
detail::async_io(next_layer_, core_,
detail::read_op<MutableBufferSequence>(buffers),
init.completion_handler);
return init.result.get();
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_read_some(), handler, this, buffers);
}
private:
struct initiate_async_handshake
{
template <typename HandshakeHandler>
void operator()(ASIO_MOVE_ARG(HandshakeHandler) handler,
stream* self, handshake_type type) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a HandshakeHandler.
ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check;
asio::detail::non_const_lvalue<HandshakeHandler> handler2(handler);
detail::async_io(self->next_layer_, self->core_,
detail::handshake_op(type), handler2.value);
}
};
struct initiate_async_buffered_handshake
{
template <typename BufferedHandshakeHandler, typename ConstBufferSequence>
void operator()(ASIO_MOVE_ARG(BufferedHandshakeHandler) handler,
stream* self, handshake_type type,
const ConstBufferSequence& buffers) const
{
// If you get an error on the following line it means that your
// handler does not meet the documented type requirements for a
// BufferedHandshakeHandler.
ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK(
BufferedHandshakeHandler, handler) type_check;
asio::detail::non_const_lvalue<
BufferedHandshakeHandler> handler2(handler);
detail::async_io(self->next_layer_, self->core_,
detail::buffered_handshake_op<ConstBufferSequence>(type, buffers),
handler2.value);
}
};
struct initiate_async_shutdown
{
template <typename ShutdownHandler>
void operator()(ASIO_MOVE_ARG(ShutdownHandler) handler,
stream* self) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ShutdownHandler.
ASIO_HANDSHAKE_HANDLER_CHECK(ShutdownHandler, handler) type_check;
asio::detail::non_const_lvalue<ShutdownHandler> handler2(handler);
detail::async_io(self->next_layer_, self->core_,
detail::shutdown_op(), handler2.value);
}
};
struct initiate_async_write_some
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
stream* self, const ConstBufferSequence& buffers) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
asio::detail::non_const_lvalue<WriteHandler> handler2(handler);
detail::async_io(self->next_layer_, self->core_,
detail::write_op<ConstBufferSequence>(buffers), handler2.value);
}
};
struct initiate_async_read_some
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
stream* self, const MutableBufferSequence& buffers) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
asio::detail::non_const_lvalue<ReadHandler> handler2(handler);
detail::async_io(self->next_layer_, self->core_,
detail::read_op<MutableBufferSequence>(buffers), handler2.value);
}
};
Stream next_layer_;
detail::stream_core core_;
};

View File

@ -197,6 +197,7 @@ PREDEFINED = GENERATING_DOCUMENTATION \
ASIO_EOF_ERROR(e)=implementation_defined \
ASIO_OS_ERROR(e1,e2)=implementation_defined \
ASIO_MOVE_ARG(a)=a&& \
ASIO_NONDEDUCED_MOVE_ARG(a)=a& \
ASIO_DECL= \
ASIO_CONSTEXPR=constexpr \
ASIO_NOEXCEPT=noexcept \

View File

@ -103,7 +103,8 @@
not(contains(compoundname, '_handler')) and
not(contains(compoundname, 'std_allocator_void')) and
not(contains(compoundname, 'thread_function')) and
not(contains(compoundname, 'context_impl'))">
not(contains(compoundname, 'context_impl')) and
not(contains(compoundname, 'initiate_'))">
<xsl:call-template name="class"/>
</xsl:if>
</xsl:when>
@ -112,10 +113,12 @@
not(contains(ancestor::*/compoundname, '::detail')) and
not(contains(ancestor::*/compoundname, '::service::key')) and
not(contains(ancestor::*/compoundname, '_helper')) and
not(contains(ancestor::*/compoundname, 'initiate_')) and
not(contains(name, '_helper')) and
not(contains(name, 'std_allocator_void')) and
not(contains(name, 'thread_function')) and
not(contains(name, 'io_context_impl'))">
not(contains(name, 'io_context_impl')) and
not(contains(name, 'initiate_'))">
<xsl:call-template name="namespace-memberdef"/>
</xsl:if>
</xsl:otherwise>
@ -850,7 +853,7 @@
[[Name][Description]]
<xsl:for-each select="
sectiondef[@kind='public-type']/memberdef |
innerclass[@prot='public' and not(contains(., '_handler')) and not(contains(., 'thread_function'))]" mode="class-table">
innerclass[@prot='public' and not(contains(., '_handler')) and not(contains(., 'thread_function')) and not(contains(., 'initiate_'))]" mode="class-table">
<xsl:sort select="concat(name, (.)[not(name)])"/>
[
<xsl:choose>