mirror of
https://github.com/facebook/sapling.git
synced 2024-10-04 22:07:44 +03:00
ImmediateFuture: allow implicit conversion from Future
Summary: Future can be implicitly converted to SemiFuture, because it's a safe operation in general. SemiFuture is a weaker interface. The same reason allows us to implicitly convert SemiFuture to ImmediateFuture. Therefore, allow an implicit conversion from Future to ImmediateFuture. Reviewed By: xavierd Differential Revision: D42086161 fbshipit-source-id: ef185101728755c099c87c2b5c15c2fe28e88b83
This commit is contained in:
parent
35db05f424
commit
ea87aa398e
@ -16,6 +16,7 @@ template <typename T>
|
||||
class ImmediateFuture;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct isImmediateFuture : std::false_type {};
|
||||
|
||||
@ -30,7 +31,7 @@ struct continuation_result_impl {
|
||||
template <typename T>
|
||||
struct continuation_result_impl<
|
||||
T,
|
||||
typename std::enable_if_t<folly::isSemiFuture<T>::value>> {
|
||||
typename std::enable_if_t<folly::isFutureOrSemiFuture<T>::value>> {
|
||||
using type = typename T::value_type;
|
||||
};
|
||||
|
||||
|
@ -102,6 +102,14 @@ class ImmediateFuture {
|
||||
/* implicit */ ImmediateFuture(folly::SemiFuture<T>&& fut) noexcept
|
||||
: ImmediateFuture{std::move(fut), SemiFutureReadiness::EagerSemiFuture} {}
|
||||
|
||||
/**
|
||||
* Construct an ImmediateFuture with a Future.
|
||||
*
|
||||
* This constructor has the same semantics as ImmediateFuture{future.semi()}.
|
||||
*/
|
||||
/* implicit */ ImmediateFuture(folly::Future<T>&& fut) noexcept
|
||||
: ImmediateFuture{std::move(fut).semi()} {}
|
||||
|
||||
~ImmediateFuture();
|
||||
|
||||
ImmediateFuture(const ImmediateFuture&) = delete;
|
||||
|
@ -687,4 +687,37 @@ TEST(ImmediateFuture, in_place_construction_multiple_arguments) {
|
||||
EXPECT_EQ("world", *result.second);
|
||||
}
|
||||
|
||||
TEST(ImmediateFuture, conversion_from_ready_Future) {
|
||||
auto fut = folly::makeFuture<int>(10);
|
||||
// use = to ensure we can implicitly convert
|
||||
ImmediateFuture<int> imm = std::move(fut);
|
||||
EXPECT_FALSE(fut.valid());
|
||||
EXPECT_TRUE(imm.valid());
|
||||
EXPECT_NE(imm.isReady(), detail::kImmediateFutureAlwaysDefer);
|
||||
EXPECT_EQ(10, std::move(imm).get());
|
||||
}
|
||||
|
||||
TEST(ImmediateFuture, conversion_from_nonready_Future) {
|
||||
folly::Promise<int> p;
|
||||
auto fut = p.getFuture();
|
||||
// use = to ensure we can implicitly convert
|
||||
ImmediateFuture<int> imm = std::move(fut);
|
||||
EXPECT_FALSE(fut.valid());
|
||||
EXPECT_TRUE(imm.valid());
|
||||
EXPECT_FALSE(imm.isReady());
|
||||
p.setValue(10);
|
||||
EXPECT_NE(imm.isReady(), detail::kImmediateFutureAlwaysDefer);
|
||||
EXPECT_EQ(10, std::move(imm).get());
|
||||
}
|
||||
|
||||
TEST(ImmediateFuture, then_with_Future) {
|
||||
ImmediateFuture<int> imm = 10;
|
||||
auto result = std::move(imm).thenValue([](int i) {
|
||||
// It's funny to std::move() an int, but it's required to match makeFuture's
|
||||
// type signature.
|
||||
return folly::makeFuture<int>(std::move(i));
|
||||
});
|
||||
EXPECT_EQ(10, std::move(result).get());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
Loading…
Reference in New Issue
Block a user