You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by mp...@apache.org on 2016/01/20 00:58:57 UTC

[1/4] mesos git commit: Used SFINAE-friendly `result_of` in libprocess.

Repository: mesos
Updated Branches:
  refs/heads/master 0e968f886 -> 1565096f2


Used SFINAE-friendly `result_of` in libprocess.

Review: https://reviews.apache.org/r/41462


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/1565096f
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/1565096f
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/1565096f

Branch: refs/heads/master
Commit: 1565096f2fba4e6ac83e6ee44a81e0290b8f7f58
Parents: 576fa0e
Author: Michael Park <mp...@apache.org>
Authored: Sat Dec 12 11:29:36 2015 -0500
Committer: Michael Park <mp...@apache.org>
Committed: Tue Jan 19 15:51:56 2016 -0800

----------------------------------------------------------------------
 3rdparty/libprocess/include/process/async.hpp  | 69 +++++++++++----------
 3rdparty/libprocess/include/process/future.hpp | 14 +++--
 2 files changed, 44 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/1565096f/3rdparty/libprocess/include/process/async.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/async.hpp b/3rdparty/libprocess/include/process/async.hpp
index b80b60a..d2d6945 100644
--- a/3rdparty/libprocess/include/process/async.hpp
+++ b/3rdparty/libprocess/include/process/async.hpp
@@ -23,6 +23,7 @@
 #include <stout/lambda.hpp>
 #include <stout/nothing.hpp>
 #include <stout/preprocessor.hpp>
+#include <stout/result_of.hpp>
 
 namespace process {
 
@@ -33,30 +34,30 @@ namespace process {
 // brittle).
 
 template <typename F>
-Future<typename lambda::result_of<F(void)>::type> async(
+Future<typename result_of<F(void)>::type> async(
     const F& f,
-    typename boost::disable_if<boost::is_void<typename lambda::result_of<F(void)>::type> >::type* = NULL); // NOLINT(whitespace/line_length)
+    typename boost::disable_if<boost::is_void<typename result_of<F(void)>::type> >::type* = NULL); // NOLINT(whitespace/line_length)
 
 
 template <typename F>
 Future<Nothing> async(
     const F& f,
-    typename boost::enable_if<boost::is_void<typename lambda::result_of<F(void)>::type> >::type* = NULL); // NOLINT(whitespace/line_length)
+    typename boost::enable_if<boost::is_void<typename result_of<F(void)>::type> >::type* = NULL); // NOLINT(whitespace/line_length)
 
 
 #define TEMPLATE(Z, N, DATA)                                            \
   template <typename F, ENUM_PARAMS(N, typename A)>                     \
-  Future<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> async( \
+  Future<typename result_of<F(ENUM_PARAMS(N, A))>::type> async( \
       const F& f,                                                       \
       ENUM_BINARY_PARAMS(N, A, a),                                      \
-      typename boost::disable_if<boost::is_void<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> >::type* = NULL); /* NOLINT(whitespace/line_length) */ \
+      typename boost::disable_if<boost::is_void<typename result_of<F(ENUM_PARAMS(N, A))>::type> >::type* = NULL); /* NOLINT(whitespace/line_length) */ \
                                                                         \
                                                                         \
   template <typename F, ENUM_PARAMS(N, typename A)>                     \
   Future<Nothing> async(                                                \
       const F& f,                                                       \
       ENUM_BINARY_PARAMS(N, A, a),                                      \
-      typename boost::enable_if<boost::is_void<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> >::type* = NULL); // NOLINT(whitespace/line_length)
+      typename boost::enable_if<boost::is_void<typename result_of<F(ENUM_PARAMS(N, A))>::type> >::type* = NULL); // NOLINT(whitespace/line_length)
 
   REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
 #undef TEMPLATE
@@ -76,9 +77,9 @@ private:
   AsyncExecutorProcess& operator=(const AsyncExecutorProcess&);
 
   template <typename F>
