Commit 271f9740 authored by Lee Howes's avatar Lee Howes Committed by Facebook Github Bot

Remove use of then inside Future

Summary: To allow deprecation, remove use cases of Future::then inside Future.h/Future-inl.h.

Reviewed By: yfeldblum

Differential Revision: D9984465

fbshipit-source-id: 48e8a5b2985c86fd5384e43e6df282da298b1d99
parent f68a5213
...@@ -468,7 +468,7 @@ FutureBase<T>::withinImplementation(Duration dur, E e, Timekeeper* tk) && { ...@@ -468,7 +468,7 @@ FutureBase<T>::withinImplementation(Duration dur, E e, Timekeeper* tk) && {
// Have time keeper use a weak ptr to hold ctx, // Have time keeper use a weak ptr to hold ctx,
// so that ctx can be deallocated as soon as the future job finished. // so that ctx can be deallocated as soon as the future job finished.
tk->after(dur).then([weakCtx = to_weak_ptr(ctx)](Try<Unit>&& t) mutable { tk->after(dur).thenTry([weakCtx = to_weak_ptr(ctx)](Try<Unit>&& t) mutable {
auto lockedCtx = weakCtx.lock(); auto lockedCtx = weakCtx.lock();
if (!lockedCtx) { if (!lockedCtx) {
// ctx already released. "this" completed first, cancel "after" // ctx already released. "this" completed first, cancel "after"
...@@ -890,7 +890,7 @@ SemiFuture<T>::defer(F&& func) && { ...@@ -890,7 +890,7 @@ SemiFuture<T>::defer(F&& func) && {
this->setExecutor(deferredExecutor); this->setExecutor(deferredExecutor);
} }
auto sf = Future<T>(this->core_).then(std::forward<F>(func)).semi(); auto sf = Future<T>(this->core_).thenTry(std::forward<F>(func)).semi();
this->core_ = nullptr; this->core_ = nullptr;
// Carry deferred executor through chain as constructor from Future will // Carry deferred executor through chain as constructor from Future will
// nullify it // nullify it
...@@ -956,7 +956,7 @@ template <typename T> ...@@ -956,7 +956,7 @@ template <typename T>
SemiFuture<T> SemiFuture<T>::delayed(Duration dur, Timekeeper* tk) && { SemiFuture<T> SemiFuture<T>::delayed(Duration dur, Timekeeper* tk) && {
return collectAllSemiFuture(*this, futures::sleep(dur, tk)) return collectAllSemiFuture(*this, futures::sleep(dur, tk))
.toUnsafeFuture() .toUnsafeFuture()
.then([](std::tuple<Try<T>, Try<Unit>> tup) { .thenValue([](std::tuple<Try<T>, Try<Unit>> tup) {
Try<T>& t = std::get<0>(tup); Try<T>& t = std::get<0>(tup);
return makeFuture<T>(std::move(*t)); return makeFuture<T>(std::move(*t));
}); });
...@@ -986,7 +986,8 @@ template < ...@@ -986,7 +986,8 @@ template <
std::is_convertible<T2&&, T>::value, std::is_convertible<T2&&, T>::value,
int>::type> int>::type>
Future<T>::Future(Future<T2>&& other) Future<T>::Future(Future<T2>&& other)
: Future(std::move(other).then([](T2&& v) { return T(std::move(v)); })) {} : Future(
std::move(other).thenValue([](T2&& v) { return T(std::move(v)); })) {}
template <class T> template <class T>
template < template <
...@@ -997,7 +998,8 @@ template < ...@@ -997,7 +998,8 @@ template <
!std::is_convertible<T2&&, T>::value, !std::is_convertible<T2&&, T>::value,
int>::type> int>::type>
Future<T>::Future(Future<T2>&& other) Future<T>::Future(Future<T2>&& other)
: Future(std::move(other).then([](T2&& v) { return T(std::move(v)); })) {} : Future(
std::move(other).thenValue([](T2&& v) { return T(std::move(v)); })) {}
template <class T> template <class T>
template < template <
...@@ -1008,7 +1010,7 @@ template < ...@@ -1008,7 +1010,7 @@ template <
int>::type> int>::type>
Future<T>& Future<T>::operator=(Future<T2>&& other) { Future<T>& Future<T>::operator=(Future<T2>&& other) {
return operator=( return operator=(
std::move(other).then([](T2&& v) { return T(std::move(v)); })); std::move(other).thenValue([](T2&& v) { return T(std::move(v)); }));
} }
// unwrap // unwrap
...@@ -1018,7 +1020,7 @@ template <class F> ...@@ -1018,7 +1020,7 @@ template <class F>
typename std:: typename std::
enable_if<isFuture<F>::value, Future<typename isFuture<T>::Inner>>::type enable_if<isFuture<F>::value, Future<typename isFuture<T>::Inner>>::type
Future<T>::unwrap() && { Future<T>::unwrap() && {
return std::move(*this).then( return std::move(*this).thenValue(
[](Future<typename isFuture<T>::Inner> internal_future) { [](Future<typename isFuture<T>::Inner> internal_future) {
return internal_future; return internal_future;
}); });
...@@ -1134,7 +1136,7 @@ Future<T> Future<T>::thenError(F&& func) && { ...@@ -1134,7 +1136,7 @@ Future<T> Future<T>::thenError(F&& func) && {
template <class T> template <class T>
Future<Unit> Future<T>::then() && { Future<Unit> Future<T>::then() && {
return std::move(*this).then([]() {}); return std::move(*this).thenValue([](T&&) {});
} }
// onError where the callback returns T // onError where the callback returns T
...@@ -1306,13 +1308,18 @@ template <class Func> ...@@ -1306,13 +1308,18 @@ template <class Func>
auto via(Executor* x, Func&& func) -> Future< auto via(Executor* x, Func&& func) -> Future<
typename isFutureOrSemiFuture<decltype(std::declval<Func>()())>::Inner> { typename isFutureOrSemiFuture<decltype(std::declval<Func>()())>::Inner> {
// TODO make this actually more performant. :-P #7260175 // TODO make this actually more performant. :-P #7260175
return via(x).then(std::forward<Func>(func)); return via(x).thenValue([f = std::forward<Func>(func)](auto&&) mutable {
return std::forward<Func>(f)();
});
} }
template <class Func> template <class Func>
auto via(Executor::KeepAlive<> x, Func&& func) -> Future< auto via(Executor::KeepAlive<> x, Func&& func) -> Future<
typename isFutureOrSemiFuture<decltype(std::declval<Func>()())>::Inner> { typename isFutureOrSemiFuture<decltype(std::declval<Func>()())>::Inner> {
return via(std::move(x)).then(std::forward<Func>(func)); return via(std::move(x))
.thenValue([f = std::forward<Func>(func)](auto&&) mutable {
return std::forward<Func>(f)();
});
} }
// makeFuture // makeFuture
...@@ -1758,14 +1765,14 @@ Future<T> reduce(It first, It last, T&& initial, F&& func) { ...@@ -1758,14 +1765,14 @@ Future<T> reduce(It first, It last, T&& initial, F&& func) {
auto sfunc = std::make_shared<std::decay_t<F>>(std::forward<F>(func)); auto sfunc = std::make_shared<std::decay_t<F>>(std::forward<F>(func));
auto f = std::move(*first).then( auto f = std::move(*first).thenTry(
[initial = std::forward<T>(initial), sfunc](Try<ItT>&& head) mutable { [initial = std::forward<T>(initial), sfunc](Try<ItT>&& head) mutable {
return (*sfunc)( return (*sfunc)(
std::move(initial), head.template get<IsTry::value, Arg&&>()); std::move(initial), head.template get<IsTry::value, Arg&&>());
}); });
for (++first; first != last; ++first) { for (++first; first != last; ++first) {
f = collectAllSemiFuture(f, *first).toUnsafeFuture().then( f = collectAllSemiFuture(f, *first).toUnsafeFuture().thenValue(
[sfunc](std::tuple<Try<T>, Try<ItT>>&& t) { [sfunc](std::tuple<Try<T>, Try<ItT>>&& t) {
return (*sfunc)( return (*sfunc)(
std::move(std::get<0>(t).value()), std::move(std::get<0>(t).value()),
...@@ -1849,7 +1856,7 @@ window(Executor* executor, Collection input, F func, size_t n) { ...@@ -1849,7 +1856,7 @@ window(Executor* executor, Collection input, F func, size_t n) {
template <class T> template <class T>
template <class I, class F> template <class I, class F>
Future<I> Future<T>::reduce(I&& initial, F&& func) && { Future<I> Future<T>::reduce(I&& initial, F&& func) && {
return std::move(*this).then( return std::move(*this).thenValue(
[minitial = std::forward<I>(initial), [minitial = std::forward<I>(initial),
mfunc = std::forward<F>(func)](T&& vals) mutable { mfunc = std::forward<F>(func)](T&& vals) mutable {
auto ret = std::move(minitial); auto ret = std::move(minitial);
...@@ -1973,7 +1980,7 @@ Future<T> Future<T>::delayed(Duration dur, Timekeeper* tk) && { ...@@ -1973,7 +1980,7 @@ Future<T> Future<T>::delayed(Duration dur, Timekeeper* tk) && {
auto e = this->getExecutor(); auto e = this->getExecutor();
return collectAllSemiFuture(*this, futures::sleep(dur, tk)) return collectAllSemiFuture(*this, futures::sleep(dur, tk))
.via(e ? e : &InlineExecutor::instance()) .via(e ? e : &InlineExecutor::instance())
.then([](std::tuple<Try<T>, Try<Unit>>&& tup) { .thenValue([](std::tuple<Try<T>, Try<Unit>>&& tup) {
return makeFuture<T>(std::get<0>(std::move(tup))); return makeFuture<T>(std::get<0>(std::move(tup)));
}); });
} }
...@@ -2051,7 +2058,7 @@ void waitViaImpl(Future<T>& f, DrivableExecutor* e) { ...@@ -2051,7 +2058,7 @@ void waitViaImpl(Future<T>& f, DrivableExecutor* e) {
if (f.isReady()) { if (f.isReady()) {
return; return;
} }
f = std::move(f).via(e).then([](T&& t) { return std::move(t); }); f = std::move(f).via(e).thenValue([](T&& t) { return std::move(t); });
while (!f.isReady()) { while (!f.isReady()) {
e->drive(); e->drive();
} }
...@@ -2071,7 +2078,7 @@ void waitViaImpl( ...@@ -2071,7 +2078,7 @@ void waitViaImpl(
return; return;
} }
// Chain operations, ensuring that the executor is kept alive for the duration // Chain operations, ensuring that the executor is kept alive for the duration
f = std::move(f).via(e).then( f = std::move(f).via(e).thenValue(
[keepAlive = getKeepAliveToken(e)](T&& t) { return std::move(t); }); [keepAlive = getKeepAliveToken(e)](T&& t) { return std::move(t); });
auto now = std::chrono::steady_clock::now(); auto now = std::chrono::steady_clock::now();
auto deadline = now + timeout; auto deadline = now + timeout;
...@@ -2269,7 +2276,7 @@ struct TryEquals { ...@@ -2269,7 +2276,7 @@ struct TryEquals {
template <class T> template <class T>
Future<bool> Future<T>::willEqual(Future<T>& f) { Future<bool> Future<T>::willEqual(Future<T>& f) {
return collectAllSemiFuture(*this, f).toUnsafeFuture().then( return collectAllSemiFuture(*this, f).toUnsafeFuture().thenValue(
[](const std::tuple<Try<T>, Try<T>>& t) { [](const std::tuple<Try<T>, Try<T>>& t) {
if (std::get<0>(t).hasValue() && std::get<1>(t).hasValue()) { if (std::get<0>(t).hasValue() && std::get<1>(t).hasValue()) {
return futures::detail::TryEquals<T>::equals( return futures::detail::TryEquals<T>::equals(
...@@ -2283,7 +2290,7 @@ Future<bool> Future<T>::willEqual(Future<T>& f) { ...@@ -2283,7 +2290,7 @@ Future<bool> Future<T>::willEqual(Future<T>& f) {
template <class T> template <class T>
template <class F> template <class F>
Future<T> Future<T>::filter(F&& predicate) && { Future<T> Future<T>::filter(F&& predicate) && {
return std::move(*this).then([p = std::forward<F>(predicate)](T val) { return std::move(*this).thenValue([p = std::forward<F>(predicate)](T val) {
T const& valConstRef = val; T const& valConstRef = val;
if (!p(valConstRef)) { if (!p(valConstRef)) {
throw_exception<FuturePredicateDoesNotObtain>(); throw_exception<FuturePredicateDoesNotObtain>();
...@@ -2301,10 +2308,11 @@ template <class P, class F> ...@@ -2301,10 +2308,11 @@ template <class P, class F>
Future<Unit> whileDo(P&& predicate, F&& thunk) { Future<Unit> whileDo(P&& predicate, F&& thunk) {
if (predicate()) { if (predicate()) {
auto future = thunk(); auto future = thunk();
return std::move(future).then([predicate = std::forward<P>(predicate), return std::move(future).thenValue(
thunk = std::forward<F>(thunk)]() mutable { [predicate = std::forward<P>(predicate),
return whileDo(std::forward<P>(predicate), std::forward<F>(thunk)); thunk = std::forward<F>(thunk)](auto&&) mutable {
}); return whileDo(std::forward<P>(predicate), std::forward<F>(thunk));
});
} }
return makeFuture(); return makeFuture();
} }
...@@ -2324,7 +2332,7 @@ std::vector<Future<Result>> map(It first, It last, F func) { ...@@ -2324,7 +2332,7 @@ std::vector<Future<Result>> map(It first, It last, F func) {
std::vector<Future<Result>> results; std::vector<Future<Result>> results;
results.reserve(std::distance(first, last)); results.reserve(std::distance(first, last));
for (auto it = first; it != last; it++) { for (auto it = first; it != last; it++) {
results.push_back(std::move(*it).then(func)); results.push_back(std::move(*it).thenValue(func));
} }
return results; return results;
} }
...@@ -2334,7 +2342,7 @@ std::vector<Future<Result>> map(Executor& exec, It first, It last, F func) { ...@@ -2334,7 +2342,7 @@ std::vector<Future<Result>> map(Executor& exec, It first, It last, F func) {
std::vector<Future<Result>> results; std::vector<Future<Result>> results;
results.reserve(std::distance(first, last)); results.reserve(std::distance(first, last));
for (auto it = first; it != last; it++) { for (auto it = first; it != last; it++) {
results.push_back(std::move(*it).via(&exec).then(func)); results.push_back(std::move(*it).via(&exec).thenValue(func));
} }
return results; return results;
} }
......
...@@ -1177,7 +1177,8 @@ class Future : private futures::detail::FutureBase<T> { ...@@ -1177,7 +1177,8 @@ class Future : private futures::detail::FutureBase<T> {
// clang-format off // clang-format off
template <typename F, typename R = futures::detail::callableResult<T, F>> template <typename F, typename R = futures::detail::callableResult<T, F>>
[[deprecated("must be rvalue-qualified, e.g., std::move(future).then(...)")]] [[deprecated(
"must be rvalue-qualified, e.g., std::move(future).thenValue(...)")]]
typename R::Return then(F&& func) & = delete; typename R::Return then(F&& func) & = delete;
// clang-format on // clang-format on
......
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