From b0ec99828f0c782a38947513c5e0c242984e269e Mon Sep 17 00:00:00 2001 From: Christopher Dykes Date: Tue, 27 Jun 2017 17:29:12 -0700 Subject: [PATCH] Shift Future::then and Future::thenMulti into the class definition Summary: GCC 7 has issues with `this->` in trailing return type declarations. This takes the approach of eliminating the trailing return types entirely. Closes https://github.com/facebook/folly/pull/621 Reviewed By: yfeldblum Differential Revision: D5324763 fbshipit-source-id: e38ae76c13ff60bc227146c1ec25afbac8b6982f --- folly/futures/Future-inl.h | 52 -------------------------------------- folly/futures/Future.h | 43 ++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 67 deletions(-) diff --git a/folly/futures/Future-inl.h b/folly/futures/Future-inl.h index 2a8b56b8..09483c15 100644 --- a/folly/futures/Future-inl.h +++ b/folly/futures/Future-inl.h @@ -297,18 +297,6 @@ Future::then(R(Caller::*func)(Args...), Caller *instance) { }); } -template -template -auto Future::then(Executor* x, Arg&& arg, Args&&... args) - -> decltype(this->then(std::forward(arg), - std::forward(args)...)) -{ - auto oldX = getExecutor(); - setExecutor(x); - return this->then(std::forward(arg), std::forward(args)...). - via(oldX); -} - template Future Future::then() { return then([] () {}); @@ -1181,46 +1169,6 @@ Future Future::filter(F&& predicate) { }); } -template -template -auto Future::thenMulti(Callback&& fn) - -> decltype(this->then(std::forward(fn))) { - // thenMulti with one callback is just a then - return then(std::forward(fn)); -} - -template -template -auto Future::thenMulti(Callback&& fn, Callbacks&&... fns) - -> decltype(this->then(std::forward(fn)). - thenMulti(std::forward(fns)...)) { - // thenMulti with two callbacks is just then(a).thenMulti(b, ...) - return then(std::forward(fn)). - thenMulti(std::forward(fns)...); -} - -template -template -auto Future::thenMultiWithExecutor(Executor* x, Callback&& fn, - Callbacks&&... fns) - -> decltype(this->then(std::forward(fn)). - thenMulti(std::forward(fns)...)) { - // thenMultiExecutor with two callbacks is - // via(x).then(a).thenMulti(b, ...).via(oldX) - auto oldX = getExecutor(); - setExecutor(x); - return then(std::forward(fn)). - thenMulti(std::forward(fns)...).via(oldX); -} - -template -template -auto Future::thenMultiWithExecutor(Executor* x, Callback&& fn) - -> decltype(this->then(std::forward(fn))) { - // thenMulti with one callback is just a then with an executor - return then(x, std::forward(fn)); -} - template inline Future when(bool p, F&& thunk) { return p ? std::forward(thunk)().unit() : makeFuture(); diff --git a/folly/futures/Future.h b/folly/futures/Future.h index 2acc1b94..aaa4cb78 100644 --- a/folly/futures/Future.h +++ b/folly/futures/Future.h @@ -210,9 +210,12 @@ class Future { /// In the former both b and c execute via x. In the latter, only b executes /// via x, and c executes via the same executor (if any) that f had. template - auto then(Executor* x, Arg&& arg, Args&&... args) - -> decltype(this->then(std::forward(arg), - std::forward(args)...)); + auto then(Executor* x, Arg&& arg, Args&&... args) { + auto oldX = getExecutor(); + setExecutor(x); + return this->then(std::forward(arg), std::forward(args)...) + .via(oldX); + } /// Convenience method for ignoring the value and creating a Future. /// Exceptions still propagate. @@ -402,14 +405,17 @@ class Future { /// /// f.thenMulti(a, b, c); template - auto thenMulti(Callback&& fn, Callbacks&&... fns) - -> decltype(this->then(std::forward(fn)). - thenMulti(std::forward(fns)...)); + auto thenMulti(Callback&& fn, Callbacks&&... fns) { + // thenMulti with two callbacks is just then(a).thenMulti(b, ...) + return then(std::forward(fn)) + .thenMulti(std::forward(fns)...); + } - // Nothing to see here, just thenMulti's base case template - auto thenMulti(Callback&& fn) - -> decltype(this->then(std::forward(fn))); + auto thenMulti(Callback&& fn) { + // thenMulti with one callback is just a then + return then(std::forward(fn)); + } /// Create a Future chain from a sequence of callbacks. i.e. /// @@ -420,14 +426,21 @@ class Future { /// /// f.thenMultiWithExecutor(executor, a, b, c); template - auto thenMultiWithExecutor(Executor* x, Callback&& fn, Callbacks&&... fns) - -> decltype(this->then(std::forward(fn)). - thenMulti(std::forward(fns)...)); + auto thenMultiWithExecutor(Executor* x, Callback&& fn, Callbacks&&... fns) { + // thenMultiExecutor with two callbacks is + // via(x).then(a).thenMulti(b, ...).via(oldX) + auto oldX = getExecutor(); + setExecutor(x); + return then(std::forward(fn)) + .thenMulti(std::forward(fns)...) + .via(oldX); + } - // Nothing to see here, just thenMultiWithExecutor's base case template - auto thenMultiWithExecutor(Executor* x, Callback&& fn) - -> decltype(this->then(std::forward(fn))); + auto thenMultiWithExecutor(Executor* x, Callback&& fn) { + // thenMulti with one callback is just a then with an executor + return then(x, std::forward(fn)); + } /// Discard a result, but propagate an exception. Future unit() { -- 2.34.1