-  typename lambda::result_of<F(void)>::type execute(
+  typename result_of<F(void)>::type execute(
       const F& f,
-      typename boost::disable_if<boost::is_void<typename lambda::result_of<F(void)>::type> >::type* = NULL) // NOLINT(whitespace/line_length)
+      typename boost::disable_if<boost::is_void<typename result_of<F(void)>::type> >::type* = NULL) // NOLINT(whitespace/line_length)
   {
     terminate(self()); // Terminate process after function returns.
     return f();
@@ -87,7 +88,7 @@ private:
   template <typename F>
   Nothing execute(
       const F& f,
-      typename boost::enable_if<boost::is_void<typename lambda::result_of<F(void)>::type> >::type* = NULL) // NOLINT(whitespace/line_length)
+      typename boost::enable_if<boost::is_void<typename result_of<F(void)>::type> >::type* = NULL) // NOLINT(whitespace/line_length)
   {
     terminate(self()); // Terminate process after function returns.
     f();
@@ -96,10 +97,10 @@ private:
 
 #define TEMPLATE(Z, N, DATA)                                            \
   template <typename F, ENUM_PARAMS(N, typename A)>                     \
-  typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type execute(       \
+  typename result_of<F(ENUM_PARAMS(N, A))>::type execute(       \
       const F& f,                                                       \
       ENUM_BINARY_PARAMS(N, A, a),                                      \
-      typename boost::disable_if<boost::is_void<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> >::type* = NULL) /* NOLINT(whitespace/line_length) */ \
+      typename boost::disable_if<boost::is_void<typename result_of<F(ENUM_PARAMS(N, A))>::type> >::type* = NULL) /* NOLINT(whitespace/line_length) */ \
   {                                                                     \
     terminate(self()); /* Terminate process after function returns. */  \
     return f(ENUM_PARAMS(N, a));                                        \
@@ -109,7 +110,7 @@ private:
   Nothing execute(                                                      \
       const F& f,                                                       \
       ENUM_BINARY_PARAMS(N, A, a),                                      \
-      typename boost::enable_if<boost::is_void<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> >::type* = NULL) /* NOLINT(whitespace/line_length) */ \
+      typename boost::enable_if<boost::is_void<typename result_of<F(ENUM_PARAMS(N, A))>::type> >::type* = NULL) /* NOLINT(whitespace/line_length) */ \
   {                                                                     \
     terminate(self()); /* Terminate process after function returns. */  \
     f(ENUM_PARAMS(N, a));                                               \
@@ -127,27 +128,27 @@ class AsyncExecutor
 private:
   // Declare async functions as friends.
   template <typename F>
-  friend Future<typename lambda::result_of<F(void)>::type> async(
+  friend Future<typename result_of<F(void)>::type> async(
       const F& f,
-      typename boost::disable_if<boost::is_void<typename lambda::result_of<F(void)>::type> >::type*); // NOLINT(whitespace/line_length)
+      typename boost::disable_if<boost::is_void<typename result_of<F(void)>::type> >::type*); // NOLINT(whitespace/line_length)
 
   template <typename F>
   friend Future<Nothing> async(
       const F& f,
-      typename boost::enable_if<boost::is_void<typename lambda::result_of<F(void)>::type> >::type*); // NOLINT(whitespace/line_length)
+      typename boost::enable_if<boost::is_void<typename result_of<F(void)>::type> >::type*); // NOLINT(whitespace/line_length)
 
 #define TEMPLATE(Z, N, DATA)                                            \
   template <typename F, ENUM_PARAMS(N, typename A)>                     \
-  friend Future<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> async( \
+  friend Future<typename result_of<F(ENUM_PARAMS(N, A))>::type> async( \
       const F& f,                                                       \
       ENUM_BINARY_PARAMS(N, A, a),                                      \
-      typename boost::disable_if<boost::is_void<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> >::type*); /* NOLINT(whitespace/line_length) */ \
+      typename boost::disable_if<boost::is_void<typename result_of<F(ENUM_PARAMS(N, A))>::type> >::type*); /* NOLINT(whitespace/line_length) */ \
                                                                         \
   template <typename F, ENUM_PARAMS(N, typename A)>                     \
   friend Future<Nothing> async(                                         \
       const F& f,                                                       \
       ENUM_BINARY_PARAMS(N, A, a),                                      \
-      typename boost::enable_if<boost::is_void<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> >::type*); // NOLINT(whitespace/line_length)
+      typename boost::enable_if<boost::is_void<typename result_of<F(ENUM_PARAMS(N, A))>::type> >::type*); // NOLINT(whitespace/line_length)
 
   REPEAT_FROM_TO(1, 11, TEMPLATE, _) // Args A0 -> A9.
 #undef TEMPLATE
