(Wangle) Actually support the universal reference used in whenAll
authorHannes Roth <hannesr@fb.com>
Wed, 5 Mar 2014 17:50:28 +0000 (09:50 -0800)
committerDave Watson <davejwatson@fb.com>
Mon, 10 Mar 2014 20:50:29 +0000 (13:50 -0700)
Summary:
Need to use `std::decay` to actually support the universal reference.

The futures are moved in, and invalidated.

Test Plan: Test; does not compile before.

Reviewed By: hans@fb.com

FB internal diff: D1199841

folly/wangle/Future-inl.h
folly/wangle/Future.h
folly/wangle/test/FutureTest.cpp

index 9a606915f85ffc1fd19bc911f194127549e24029..6b5907dc7693a86cb2fcad34b1f7f257a2fb6521 100644 (file)
@@ -282,13 +282,16 @@ makeFuture(E const& e) {
 // when (variadic)
 
 template <typename... Fs>
-typename detail::VariadicContext<typename Fs::value_type...>::type
+typename detail::VariadicContext<
+  typename std::decay<Fs>::type::value_type...>::type
 whenAll(Fs&&... fs)
 {
-  auto ctx = new detail::VariadicContext<typename Fs::value_type...>();
+  auto ctx =
+    new detail::VariadicContext<typename std::decay<Fs>::type::value_type...>();
   ctx->total = sizeof...(fs);
   auto f_saved = ctx->p.getFuture();
-  detail::whenAllVariadicHelper(ctx, std::forward<Fs>(fs)...);
+  detail::whenAllVariadicHelper(ctx,
+    std::forward<typename std::decay<Fs>::type>(fs)...);
   return std::move(f_saved);
 }
 
index f590e0915dd7f7daa092ac35ba41bad1534aa417..d89f7134092f538c6f957ff1dd8baf5be3d60118 100644 (file)
@@ -197,8 +197,10 @@ whenAll(InputIterator first, InputIterator last);
 /// This version takes a varying number of Futures instead of an iterator.
 /// The return type for (Future<T1>, Future<T2>, ...) input
 /// is a Future<std::tuple<Try<T1>, Try<T2>, ...>>.
+/// The Futures are moved in, so your copies are invalid.
 template <typename... Fs>
-typename detail::VariadicContext<typename Fs::value_type...>::type
+typename detail::VariadicContext<
+  typename std::decay<Fs>::type::value_type...>::type
 whenAll(Fs&&... fs);
 
 /** The result is a pair of the index of the first Future to complete and
index a70af1ab0af4b165e3467200da538fcaa1ac1f53..e356d0deab2139297bd0d1426b7715cd0a797d38 100644 (file)
@@ -521,6 +521,27 @@ TEST(Future, whenAllVariadic) {
   EXPECT_TRUE(flag);
 }
 
+TEST(Future, whenAllVariadicReferences) {
+  Promise<bool> pb;
+  Promise<int> pi;
+  Future<bool> fb = pb.getFuture();
+  Future<int> fi = pi.getFuture();
+  bool flag = false;
+  whenAll(fb, fi)
+    .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
+      flag = true;
+      EXPECT_TRUE(t.hasValue());
+      EXPECT_TRUE(std::get<0>(t.value()).hasValue());
+      EXPECT_EQ(std::get<0>(t.value()).value(), true);
+      EXPECT_TRUE(std::get<1>(t.value()).hasValue());
+      EXPECT_EQ(std::get<1>(t.value()).value(), 42);
+    });
+  pb.setValue(true);
+  EXPECT_FALSE(flag);
+  pi.setValue(42);
+  EXPECT_TRUE(flag);
+}
+
 TEST(Future, whenAll_none) {
   vector<Future<int>> fs;
   auto f = whenAll(fs.begin(), fs.end());