From 60c0047af915dee869b5c44b0cd8a1a964dc3e09 Mon Sep 17 00:00:00 2001 From: Hannes Roth Date: Mon, 3 Mar 2014 14:45:10 -0800 Subject: [PATCH] (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 --- folly/wangle/Future-inl.h | 4 ++-- folly/wangle/Future.h | 3 +-- folly/wangle/detail.h | 13 ++++++------- folly/wangle/test/FutureTest.cpp | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/folly/wangle/Future-inl.h b/folly/wangle/Future-inl.h index 46a63d52..9a606915 100644 --- a/folly/wangle/Future-inl.h +++ b/folly/wangle/Future-inl.h @@ -283,12 +283,12 @@ makeFuture(E const& e) { template typename detail::VariadicContext::type -whenAll(Fs&... fs) +whenAll(Fs&&... fs) { auto ctx = new detail::VariadicContext(); ctx->total = sizeof...(fs); auto f_saved = ctx->p.getFuture(); - detail::whenAllVariadicHelper(ctx, fs...); + detail::whenAllVariadicHelper(ctx, std::forward(fs)...); return std::move(f_saved); } diff --git a/folly/wangle/Future.h b/folly/wangle/Future.h index 3b3bcf06..f590e091 100644 --- a/folly/wangle/Future.h +++ b/folly/wangle/Future.h @@ -197,10 +197,9 @@ whenAll(InputIterator first, InputIterator last); /// This version takes a varying number of Futures instead of an iterator. /// The return type for (Future, Future, ...) input /// is a Future, Try, ...>>. -// XXX why does it take Fs& instead of Fs&&? template typename detail::VariadicContext::type -whenAll(Fs&... fs); +whenAll(Fs&&... fs); /** 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 diff --git a/folly/wangle/detail.h b/folly/wangle/detail.h index f939cb0d..b1d6ade4 100644 --- a/folly/wangle/detail.h +++ b/folly/wangle/detail.h @@ -104,10 +104,9 @@ struct VariadicContext { template typename std::enable_if::type -whenAllVariadicHelper(VariadicContext *ctx, THead& head, Fs&... tail) { +whenAllVariadicHelper(VariadicContext *ctx, THead&& head, Fs&&... tail) { head.setContinuation([ctx](Try&& t) { - const size_t i = sizeof...(Ts) - sizeof...(Fs) - 1; - std::get(ctx->results) = std::move(t); + std::get(ctx->results) = std::move(t); if (++ctx->count == ctx->total) { ctx->p.setValue(std::move(ctx->results)); delete ctx; @@ -117,16 +116,16 @@ whenAllVariadicHelper(VariadicContext *ctx, THead& head, Fs&... tail) { template typename std::enable_if::type -whenAllVariadicHelper(VariadicContext *ctx, THead& head, Fs&... tail) { +whenAllVariadicHelper(VariadicContext *ctx, THead&& head, Fs&&... tail) { head.setContinuation([ctx](Try&& t) { - const size_t i = sizeof...(Ts) - sizeof...(Fs) - 1; - std::get(ctx->results) = std::move(t); + std::get(ctx->results) = std::move(t); if (++ctx->count == ctx->total) { ctx->p.setValue(std::move(ctx->results)); delete ctx; } }); - whenAllVariadicHelper(ctx, tail...); // recursive template tail call + // template tail-recursion + whenAllVariadicHelper(ctx, std::forward(tail)...); } template diff --git a/folly/wangle/test/FutureTest.cpp b/folly/wangle/test/FutureTest.cpp index 2468c580..a70af1ab 100644 --- a/folly/wangle/test/FutureTest.cpp +++ b/folly/wangle/test/FutureTest.cpp @@ -506,7 +506,7 @@ TEST(Future, whenAllVariadic) { Future fb = pb.getFuture(); Future fi = pi.getFuture(); bool flag = false; - whenAll(fb, fi) + whenAll(std::move(fb), std::move(fi)) .then([&](Try, Try>>&& t) { flag = true; EXPECT_TRUE(t.hasValue()); -- 2.34.1