Commit 60c0047a authored by Hannes Roth's avatar Hannes Roth Committed by Dave Watson

(Wangle) whenAll should take rvalue references instead of references

Summary: Don't need to keep the old futures around.

Test Plan: `FutureTest.cpp`

Reviewed By: hans@fb.com

FB internal diff: D1197360
parent a640baa1
...@@ -283,12 +283,12 @@ makeFuture(E const& e) { ...@@ -283,12 +283,12 @@ makeFuture(E const& e) {
template <typename... Fs> template <typename... Fs>
typename detail::VariadicContext<typename Fs::value_type...>::type typename detail::VariadicContext<typename Fs::value_type...>::type
whenAll(Fs&... fs) whenAll(Fs&&... fs)
{ {
auto ctx = new detail::VariadicContext<typename Fs::value_type...>(); auto ctx = new detail::VariadicContext<typename Fs::value_type...>();
ctx->total = sizeof...(fs); ctx->total = sizeof...(fs);
auto f_saved = ctx->p.getFuture(); auto f_saved = ctx->p.getFuture();
detail::whenAllVariadicHelper(ctx, fs...); detail::whenAllVariadicHelper(ctx, std::forward<Fs>(fs)...);
return std::move(f_saved); return std::move(f_saved);
} }
......
...@@ -197,10 +197,9 @@ whenAll(InputIterator first, InputIterator last); ...@@ -197,10 +197,9 @@ whenAll(InputIterator first, InputIterator last);
/// This version takes a varying number of Futures instead of an iterator. /// This version takes a varying number of Futures instead of an iterator.
/// The return type for (Future<T1>, Future<T2>, ...) input /// The return type for (Future<T1>, Future<T2>, ...) input
/// is a Future<std::tuple<Try<T1>, Try<T2>, ...>>. /// is a Future<std::tuple<Try<T1>, Try<T2>, ...>>.
// XXX why does it take Fs& instead of Fs&&?
template <typename... Fs> template <typename... Fs>
typename detail::VariadicContext<typename Fs::value_type...>::type typename detail::VariadicContext<typename Fs::value_type...>::type
whenAll(Fs&... fs); whenAll(Fs&&... fs);
/** The result is a pair of the index of the first Future to complete and /** The result is a pair of the index of the first Future to complete and
the Try. If multiple Futures complete at the same time (or are already the Try. If multiple Futures complete at the same time (or are already
......
...@@ -104,10 +104,9 @@ struct VariadicContext { ...@@ -104,10 +104,9 @@ struct VariadicContext {
template <typename... Ts, typename THead, typename... Fs> template <typename... Ts, typename THead, typename... Fs>
typename std::enable_if<sizeof...(Fs) == 0, void>::type typename std::enable_if<sizeof...(Fs) == 0, void>::type
whenAllVariadicHelper(VariadicContext<Ts...> *ctx, THead& head, Fs&... tail) { whenAllVariadicHelper(VariadicContext<Ts...> *ctx, THead&& head, Fs&&... tail) {
head.setContinuation([ctx](Try<typename THead::value_type>&& t) { head.setContinuation([ctx](Try<typename THead::value_type>&& t) {
const size_t i = sizeof...(Ts) - sizeof...(Fs) - 1; std::get<sizeof...(Ts) - sizeof...(Fs) - 1>(ctx->results) = std::move(t);
std::get<i>(ctx->results) = std::move(t);
if (++ctx->count == ctx->total) { if (++ctx->count == ctx->total) {
ctx->p.setValue(std::move(ctx->results)); ctx->p.setValue(std::move(ctx->results));
delete ctx; delete ctx;
...@@ -117,16 +116,16 @@ whenAllVariadicHelper(VariadicContext<Ts...> *ctx, THead& head, Fs&... tail) { ...@@ -117,16 +116,16 @@ whenAllVariadicHelper(VariadicContext<Ts...> *ctx, THead& head, Fs&... tail) {
template <typename... Ts, typename THead, typename... Fs> template <typename... Ts, typename THead, typename... Fs>
typename std::enable_if<sizeof...(Fs) != 0, void>::type typename std::enable_if<sizeof...(Fs) != 0, void>::type
whenAllVariadicHelper(VariadicContext<Ts...> *ctx, THead& head, Fs&... tail) { whenAllVariadicHelper(VariadicContext<Ts...> *ctx, THead&& head, Fs&&... tail) {
head.setContinuation([ctx](Try<typename THead::value_type>&& t) { head.setContinuation([ctx](Try<typename THead::value_type>&& t) {
const size_t i = sizeof...(Ts) - sizeof...(Fs) - 1; std::get<sizeof...(Ts) - sizeof...(Fs) - 1>(ctx->results) = std::move(t);
std::get<i>(ctx->results) = std::move(t);
if (++ctx->count == ctx->total) { if (++ctx->count == ctx->total) {
ctx->p.setValue(std::move(ctx->results)); ctx->p.setValue(std::move(ctx->results));
delete ctx; delete ctx;
} }
}); });
whenAllVariadicHelper(ctx, tail...); // recursive template tail call // template tail-recursion
whenAllVariadicHelper(ctx, std::forward<Fs>(tail)...);
} }
template <typename T> template <typename T>
......
...@@ -506,7 +506,7 @@ TEST(Future, whenAllVariadic) { ...@@ -506,7 +506,7 @@ TEST(Future, whenAllVariadic) {
Future<bool> fb = pb.getFuture(); Future<bool> fb = pb.getFuture();
Future<int> fi = pi.getFuture(); Future<int> fi = pi.getFuture();
bool flag = false; bool flag = false;
whenAll(fb, fi) whenAll(std::move(fb), std::move(fi))
.then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) { .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
flag = true; flag = true;
EXPECT_TRUE(t.hasValue()); EXPECT_TRUE(t.hasValue());
......
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