Commit 426eb685 authored by Andrii Grynenko's avatar Andrii Grynenko Committed by Facebook Github Bot

Implement coro::Future -> Future conversion

Reviewed By: wqfish

Differential Revision: D7205067

fbshipit-source-id: 2236c132b2150e38da6d5a5c9970347320e19a60
parent db2cedc7
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <folly/experimental/coro/Promise.h> #include <folly/experimental/coro/Promise.h>
#include <folly/experimental/coro/Task.h> #include <folly/experimental/coro/Task.h>
#include <folly/experimental/coro/Wait.h> #include <folly/experimental/coro/Wait.h>
#include <folly/futures/Future.h>
namespace folly { namespace folly {
namespace coro { namespace coro {
...@@ -77,6 +78,11 @@ class Future { ...@@ -77,6 +78,11 @@ class Future {
return get(); return get();
} }
folly::Future<T> toFuture() && {
auto executor = promise_->executor_;
return SemiFuture<T>::fromAwaitable(std::move(*this)).via(executor);
}
~Future() { ~Future() {
if (!promise_) { if (!promise_) {
return; return;
......
...@@ -41,6 +41,16 @@ TEST(Coro, Basic) { ...@@ -41,6 +41,16 @@ TEST(Coro, Basic) {
EXPECT_EQ(42, future.get()); EXPECT_EQ(42, future.get());
} }
TEST(Coro, BasicFuture) {
ManualExecutor executor;
auto future = via(&executor, task42()).toFuture();
EXPECT_FALSE(future.isReady());
EXPECT_EQ(42, future.getVia(&executor));
}
coro::Task<void> taskVoid() { coro::Task<void> taskVoid() {
(void)co_await task42(); (void)co_await task42();
co_return; co_return;
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#if FOLLY_HAS_COROUTINES
#include <experimental/coroutine>
#endif
#include <folly/Optional.h> #include <folly/Optional.h>
#include <folly/Portability.h> #include <folly/Portability.h>
...@@ -392,6 +395,41 @@ class SemiFuture : private futures::detail::FutureBase<T> { ...@@ -392,6 +395,41 @@ class SemiFuture : private futures::detail::FutureBase<T> {
/// use via and pass a meaningful executor. /// use via and pass a meaningful executor.
inline Future<T> toUnsafeFuture() &&; inline Future<T> toUnsafeFuture() &&;
#if FOLLY_HAS_COROUTINES
class promise_type {
public:
SemiFuture get_return_object() {
return promise_.getSemiFuture();
}
std::experimental::suspend_never initial_suspend() {
return {};
}
std::experimental::suspend_never final_suspend() {
return {};
}
void return_value(T& value) {
promise_.setValue(std::move(value));
}
void unhandled_exception() {
promise_.setException(exception_wrapper(std::current_exception()));
}
private:
folly::Promise<T> promise_;
};
template <typename Awaitable>
static SemiFuture fromAwaitable(Awaitable&& awaitable) {
return [](Awaitable awaitable) -> SemiFuture {
co_return co_await awaitable;
}(std::forward<Awaitable>(awaitable));
}
#endif
private: private:
friend class Promise<T>; friend class Promise<T>;
template <class> template <class>
...@@ -897,7 +935,6 @@ class Future : private futures::detail::FutureBase<T> { ...@@ -897,7 +935,6 @@ class Future : private futures::detail::FutureBase<T> {
} // namespace folly } // namespace folly
#if FOLLY_HAS_COROUTINES #if FOLLY_HAS_COROUTINES
#include <experimental/coroutine>
namespace folly { namespace folly {
namespace detail { namespace detail {
......
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