p.setException(std::move(t.exception()));
}
} else if (!threw) {
- std::get<I>(results) = std::move(t.value());
+ std::get<I>(results) = std::move(t);
}
}
~CollectVariadicContext() {
if (!threw.exchange(true)) {
- p.setValue(std::move(results));
+ p.setValue(unwrap(std::move(results)));
}
}
Promise<std::tuple<Ts...>> p;
- std::tuple<Ts...> results;
+ std::tuple<folly::Try<Ts>...> results;
std::atomic<bool> threw {false};
typedef Future<std::tuple<Ts...>> type;
+
+ private:
+ template <typename... Ts2>
+ static std::tuple<Ts...> unwrap(std::tuple<folly::Try<Ts>...>&& o,
+ Ts2&&... ts2) {
+ static_assert(sizeof...(ts2) <
+ std::tuple_size<std::tuple<folly::Try<Ts>...>>::value,
+ "Non-templated unwrap should be used instead");
+ assert(std::get<sizeof...(ts2)>(o).hasValue());
+
+ return unwrap(std::move(o),
+ std::forward<Ts2>(ts2)...,
+ std::move(*std::get<sizeof...(ts2)>(o)));
+ }
+
+ static std::tuple<Ts...> unwrap(std::tuple<folly::Try<Ts>...>&& o,
+ Ts&&... ts) {
+ return std::tuple<Ts...>(std::forward<Ts>(ts)...);
+ }
};
template <template <typename ...> class T, typename... Ts>
auto f = collectAll(fs);
EXPECT_TRUE(f.isReady());
}
+
+TEST(Collect, noDefaultConstructor) {
+ struct A {
+ explicit A(size_t x) {}
+ };
+
+ auto f1 = makeFuture(A(1));
+ auto f2 = makeFuture(A(2));
+
+ auto f = collect(std::move(f1), std::move(f2));
+}