Commit b0ec9982 authored by Christopher Dykes's avatar Christopher Dykes Committed by Facebook Github Bot

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
parent 258585ef
......@@ -297,18 +297,6 @@ Future<T>::then(R(Caller::*func)(Args...), Caller *instance) {
});
}
template <class T>
template <class Executor, class Arg, class... Args>
auto Future<T>::then(Executor* x, Arg&& arg, Args&&... args)
-> decltype(this->then(std::forward<Arg>(arg),
std::forward<Args>(args)...))
{
auto oldX = getExecutor();
setExecutor(x);
return this->then(std::forward<Arg>(arg), std::forward<Args>(args)...).
via(oldX);
}
template <class T>
Future<Unit> Future<T>::then() {
return then([] () {});
......@@ -1181,46 +1169,6 @@ Future<T> Future<T>::filter(F&& predicate) {
});
}
template <class T>
template <class Callback>
auto Future<T>::thenMulti(Callback&& fn)
-> decltype(this->then(std::forward<Callback>(fn))) {
// thenMulti with one callback is just a then
return then(std::forward<Callback>(fn));
}
template <class T>
template <class Callback, class... Callbacks>
auto Future<T>::thenMulti(Callback&& fn, Callbacks&&... fns)
-> decltype(this->then(std::forward<Callback>(fn)).
thenMulti(std::forward<Callbacks>(fns)...)) {
// thenMulti with two callbacks is just then(a).thenMulti(b, ...)
return then(std::forward<Callback>(fn)).
thenMulti(std::forward<Callbacks>(fns)...);
}
template <class T>
template <class Callback, class... Callbacks>
auto Future<T>::thenMultiWithExecutor(Executor* x, Callback&& fn,
Callbacks&&... fns)
-> decltype(this->then(std::forward<Callback>(fn)).
thenMulti(std::forward<Callbacks>(fns)...)) {
// thenMultiExecutor with two callbacks is
// via(x).then(a).thenMulti(b, ...).via(oldX)
auto oldX = getExecutor();
setExecutor(x);
return then(std::forward<Callback>(fn)).
thenMulti(std::forward<Callbacks>(fns)...).via(oldX);
}
template <class T>
template <class Callback>
auto Future<T>::thenMultiWithExecutor(Executor* x, Callback&& fn)
-> decltype(this->then(std::forward<Callback>(fn))) {
// thenMulti with one callback is just a then with an executor
return then(x, std::forward<Callback>(fn));
}
template <class F>
inline Future<Unit> when(bool p, F&& thunk) {
return p ? std::forward<F>(thunk)().unit() : makeFuture();
......
......@@ -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 <class Executor, class Arg, class... Args>
auto then(Executor* x, Arg&& arg, Args&&... args)
-> decltype(this->then(std::forward<Arg>(arg),
std::forward<Args>(args)...));
auto then(Executor* x, Arg&& arg, Args&&... args) {
auto oldX = getExecutor();
setExecutor(x);
return this->then(std::forward<Arg>(arg), std::forward<Args>(args)...)
.via(oldX);
}
/// Convenience method for ignoring the value and creating a Future<Unit>.
/// Exceptions still propagate.
......@@ -402,14 +405,17 @@ class Future {
///
/// f.thenMulti(a, b, c);
template <class Callback, class... Callbacks>
auto thenMulti(Callback&& fn, Callbacks&&... fns)
-> decltype(this->then(std::forward<Callback>(fn)).
thenMulti(std::forward<Callbacks>(fns)...));
auto thenMulti(Callback&& fn, Callbacks&&... fns) {
// thenMulti with two callbacks is just then(a).thenMulti(b, ...)
return then(std::forward<Callback>(fn))
.thenMulti(std::forward<Callbacks>(fns)...);
}
// Nothing to see here, just thenMulti's base case
template <class Callback>
auto thenMulti(Callback&& fn)
-> decltype(this->then(std::forward<Callback>(fn)));
auto thenMulti(Callback&& fn) {
// thenMulti with one callback is just a then
return then(std::forward<Callback>(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 <class Callback, class... Callbacks>
auto thenMultiWithExecutor(Executor* x, Callback&& fn, Callbacks&&... fns)
-> decltype(this->then(std::forward<Callback>(fn)).
thenMulti(std::forward<Callbacks>(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<Callback>(fn))
.thenMulti(std::forward<Callbacks>(fns)...)
.via(oldX);
}
// Nothing to see here, just thenMultiWithExecutor's base case
template <class Callback>
auto thenMultiWithExecutor(Executor* x, Callback&& fn)
-> decltype(this->then(std::forward<Callback>(fn)));
auto thenMultiWithExecutor(Executor* x, Callback&& fn) {
// thenMulti with one callback is just a then with an executor
return then(x, std::forward<Callback>(fn));
}
/// Discard a result, but propagate an exception.
Future<Unit> unit() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment