Prepared `defer` for use in callable-once contexts. This changes `defer` to use `lambda::partial` instead of `std::bind`, which allows it be used in callable-once contexts.
Review: https://reviews.apache.org/r/63635/ Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/13eda278 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/13eda278 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/13eda278 Branch: refs/heads/master Commit: 13eda27802cfe05800d4dcbed22c46ca7b46bafb Parents: 0d9ce98 Author: Dmitry Zhuk <dz...@twopensource.com> Authored: Tue Dec 5 10:40:37 2017 -0800 Committer: Michael Park <mp...@apache.org> Committed: Tue Dec 5 10:56:56 2017 -0800 ---------------------------------------------------------------------- 3rdparty/libprocess/include/process/defer.hpp | 68 +++++++++++--------- .../libprocess/include/process/deferred.hpp | 6 +- 2 files changed, 39 insertions(+), 35 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/13eda278/3rdparty/libprocess/include/process/defer.hpp ---------------------------------------------------------------------- diff --git a/3rdparty/libprocess/include/process/defer.hpp b/3rdparty/libprocess/include/process/defer.hpp index 1c114a8..a5e9b98 100644 --- a/3rdparty/libprocess/include/process/defer.hpp +++ b/3rdparty/libprocess/include/process/defer.hpp @@ -60,7 +60,10 @@ Deferred<void()> defer(const Process<T>* process, void (T::*method)()) // http://stackoverflow.com/questions/20097616/stdbind-to-a-stdfunction-crashes-with-clang). // This assumes that type and variable base names are `A` and `a` respectively. -#define FORWARD(Z, N, DATA) std::forward<A ## N>(a ## N) +#define FORWARD_A(Z, N, DATA) std::forward<A ## N>(a ## N) + +// This assumes that type and variable base names are `P` and `p` respectively. +#define FORWARD_P(Z, N, DATA) std::forward<P ## N>(p ## N) #define TEMPLATE(Z, N, DATA) \ template <typename T, \ @@ -70,19 +73,19 @@ Deferred<void()> defer(const Process<T>* process, void (T::*method)()) void (T::*method)(ENUM_PARAMS(N, P)), \ ENUM_BINARY_PARAMS(N, A, &&a)) \ -> _Deferred<decltype( \ - std::bind( \ + lambda::partial( \ &std::function<void(ENUM_PARAMS(N, P))>::operator(), \ std::function<void(ENUM_PARAMS(N, P))>(), \ - ENUM(N, FORWARD, _)))> \ + ENUM(N, FORWARD_A, _)))> \ { \ std::function<void(ENUM_PARAMS(N, P))> f( \ - [=](ENUM_BINARY_PARAMS(N, P, p)) { \ - dispatch(pid, method, ENUM_PARAMS(N, p)); \ + [=](ENUM_BINARY_PARAMS(N, P, &&p)) { \ + dispatch(pid, method, ENUM(N, FORWARD_P, _)); \ }); \ - return std::bind( \ + return lambda::partial( \ &std::function<void(ENUM_PARAMS(N, P))>::operator(), \ std::move(f), \ - ENUM(N, FORWARD, _)); \ + ENUM(N, FORWARD_A, _)); \ } \ \ template <typename T, \ @@ -91,9 +94,9 @@ Deferred<void()> defer(const Process<T>* process, void (T::*method)()) auto defer(const Process<T>& process, \ void (T::*method)(ENUM_PARAMS(N, P)), \ ENUM_BINARY_PARAMS(N, A, &&a)) \ - -> decltype(defer(process.self(), method, ENUM(N, FORWARD, _))) \ + -> decltype(defer(process.self(), method, ENUM(N, FORWARD_A, _))) \ { \ - return defer(process.self(), method, ENUM(N, FORWARD, _)); \ + return defer(process.self(), method, ENUM(N, FORWARD_A, _)); \ } \ \ template <typename T, \ @@ -102,9 +105,9 @@ Deferred<void()> defer(const Process<T>* process, void (T::*method)()) auto defer(const Process<T>* process, \ void (T::*method)(ENUM_PARAMS(N, P)), \ ENUM_BINARY_PARAMS(N, A, &&a)) \ - -> decltype(defer(process->self(), method, ENUM(N, FORWARD, _))) \ + -> decltype(defer(process->self(), method, ENUM(N, FORWARD_A, _))) \ { \ - return defer(process->self(), method, ENUM(N, FORWARD, _)); \ + return defer(process->self(), method, ENUM(N, FORWARD_A, _)); \ } REPEAT_FROM_TO(1, 13, TEMPLATE, _) // Args A0 -> A11. @@ -140,19 +143,19 @@ Deferred<Future<R>()> defer(const Process<T>* process, Future<R> (T::*method)()) Future<R> (T::*method)(ENUM_PARAMS(N, P)), \ ENUM_BINARY_PARAMS(N, A, &&a)) \ -> _Deferred<decltype( \ - std::bind( \ + lambda::partial( \ &std::function<Future<R>(ENUM_PARAMS(N, P))>::operator(), \ std::function<Future<R>(ENUM_PARAMS(N, P))>(), \ - ENUM(N, FORWARD, _)))> \ + ENUM(N, FORWARD_A, _)))> \ { \ std::function<Future<R>(ENUM_PARAMS(N, P))> f( \ - [=](ENUM_BINARY_PARAMS(N, P, p)) { \ - return dispatch(pid, method, ENUM_PARAMS(N, p)); \ + [=](ENUM_BINARY_PARAMS(N, P, &&p)) { \ + return dispatch(pid, method, ENUM(N, FORWARD_P, _)); \ }); \ - return std::bind( \ + return lambda::partial( \ &std::function<Future<R>(ENUM_PARAMS(N, P))>::operator(), \ std::move(f), \ - ENUM(N, FORWARD, _)); \ + ENUM(N, FORWARD_A, _)); \ } \ \ template <typename R, \ @@ -162,9 +165,9 @@ Deferred<Future<R>()> defer(const Process<T>* process, Future<R> (T::*method)()) auto defer(const Process<T>& process, \ Future<R> (T::*method)(ENUM_PARAMS(N, P)), \ ENUM_BINARY_PARAMS(N, A, &&a)) \ - -> decltype(defer(process.self(), method, ENUM(N, FORWARD, _))) \ + -> decltype(defer(process.self(), method, ENUM(N, FORWARD_A, _))) \ { \ - return defer(process.self(), method, ENUM(N, FORWARD, _)); \ + return defer(process.self(), method, ENUM(N, FORWARD_A, _)); \ } \ \ template <typename R, \ @@ -174,9 +177,9 @@ Deferred<Future<R>()> defer(const Process<T>* process, Future<R> (T::*method)()) auto defer(const Process<T>* process, \ Future<R> (T::*method)(ENUM_PARAMS(N, P)), \ ENUM_BINARY_PARAMS(N, A, &&a)) \ - -> decltype(defer(process->self(), method, ENUM(N, FORWARD, _))) \ + -> decltype(defer(process->self(), method, ENUM(N, FORWARD_A, _))) \ { \ - return defer(process->self(), method, ENUM(N, FORWARD, _)); \ + return defer(process->self(), method, ENUM(N, FORWARD_A, _)); \ } REPEAT_FROM_TO(1, 13, TEMPLATE, _) // Args A0 -> A11. @@ -212,19 +215,19 @@ Deferred<Future<R>()> defer(const Process<T>* process, R (T::*method)()) R (T::*method)(ENUM_PARAMS(N, P)), \ ENUM_BINARY_PARAMS(N, A, &&a)) \ -> _Deferred<decltype( \ - std::bind( \ + lambda::partial( \ &std::function<Future<R>(ENUM_PARAMS(N, P))>::operator(), \ std::function<Future<R>(ENUM_PARAMS(N, P))>(), \ - ENUM(N, FORWARD, _)))> \ + ENUM(N, FORWARD_A, _)))> \ { \ std::function<Future<R>(ENUM_PARAMS(N, P))> f( \ - [=](ENUM_BINARY_PARAMS(N, P, p)) { \ - return dispatch(pid, method, ENUM_PARAMS(N, p)); \ + [=](ENUM_BINARY_PARAMS(N, P, &&p)) { \ + return dispatch(pid, method, ENUM(N, FORWARD_P, _)); \ }); \ - return std::bind( \ + return lambda::partial( \ &std::function<Future<R>(ENUM_PARAMS(N, P))>::operator(), \ std::move(f), \ - ENUM(N, FORWARD, _)); \ + ENUM(N, FORWARD_A, _)); \ } \ \ template <typename R, \ @@ -235,9 +238,9 @@ Deferred<Future<R>()> defer(const Process<T>* process, R (T::*method)()) defer(const Process<T>& process, \ R (T::*method)(ENUM_PARAMS(N, P)), \ ENUM_BINARY_PARAMS(N, A, &&a)) \ - -> decltype(defer(process.self(), method, ENUM(N, FORWARD, _))) \ + -> decltype(defer(process.self(), method, ENUM(N, FORWARD_A, _))) \ { \ - return defer(process.self(), method, ENUM(N, FORWARD, _)); \ + return defer(process.self(), method, ENUM(N, FORWARD_A, _)); \ } \ \ template <typename R, \ @@ -248,15 +251,16 @@ Deferred<Future<R>()> defer(const Process<T>* process, R (T::*method)()) defer(const Process<T>* process, \ R (T::*method)(ENUM_PARAMS(N, P)), \ ENUM_BINARY_PARAMS(N, A, &&a)) \ - -> decltype(defer(process->self(), method, ENUM(N, FORWARD, _))) \ + -> decltype(defer(process->self(), method, ENUM(N, FORWARD_A, _))) \ { \ - return defer(process->self(), method, ENUM(N, FORWARD, _)); \ + return defer(process->self(), method, ENUM(N, FORWARD_A, _)); \ } REPEAT_FROM_TO(1, 13, TEMPLATE, _) // Args A0 -> A11. #undef TEMPLATE -#undef FORWARD +#undef FORWARD_A +#undef FORWARD_P // Now we define defer calls for functors (with and without a PID): http://git-wip-us.apache.org/repos/asf/mesos/blob/13eda278/3rdparty/libprocess/include/process/deferred.hpp ---------------------------------------------------------------------- diff --git a/3rdparty/libprocess/include/process/deferred.hpp b/3rdparty/libprocess/include/process/deferred.hpp index 950f1cc..dfce0b9 100644 --- a/3rdparty/libprocess/include/process/deferred.hpp +++ b/3rdparty/libprocess/include/process/deferred.hpp @@ -244,7 +244,7 @@ private: void (T::*method)(ENUM_PARAMS(N, P)), \ ENUM_BINARY_PARAMS(N, A, &&a)) \ -> _Deferred<decltype( \ - std::bind( \ + lambda::partial( \ &std::function<void(ENUM_PARAMS(N, P))>::operator(), \ std::function<void(ENUM_PARAMS(N, P))>(), \ ENUM(N, FORWARD, _)))>; @@ -261,7 +261,7 @@ private: Future<R> (T::*method)(ENUM_PARAMS(N, P)), \ ENUM_BINARY_PARAMS(N, A, &&a)) \ -> _Deferred<decltype( \ - std::bind( \ + lambda::partial( \ &std::function<Future<R>(ENUM_PARAMS(N, P))>::operator(), \ std::function<Future<R>(ENUM_PARAMS(N, P))>(), \ ENUM(N, FORWARD, _)))>; @@ -278,7 +278,7 @@ private: R (T::*method)(ENUM_PARAMS(N, P)), \ ENUM_BINARY_PARAMS(N, A, &&a)) \ -> _Deferred<decltype( \ - std::bind( \ + lambda::partial( \ &std::function<Future<R>(ENUM_PARAMS(N, P))>::operator(), \ std::function<Future<R>(ENUM_PARAMS(N, P))>(), \ ENUM(N, FORWARD, _)))>;