@@ -165,12 +166,12 @@ private:
   AsyncExecutor& operator=(const AsyncExecutor&);
 
   template <typename F>
-  Future<typename lambda::result_of<F(void)>::type> execute(
+  Future<typename result_of<F(void)>::type> execute(
       const F& f,
-      typename boost::disable_if<boost::is_void<typename lambda::result_of<F(void)>::type> >::type* = NULL) // NOLINT(whitespace/line_length)
+      typename boost::disable_if<boost::is_void<typename result_of<F(void)>::type> >::type* = NULL) // NOLINT(whitespace/line_length)
   {
     // Need to disambiguate overloaded method.
-    typename lambda::result_of<F(void)>::type(AsyncExecutorProcess::*method)(const F&, typename boost::disable_if<boost::is_void<typename lambda::result_of<F(void)>::type> >::type*) = // NOLINT(whitespace/line_length)
+    typename result_of<F(void)>::type(AsyncExecutorProcess::*method)(const F&, typename boost::disable_if<boost::is_void<typename result_of<F(void)>::type> >::type*) = // NOLINT(whitespace/line_length)
       &AsyncExecutorProcess::execute<F>;
 
     return dispatch(process, method, f, (void*) NULL);
@@ -179,10 +180,10 @@ private:
   template <typename F>
   Future<Nothing> execute(
       const F& f,
-      typename boost::enable_if<boost::is_void<typename lambda::result_of<F(void)>::type> >::type* = NULL) // NOLINT(whitespace/line_length)
+      typename boost::enable_if<boost::is_void<typename result_of<F(void)>::type> >::type* = NULL) // NOLINT(whitespace/line_length)
   {
     // Need to disambiguate overloaded method.
-    Nothing(AsyncExecutorProcess::*method)(const F&, typename boost::enable_if<boost::is_void<typename lambda::result_of<F(void)>::type> >::type*) = // NOLINT(whitespace/line_length)
+    Nothing(AsyncExecutorProcess::*method)(const F&, typename boost::enable_if<boost::is_void<typename result_of<F(void)>::type> >::type*) = // NOLINT(whitespace/line_length)
       &AsyncExecutorProcess::execute<F>;
 
     return dispatch(process, method, f, (void*) NULL);
@@ -190,13 +191,13 @@ private:
 
 #define TEMPLATE(Z, N, DATA)                                            \
   template <typename F, ENUM_PARAMS(N, typename A)>                     \
-  Future<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> execute( \
+  Future<typename result_of<F(ENUM_PARAMS(N, A))>::type> execute( \
       const F& f,                                                       \
       ENUM_BINARY_PARAMS(N, A, a),                                      \
-      typename boost::disable_if<boost::is_void<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> >::type* = NULL) /* NOLINT(whitespace/line_length) */ \
+      typename boost::disable_if<boost::is_void<typename result_of<F(ENUM_PARAMS(N, A))>::type> >::type* = NULL) /* NOLINT(whitespace/line_length) */ \
   {                                                                     \
     /* Need to disambiguate overloaded method. */                       \
-    typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type(AsyncExecutorProcess::*method)(const F&, ENUM_PARAMS(N, A), typename boost::disable_if<boost::is_void<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> >::type*) = /* NOLINT(whitespace/line_length) */ \
+    typename result_of<F(ENUM_PARAMS(N, A))>::type(AsyncExecutorProcess::*method)(const F&, ENUM_PARAMS(N, A), typename boost::disable_if<boost::is_void<typename result_of<F(ENUM_PARAMS(N, A))>::type> >::type*) = /* NOLINT(whitespace/line_length) */ \
       &AsyncExecutorProcess::execute<F, ENUM_PARAMS(N, A)>;             \
                                                                         \
     return dispatch(process, method, f, ENUM_PARAMS(N, a), (void*) NULL); \
@@ -206,10 +207,10 @@ private:
   Future<Nothing> execute(                                              \
       const F& f,                                                       \
       ENUM_BINARY_PARAMS(N, A, a),                                      \
-      typename boost::enable_if<boost::is_void<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> >::type* = NULL) /* NOLINT(whitespace/line_length) */ \
+      typename boost::enable_if<boost::is_void<typename result_of<F(ENUM_PARAMS(N, A))>::type> >::type* = NULL) /* NOLINT(whitespace/line_length) */ \
   {                                                                     \
     /* Need to disambiguate overloaded method. */                       \
-    Nothing(AsyncExecutorProcess::*method)(const F&, ENUM_PARAMS(N, A), typename boost::enable_if<boost::is_void<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> >::type*) = /* NOLINT(whitespace/line_length) */ \
+    Nothing(AsyncExecutorProcess::*method)(const F&, ENUM_PARAMS(N, A), typename boost::enable_if<boost::is_void<typename result_of<F(ENUM_PARAMS(N, A))>::type> >::type*) = /* NOLINT(whitespace/line_length) */ \
       &AsyncExecutorProcess::execute<F, ENUM_PARAMS(N, A)>;             \
                                                                         \
     return dispatch(process, method, f, ENUM_PARAMS(N, a), (void*) NULL); \
@@ -224,9 +225,9 @@ private:
 
 // Provides an abstraction for asynchronously executing a function.
 template <typename F>
-Future<typename lambda::result_of<F(void)>::type> async(
+Future<typename result_of<F(void)>::type> async(
     const F& f,
-    typename boost::disable_if<boost::is_void<typename lambda::result_of<F(void)>::type> >::type*) // NOLINT(whitespace/line_length)
+    typename boost::disable_if<boost::is_void<typename result_of<F(void)>::type> >::type*) // NOLINT(whitespace/line_length)
 {
   return AsyncExecutor().execute(f);
 }
@@ -235,7 +236,7 @@ Future<typename lambda::result_of<F(void)>::type> async(
 template <typename F>
 Future<Nothing> async(
     const F& f,
-    typename boost::enable_if<boost::is_void<typename lambda::result_of<F(void)>::type> >::type*) // NOLINT(whitespace/line_length)
+    typename boost::enable_if<boost::is_void<typename result_of<F(void)>::type> >::type*) // NOLINT(whitespace/line_length)
 {
   return AsyncExecutor().execute(f);
 }
@@ -243,10 +244,10 @@ Future<Nothing> async(
 
 #define TEMPLATE(Z, N, DATA)                                            \
   template <typename F, ENUM_PARAMS(N, typename A)>                     \
-  Future<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> async( \
+  Future<typename result_of<F(ENUM_PARAMS(N, A))>::type> async( \
       const F& f,                                                       \
       ENUM_BINARY_PARAMS(N, A, a),                                      \
-      typename boost::disable_if<boost::is_void<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> >::type*) /* NOLINT(whitespace/line_length) */ \
+      typename boost::disable_if<boost::is_void<typename result_of<F(ENUM_PARAMS(N, A))>::type> >::type*) /* NOLINT(whitespace/line_length) */ \
   {                                                                     \
     return AsyncExecutor().execute(f, ENUM_PARAMS(N, a));               \
   }                                                                     \
@@ -255,7 +256,7 @@ Future<Nothing> async(
   Future<Nothing> async(                                                \
       const F& f,                                                       \
       ENUM_BINARY_PARAMS(N, A, a),                                      \
-      typename boost::enable_if<boost::is_void<typename lambda::result_of<F(ENUM_PARAMS(N, A))>::type> >::type*) /* NOLINT(whitespace/line_length) */ \
+      typename boost::enable_if<boost::is_void<typename result_of<F(ENUM_PARAMS(N, A))>::type> >::type*) /* NOLINT(whitespace/line_length) */ \
   {                                                                     \
     return AsyncExecutor().execute(f, ENUM_PARAMS(N, a));               \
   }

http://git-wip-us.apache.org/repos/asf/mesos/blob/1565096f/3rdparty/libprocess/include/process/future.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/future.hpp b/3rdparty/libprocess/include/process/future.hpp
index dc356d0..a05d9e4 100644
--- a/3rdparty/libprocess/include/process/future.hpp
+++ b/3rdparty/libprocess/include/process/future.hpp
@@ -41,6 +41,7 @@
 #include <stout/option.hpp>
 #include <stout/preprocessor.hpp>
 #include <stout/result.hpp>
+#include <stout/result_of.hpp>
 #include <stout/synchronized.hpp>
 #include <stout/try.hpp>
 
@@ -210,7 +211,7 @@ private:
   struct LessPrefer {};
   struct Prefer : LessPrefer {};
 
-  template <typename F, typename = typename std::result_of<F(const T&)>::type>
+  template <typename F, typename = typename result_of<F(const T&)>::type>
   const Future<T>& onReady(F&& f, Prefer) const
   {
     return onReady(std::function<void(const T&)>(
@@ -240,7 +241,7 @@ private:
         }));
   }
 
-  template <typename F, typename = typename std::result_of<F(const std::string&)>::type> // NOLINT(whitespace/line_length)
+  template <typename F, typename = typename result_of<F(const std::string&)>::type> // NOLINT(whitespace/line_length)
   const Future<T>& onFailed(F&& f, Prefer) const
   {
     return onFailed(std::function<void(const std::string&)>(
@@ -264,7 +265,7 @@ private:
         }));
   }
 
-  template <typename F, typename = typename std::result_of<F(const Future<T>&)>::type> // NOLINT(whitespace/line_length)
+  template <typename F, typename = typename result_of<F(const Future<T>&)>::type> // NOLINT(whitespace/line_length)
   const Future<T>& onAny(F&& f, Prefer) const
   {
     return onAny(std::function<void(const Future<T>&)>(
@@ -347,7 +348,10 @@ public:
   }
 
 private:
-  template <typename F, typename X = typename internal::unwrap<typename std::result_of<F(const T&)>::type>::type> // NOLINT(whitespace/line_length)
+  template <
+      typename F,
+      typename X =
+        typename internal::unwrap<typename result_of<F(const T&)>::type>::type>
   Future<X> then(_Deferred<F>&& f, Prefer) const
   {
     // note the then<X> is necessary to not have an infinite loop with
@@ -368,7 +372,7 @@ private:
     return then<X>(f.operator std::function<Future<X>()>());
   }
 
-  template <typename F, typename X = typename internal::unwrap<typename std::result_of<F(const T&)>::type>::type> // NOLINT(whitespace/line_length)
+  template <typename F, typename X = typename internal::unwrap<typename result_of<F(const T&)>::type>::type> // NOLINT(whitespace/line_length)
   Future<X> then(F&& f, Prefer) const
   {
     return then<X>(std::function<Future<X>(const T&)>(f));


[2/4] mesos git commit: Used `std::is_bind_expression` to SFINAE correctly.

Posted by mp...@apache.org.
Used `std::is_bind_expression` to SFINAE correctly.

Review: https://reviews.apache.org/r/41460


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/a5a42d5e
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/a5a42d5e
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/a5a42d5e

Branch: refs/heads/master
Commit: a5a42d5e861ee848c79370ed2408f8382ab1010a
Parents: b15161e
Author: Michael Park <mp...@apache.org>
Authored: Tue Jan 5 18:07:26 2016 -0800
Committer: Michael Park <mp...@apache.org>
Committed: Tue Jan 19 15:51:56 2016 -0800

----------------------------------------------------------------------
 3rdparty/libprocess/include/process/future.hpp | 48 ++++++++++++++++++---
 1 file changed, 43 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/a5a42d5e/3rdparty/libprocess/include/process/future.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/future.hpp b/3rdparty/libprocess/include/process/future.hpp
index 280690c..dc356d0 100644
--- a/3rdparty/libprocess/include/process/future.hpp
+++ b/3rdparty/libprocess/include/process/future.hpp
@@ -219,7 +219,19 @@ private:
         }));
   }
 
