namespace boost {
namespace asio {
+#if defined(BOOST_ASIO_HAS_CONCEPTS) \
+ && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \
+ && defined(BOOST_ASIO_HAS_DECLTYPE)
+
+namespace detail {
+
+template <typename T>
+struct is_completion_signature : false_type
+{
+};
+
+template <typename R, typename... Args>
+struct is_completion_signature<R(Args...)> : true_type
+{
+};
+
+template <typename T, typename... Args>
+BOOST_ASIO_CONCEPT callable_with = requires(T t, Args&&... args)
+{
+ t(static_cast<Args&&>(args)...);
+};
+
+template <typename T, typename Signature>
+struct is_completion_handler_for : false_type
+{
+};
+
+template <typename T, typename R, typename... Args>
+struct is_completion_handler_for<T, R(Args...)>
+ : integral_constant<bool, (callable_with<T, Args...>)>
+{
+};
+
+} // namespace detail
+
+template <typename T>
+BOOST_ASIO_CONCEPT completion_signature =
+ detail::is_completion_signature<T>::value;
+
+#define BOOST_ASIO_COMPLETION_SIGNATURE \
+ ::boost::asio::completion_signature
+
+template <typename T, completion_signature Signature>
+BOOST_ASIO_CONCEPT completion_handler_for =
+ detail::is_completion_handler_for<T, Signature>::value;
+
+#define BOOST_ASIO_COMPLETION_HANDLER_FOR(s) \
+ ::boost::asio::completion_handler_for<s>
+
+#else // defined(BOOST_ASIO_HAS_CONCEPTS)
+ // && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+ // && defined(BOOST_ASIO_HAS_DECLTYPE)
+
+#define BOOST_ASIO_COMPLETION_SIGNATURE typename
+#define BOOST_ASIO_COMPLETION_HANDLER_FOR(s) typename
+
+#endif // defined(BOOST_ASIO_HAS_CONCEPTS)
+ // && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+ // && defined(BOOST_ASIO_HAS_DECLTYPE)
+
/// An interface for customising the behaviour of an initiating function.
/**
* The async_result traits class is used for determining:
* The primary template assumes that the CompletionToken is the completion
* handler.
*/
-template <typename CompletionToken, typename Signature>
+template <typename CompletionToken, BOOST_ASIO_COMPLETION_SIGNATURE Signature>
class async_result
{
public:
{
}
-#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \
- || defined(GENERATING_DOCUMENTATION)
+#if defined(GENERATING_DOCUMENTATION)
/// Initiate the asynchronous operation that will produce the result, and
/// obtain the value to be returned from the initiating function.
static return_type initiate(
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
+ BOOST_ASIO_MOVE_ARG(Args)... args);
+
+#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+ template <typename Initiation,
+ BOOST_ASIO_COMPLETION_HANDLER_FOR(Signature) RawCompletionToken,
+ typename... Args>
+ static return_type initiate(
+ BOOST_ASIO_MOVE_ARG(Initiation) initiation,
+ BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
BOOST_ASIO_MOVE_ARG(Args)... args)
{
BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
}
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
- // || defined(GENERATING_DOCUMENTATION)
- template <typename Initiation, typename RawCompletionToken>
+ template <typename Initiation,
+ BOOST_ASIO_COMPLETION_HANDLER_FOR(Signature) RawCompletionToken>
static return_type initiate(
BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_MOVE_ARG(RawCompletionToken) token)
}
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
- template <typename Initiation, typename RawCompletionToken, \
+ template <typename Initiation, \
+ BOOST_ASIO_COMPLETION_HANDLER_FOR(Signature) RawCompletionToken, \
BOOST_ASIO_VARIADIC_TPARAMS(n)> \
static return_type initiate( \
BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
#undef BOOST_ASIO_PRIVATE_INITIATE_DEF
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
- // || defined(GENERATING_DOCUMENTATION)
private:
async_result(const async_result&) BOOST_ASIO_DELETED;
async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
};
+#if !defined(GENERATING_DOCUMENTATION)
+
+template <BOOST_ASIO_COMPLETION_SIGNATURE Signature>
+class async_result<void, Signature>
+{
+ // Empty.
+};
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
/// Helper template to deduce the handler type from a CompletionToken, capture
/// a local copy of the handler, and then create an async_result for the
/// handler.
-template <typename CompletionToken, typename Signature>
+template <typename CompletionToken, BOOST_ASIO_COMPLETION_SIGNATURE Signature>
struct async_completion
{
/// The real handler type to be used for the asynchronous operation.
typename ::boost::asio::decay<ct>::type, sig>::completion_handler_type
#endif
+#if defined(GENERATION_DOCUMENTATION)
+# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
+ auto
+#elif defined(BOOST_ASIO_HAS_RETURN_TYPE_DEDUCTION)
+# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
+ auto
+#else
+# define BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ct, sig) \
+ BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig)
+#endif
+
+#if defined(GENERATION_DOCUMENTATION)
+# define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
+ void_or_deduced
+#elif defined(BOOST_ASIO_HAS_DECLTYPE)
+# define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
+ decltype expr
+#else
+# define BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(ct, sig, expr) \
+ BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig)
+#endif
+
#if defined(GENERATING_DOCUMENTATION)
-template <typename CompletionToken, typename Signature,
+template <typename CompletionToken,
+ completion_signature Signature,
typename Initiation, typename... Args>
-BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
-async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
+void_or_deduced async_initiate(
+ BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken),
BOOST_ASIO_MOVE_ARG(Args)... args);
#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
-template <typename CompletionToken, typename Signature,
+template <typename CompletionToken,
+ BOOST_ASIO_COMPLETION_SIGNATURE Signature,
typename Initiation, typename... Args>
inline typename enable_if<
detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
- BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
+ BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature,
+ (async_result<typename decay<CompletionToken>::type,
+ Signature>::initiate(declval<BOOST_ASIO_MOVE_ARG(Initiation)>(),
+ declval<BOOST_ASIO_MOVE_ARG(CompletionToken)>(),
+ declval<BOOST_ASIO_MOVE_ARG(Args)>()...)))>::type
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
BOOST_ASIO_MOVE_ARG(Args)... args)
BOOST_ASIO_MOVE_CAST(Args)(args)...);
}
-template <typename CompletionToken, typename Signature,
+template <typename CompletionToken,
+ BOOST_ASIO_COMPLETION_SIGNATURE Signature,
typename Initiation, typename... Args>
inline typename enable_if<
!detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
-template <typename CompletionToken, typename Signature, typename Initiation>
+template <typename CompletionToken,
+ BOOST_ASIO_COMPLETION_SIGNATURE Signature,
+ typename Initiation>
inline typename enable_if<
detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
- BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
+ BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature,
+ (async_result<typename decay<CompletionToken>::type,
+ Signature>::initiate(declval<BOOST_ASIO_MOVE_ARG(Initiation)>(),
+ declval<BOOST_ASIO_MOVE_ARG(CompletionToken)>())))>::type
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
{
BOOST_ASIO_MOVE_CAST(CompletionToken)(token));
}
-template <typename CompletionToken, typename Signature, typename Initiation>
+template <typename CompletionToken,
+ BOOST_ASIO_COMPLETION_SIGNATURE Signature,
+ typename Initiation>
inline typename enable_if<
!detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
}
#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
- template <typename CompletionToken, typename Signature, \
+ template <typename CompletionToken, \
+ BOOST_ASIO_COMPLETION_SIGNATURE Signature, \
typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
inline typename enable_if< \
detail::async_result_has_initiate_memfn< \
CompletionToken, Signature>::value, \
- BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \
+ BOOST_ASIO_INITFN_DEDUCED_RESULT_TYPE(CompletionToken, Signature, \
+ (async_result<typename decay<CompletionToken>::type, \
+ Signature>::initiate(declval<BOOST_ASIO_MOVE_ARG(Initiation)>(), \
+ declval<BOOST_ASIO_MOVE_ARG(CompletionToken)>(), \
+ BOOST_ASIO_VARIADIC_MOVE_DECLVAL(n))))>::type \
async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
} \
\
- template <typename CompletionToken, typename Signature, \
+ template <typename CompletionToken, \
+ BOOST_ASIO_COMPLETION_SIGNATURE Signature, \
typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
inline typename enable_if< \
!detail::async_result_has_initiate_memfn< \
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+#if defined(BOOST_ASIO_HAS_CONCEPTS) \
+ && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \
+ && defined(BOOST_ASIO_HAS_DECLTYPE)
+
+namespace detail {
+
+template <typename Signature>
+struct initiation_archetype
+{
+ template <completion_handler_for<Signature> CompletionHandler>
+ void operator()(CompletionHandler&&) const
+ {
+ }
+};
+
+} // namespace detail
+
+template <typename T, completion_signature Signature>
+BOOST_ASIO_CONCEPT completion_token_for = requires(T&& t)
+{
+ async_initiate<T, Signature>(detail::initiation_archetype<Signature>{}, t);
+};
+
+#define BOOST_ASIO_COMPLETION_TOKEN_FOR(s) \
+ ::boost::asio::completion_token_for<s>
+
+#else // defined(BOOST_ASIO_HAS_CONCEPTS)
+ // && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+ // && defined(BOOST_ASIO_HAS_DECLTYPE)
+
+#define BOOST_ASIO_COMPLETION_TOKEN_FOR(s) typename
+
+#endif // defined(BOOST_ASIO_HAS_CONCEPTS)
+ // && defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+ // && defined(BOOST_ASIO_HAS_DECLTYPE)
+
+namespace detail {
+
+template <typename>
+struct default_completion_token_check
+{
+ typedef void type;
+};
+
+template <typename T, typename = void>
+struct default_completion_token_impl
+{
+ typedef void type;
+};
+
+template <typename T>
+struct default_completion_token_impl<T,
+ typename default_completion_token_check<
+ typename T::default_completion_token_type>::type>
+{
+ typedef typename T::default_completion_token_type type;
+};
+
+} // namespace detail
+
+#if defined(GENERATING_DOCUMENTATION)
+
+/// Traits type used to determine the default completion token type associated
+/// with a type (such as an executor).
+/**
+ * A program may specialise this traits type if the @c T template parameter in
+ * the specialisation is a user-defined type.
+ *
+ * Specialisations of this trait may provide a nested typedef @c type, which is
+ * a default-constructible completion token type.
+ */
+template <typename T>
+struct default_completion_token
+{
+ /// If @c T has a nested type @c default_completion_token_type,
+ /// <tt>T::default_completion_token_type</tt>. Otherwise the typedef @c type
+ /// is not defined.
+ typedef see_below type;
+};
+#else
+template <typename T>
+struct default_completion_token
+ : detail::default_completion_token_impl<T>
+{
+};
+#endif
+
+#if defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
+
+template <typename T>
+using default_completion_token_t = typename default_completion_token<T>::type;
+
+#endif // defined(BOOST_ASIO_HAS_ALIAS_TEMPLATES)
+
+#if defined(BOOST_ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
+
+#define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e) \
+ = typename ::boost::asio::default_completion_token<e>::type
+#define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(e) \
+ = typename ::boost::asio::default_completion_token<e>::type()
+
+#else // defined(BOOST_ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
+
+#define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(e)
+#define BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(e)
+
+#endif // defined(BOOST_ASIO_HAS_DEFAULT_FUNCTION_TEMPLATE_ARGUMENTS)
+
} // namespace asio
} // namespace boost