Commit dacdff5d authored by Hannes Roth's avatar Hannes Roth Committed by Dave Watson

(Wangle) Actually support the universal reference used in whenAll

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
parent 920a14c7
...@@ -282,13 +282,16 @@ makeFuture(E const& e) { ...@@ -282,13 +282,16 @@ makeFuture(E const& e) {
// when (variadic) // when (variadic)
template <typename... Fs> 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) 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); ctx->total = sizeof...(fs);
auto f_saved = ctx->p.getFuture(); 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); return std::move(f_saved);
} }
......
...@@ -197,8 +197,10 @@ whenAll(InputIterator first, InputIterator last); ...@@ -197,8 +197,10 @@ 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>, ...>>.
/// The Futures are moved in, so your copies are invalid.
template <typename... Fs> 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); 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
......
...@@ -521,6 +521,27 @@ TEST(Future, whenAllVariadic) { ...@@ -521,6 +521,27 @@ TEST(Future, whenAllVariadic) {
EXPECT_TRUE(flag); 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) { TEST(Future, whenAll_none) {
vector<Future<int>> fs; vector<Future<int>> fs;
auto f = whenAll(fs.begin(), fs.end()); auto f = whenAll(fs.begin(), fs.end());
......
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