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
// 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);
}
/// 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
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());