Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / asio / async_result.hpp
index 4f3bb1e..d085798 100644 (file)
 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:
@@ -42,7 +102,7 @@ namespace asio {
  * 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:
@@ -68,8 +128,7 @@ 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.
@@ -77,6 +136,16 @@ public:
   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)(
@@ -85,9 +154,9 @@ public:
   }
 
 #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)
@@ -97,7 +166,8 @@ public:
   }
 
 #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, \
@@ -113,17 +183,26 @@ public:
 #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.
@@ -233,22 +312,50 @@ struct async_result_has_initiate_memfn
     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)
@@ -259,7 +366,8 @@ async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
       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,
@@ -280,10 +388,15 @@ async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
 
 #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)
 {
@@ -292,7 +405,9 @@ async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
       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
@@ -309,12 +424,17 @@ async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
 }
 
 #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)) \
@@ -325,7 +445,8 @@ async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
         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< \
@@ -350,6 +471,114 @@ async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
 
 #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