typedef T Inner;
};
+template <typename T>
+struct isFutureOrSemiFuture : std::false_type {
+ using Inner = typename Unit::Lift<T>::type;
+ using Return = Inner;
+};
+
+template <typename T>
+struct isFutureOrSemiFuture<Future<T>> : std::true_type {
+ typedef T Inner;
+ using Return = Future<Inner>;
+};
+
+template <typename T>
+struct isFutureOrSemiFuture<SemiFuture<T>> : std::true_type {
+ typedef T Inner;
+ using Return = SemiFuture<Inner>;
+};
+
template <typename T>
struct isTry : std::false_type {};
callableWith<F, Try<T>&&>::value,
detail::argResult<true, F, Try<T>&&>,
detail::argResult<true, F, Try<T>&>>::type>::type>::type>::type Arg;
- typedef isFuture<typename Arg::Result> ReturnsFuture;
+ typedef isFutureOrSemiFuture<typename Arg::Result> ReturnsFuture;
typedef Future<typename ReturnsFuture::Inner> Return;
};
template <typename Class, typename R, typename... Args>
struct Extract<R(Class::*)(Args...) const> {
- typedef isFuture<R> ReturnsFuture;
+ typedef isFutureOrSemiFuture<R> ReturnsFuture;
typedef Future<typename ReturnsFuture::Inner> Return;
typedef typename ReturnsFuture::Inner RawReturn;
typedef typename ArgType<Args...>::FirstArg FirstArg;
template <typename Class, typename R, typename... Args>
struct Extract<R(Class::*)(Args...)> {
- typedef isFuture<R> ReturnsFuture;
+ typedef isFutureOrSemiFuture<R> ReturnsFuture;
typedef Future<typename ReturnsFuture::Inner> Return;
typedef typename ReturnsFuture::Inner RawReturn;
typedef typename ArgType<Args...>::FirstArg FirstArg;
template <typename R, typename... Args>
struct Extract<R (*)(Args...)> {
- typedef isFuture<R> ReturnsFuture;
+ typedef isFutureOrSemiFuture<R> ReturnsFuture;
typedef Future<typename ReturnsFuture::Inner> Return;
typedef typename ReturnsFuture::Inner RawReturn;
typedef typename ArgType<Args...>::FirstArg FirstArg;
template <typename R, typename... Args>
struct Extract<R (&)(Args...)> {
- typedef isFuture<R> ReturnsFuture;
+ typedef isFutureOrSemiFuture<R> ReturnsFuture;
typedef Future<typename ReturnsFuture::Inner> Return;
typedef typename ReturnsFuture::Inner RawReturn;
typedef typename ArgType<Args...>::FirstArg FirstArg;
ASSERT_EQ(result, 42);
}
+TEST(SemiFuture, MakeFutureFromSemiFutureReturnFuture) {
+ folly::EventBase e;
+ Promise<int> p;
+ int result{0};
+ auto f = p.getSemiFuture();
+ auto future = std::move(f).via(&e).then([&](int value) {
+ result = value;
+ return folly::makeFuture(std::move(value));
+ });
+ e.loop();
+ EXPECT_EQ(result, 0);
+ EXPECT_FALSE(future.isReady());
+ p.setValue(42);
+ e.loop();
+ EXPECT_TRUE(future.isReady());
+ ASSERT_EQ(future.value(), 42);
+ ASSERT_EQ(result, 42);
+}
+
+TEST(SemiFuture, MakeFutureFromSemiFutureReturnSemiFuture) {
+ folly::EventBase e;
+ Promise<int> p;
+ int result{0};
+ auto f = p.getSemiFuture();
+ auto future = std::move(f).via(&e).then([&](int value) {
+ result = value;
+ return folly::makeSemiFuture(std::move(value));
+ });
+ e.loop();
+ EXPECT_EQ(result, 0);
+ EXPECT_FALSE(future.isReady());
+ p.setValue(42);
+ e.loop();
+ EXPECT_TRUE(future.isReady());
+ ASSERT_EQ(future.value(), 42);
+ ASSERT_EQ(result, 42);
+}
+
TEST(SemiFuture, MakeFutureFromSemiFutureLValue) {
folly::EventBase e;
Promise<int> p;