-  template <typename F, typename = typename std::result_of<F()>::type>
+  // This is the less prefered `onReady`, we prefer the `onReady` method which
+  // has `f` taking a `const T&` parameter. Unfortunately, to complicate
+  // matters, if `F` is the result of a `std::bind` expression we need to SFINAE
+  // out this version of `onReady` and force the use of the preferred `onReady`
+  // (which works because `std::bind` will just ignore the `const T&` argument).
+  // This is necessary because Visual Studio 2015 doesn't support using the
+  // `std::bind` call operator with `std::result_of` as it's technically not a
+  // requirement by the C++ standard.
+  template <
+      typename F,
+      typename = typename std::result_of<typename std::enable_if<
+          !std::is_bind_expression<typename std::decay<F>::type>::value,
+          F>::type()>::type>
   const Future<T>& onReady(F&& f, LessPrefer) const
   {
     return onReady(std::function<void(const T&)>(
@@ -237,7 +249,13 @@ private:
         }));
   }
 
-  template <typename F, typename = typename std::result_of<F()>::type>
+  // Refer to the less preferred version of `onReady` for why these SFINAE
+  // conditions are necessary.
+  template <
+      typename F,
+      typename = typename std::result_of<typename std::enable_if<
+          !std::is_bind_expression<typename std::decay<F>::type>::value,
+          F>::type()>::type>
   const Future<T>& onFailed(F&& f, LessPrefer) const
   {
     return onFailed(std::function<void(const std::string&)>(
@@ -255,7 +273,13 @@ private:
         }));
   }
 
-  template <typename F, typename = typename std::result_of<F()>::type>
+  // Refer to the less preferred version of `onReady` for why these SFINAE
+  // conditions are necessary.
+  template <
+      typename F,
+      typename = typename std::result_of<typename std::enable_if<
+          !std::is_bind_expression<typename std::decay<F>::type>::value,
+          F>::type()>::type>
   const Future<T>& onAny(F&& f, LessPrefer) const
   {
     return onAny(std::function<void(const Future<T>&)>(
@@ -331,7 +355,14 @@ private:
     return then<X>(f.operator std::function<Future<X>(const T&)>());
   }
 
-  template <typename F, typename X = typename internal::unwrap<typename std::result_of<F()>::type>::type> // NOLINT(whitespace/line_length)
+  // Refer to the less preferred version of `onReady` for why these SFINAE
+  // conditions are necessary.
+  template <
+      typename F,
+      typename X = typename internal::unwrap<
+          typename std::result_of<typename std::enable_if<
+              !std::is_bind_expression<typename std::decay<F>::type>::value,
+              F>::type()>::type>::type>
   Future<X> then(_Deferred<F>&& f, LessPrefer) const
   {
     return then<X>(f.operator std::function<Future<X>()>());
@@ -343,7 +374,14 @@ private:
     return then<X>(std::function<Future<X>(const T&)>(f));
   }
 
-  template <typename F, typename X = typename internal::unwrap<typename std::result_of<F()>::type>::type> // NOLINT(whitespace/line_length)
+  // Refer to the less preferred version of `onReady` for why these SFINAE
+  // conditions are necessary.
+  template <
+      typename F,
+      typename X = typename internal::unwrap<
+          typename std::result_of<typename std::enable_if<
+              !std::is_bind_expression<typename std::decay<F>::type>::value,
+              F>::type()>::type>::type>
   Future<X> then(F&& f, LessPrefer) const
   {
     return then<X>(std::function<Future<X>()>(f));


[3/4] mesos git commit: Added SFINAE-friendly `result_of` in stout.

Posted by mp...@apache.org.
Added SFINAE-friendly `result_of` in stout.

Review: https://reviews.apache.org/r/41461


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/576fa0ee
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/576fa0ee
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/576fa0ee

Branch: refs/heads/master
Commit: 576fa0ee11f81006950094d4e35d231e7cb11472
Parents: a5a42d5
Author: Michael Park <mp...@apache.org>
Authored: Sat Dec 12 11:29:12 2015 -0500
Committer: Michael Park <mp...@apache.org>
Committed: Tue Jan 19 15:51:56 2016 -0800

----------------------------------------------------------------------
 .../3rdparty/stout/include/Makefile.am          |  1 +
 .../3rdparty/stout/include/stout/result_of.hpp  | 82 ++++++++++++++++++++
 2 files changed, 83 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/576fa0ee/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/Makefile.am b/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
index b257ab2..1c452fb 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
+++ b/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
@@ -133,6 +133,7 @@ nobase_include_HEADERS =		\
   stout/recordio.hpp			\
   stout/representation.hpp			\
   stout/result.hpp			\
+  stout/result_of.hpp			\
   stout/set.hpp				\
   stout/some.hpp			\
   stout/stopwatch.hpp			\

http://git-wip-us.apache.org/repos/asf/mesos/blob/576fa0ee/3rdparty/libprocess/3rdparty/stout/include/stout/result_of.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/result_of.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/result_of.hpp
new file mode 100644
index 0000000..ee2bbd9
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/result_of.hpp
@@ -0,0 +1,82 @@
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef __STOUT_RESULT_OF_HPP__
+#define __STOUT_RESULT_OF_HPP__
+
+#include <type_traits>
+
+#ifndef __WINDOWS__
+using std::result_of;
+#else
+// TODO(mpark): Switch back to simply using `std::result_of` this once we
+// upgrade our Windows support to VS 2015 Update 2 (MESOS-3993).
+
+#include <utility>
+
+namespace internal {
+
+// TODO(mpark): Consider pulling this out to something like <stout/meta.hpp>,
+// This pattern already exists in `<process/future.hpp>`.
+struct LessPrefer {};
+struct Prefer : LessPrefer {};
+
+
+// A tag type that indicates substitution failure.
+struct Fail;
+
+// Perform the necessary expression SFINAE in a context supported in VS 2015
+// Update 1. Note that it leverages `std::invoke` which is carefully written to
+// avoid the limitations around the partial expression SFINAE support.
+
+// `std::invoke` is a C++17 feature, but we only compile this code for Windows,
+// which has it implemented in VS 2015 Update 1. It is also supposed to be
+// defined in `<functional>`, but is included in `<utility>` in VS.
+template <typename F, typename... Args>
+auto result_of_test(Prefer)
+  -> decltype(std::invoke(std::declval<F>(), std::declval<Args>()...));
+
+
+// Report `Fail` if expression SFINAE fails in the above overload.
+template <typename, typename...>
+Fail result_of_test(LessPrefer);
+
+
+// The generic case where `std::invoke(f, args...)` is well-formed.
+template <typename T>
+struct result_of_impl { using type = T; };
+
+
+// The specialization for SFINAE failure case where
+// `std::invoke(f, args...)` is ill-formed.
+template <>
+struct result_of_impl<Fail> {};
+
+
+template <typename F>
+struct result_of;  // undefined.
+
+
+// `decltype(result_of_test<F, Args...>(Prefer()))` is either `Fail` in the case
+// of substitution failure, or the return type of `std::invoke(f, args...)`.
+// `result_of_impl` provides a member typedef `type = T` only if `T != Fail`.
+template <typename F, typename... Args>
+struct result_of<F(Args...)>
+  : result_of_impl<decltype(result_of_test<F, Args...>(Prefer()))> {};
+
+} // namespace internal {
+
+using internal::result_of;
+
+#endif // __WINDOWS__
+
+#endif // __STOUT_RESULT_OF_HPP__


[4/4] mesos git commit: Invoked `_Deferred`'s `operator F()` explicitly.

Posted by mp...@apache.org.
Invoked `_Deferred`'s `operator F()` explicitly.

Review: https://reviews.apache.org/r/41459


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/b15161ee
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/b15161ee
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/b15161ee

Branch: refs/heads/master
Commit: b15161eea964c196276b51ef24763fee2f409d57
Parents: 0e968f8
Author: Michael Park <mp...@apache.org>
Authored: Tue Dec 15 02:54:56 2015 +0000
Committer: Michael Park <mp...@apache.org>
Committed: Tue Jan 19 15:51:56 2016 -0800

----------------------------------------------------------------------
 3rdparty/libprocess/include/process/future.hpp | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/b15161ee/3rdparty/libprocess/include/process/future.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/future.hpp b/3rdparty/libprocess/include/process/future.hpp
index bcb5668..280690c 100644
--- a/3rdparty/libprocess/include/process/future.hpp
+++ b/3rdparty/libprocess/include/process/future.hpp
@@ -170,31 +170,32 @@ public:
   template <typename F>
   const Future<T>& onDiscard(_Deferred<F>&& deferred) const
   {
-    return onDiscard(std::function<void()>(deferred));
+    return onDiscard(deferred.operator std::function<void()>());
   }
 
   template <typename F>
   const Future<T>& onReady(_Deferred<F>&& deferred) const
   {
-    return onReady(std::function<void(const T&)>(deferred));
+    return onReady(deferred.operator std::function<void(const T&)>());
   }
 
   template <typename F>
   const Future<T>& onFailed(_Deferred<F>&& deferred) const
   {
-    return onFailed(std::function<void(const std::string&)>(deferred));
+    return onFailed(
+        deferred.operator std::function<void(const std::string&)>());
   }
 
   template <typename F>
   const Future<T>& onDiscarded(_Deferred<F>&& deferred) const
   {
-    return onDiscarded(std::function<void()>(deferred));
+    return onDiscarded(deferred.operator std::function<void()>());
   }
 
   template <typename F>
   const Future<T>& onAny(_Deferred<F>&& deferred) const
   {
-    return onAny(std::function<void(const Future<T>&)>(deferred));
+    return onAny(deferred.operator std::function<void(const Future<T>&)>());
   }
 
 private:
@@ -327,13 +328,13 @@ private:
   {
     // note the then<X> is necessary to not have an infinite loop with
     // then(F&& f)
-    return then<X>(std::function<Future<X>(const T&)>(f));
+    return then<X>(f.operator std::function<Future<X>(const T&)>());
   }
 
   template <typename F, typename X = typename internal::unwrap<typename std::result_of<F()>::type>::type> // NOLINT(whitespace/line_length)
   Future<X> then(_Deferred<F>&& f, LessPrefer) const
   {
-    return then<X>(std::function<Future<X>()>(f));
+    return then<X>(f.operator std::function<Future<X>()>());
   }
 
   template <typename F, typename X = typename internal::unwrap<typename std::result_of<F(const T&)>::type>::type> // NOLINT(whitespace/line_length)