From 2006de6b393b3e22889c3c22e10e09e79733574b Mon Sep 17 00:00:00 2001 From: Dave Watson Date: Wed, 4 Feb 2015 10:52:49 -0800 Subject: [PATCH] Future constructor Summary: As a replacement for makeFuture(). The main advantage is for non-void futures, implicit conversion works pretty well. See unittest for examples Test Plan: fbconfig -r folly/futures; fbmake runtests Reviewed By: hannesr@fb.com Subscribers: yfeldblum, trunkagent, doug, folly-diffs@, jsedgwick FB internal diff: D1806575 Signature: t1:1806575:1422465608:6099f791591b70ce1bcda439b49307b8f3187d89 --- folly/futures/Future-inl.h | 30 ++++++++++++++++++++++++++++++ folly/futures/Future.h | 13 +++++++++++++ folly/futures/test/FutureTest.cpp | 15 +++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/folly/futures/Future-inl.h b/folly/futures/Future-inl.h index e7d6954e..893aa020 100644 --- a/folly/futures/Future-inl.h +++ b/folly/futures/Future-inl.h @@ -42,6 +42,36 @@ Future& Future::operator=(Future&& other) { return *this; } +template +template +Future::Future( + const typename std::enable_if::value, F>::type& val) + : core_(nullptr) { + Promise p; + p.setValue(val); + *this = p.getFuture(); +} + +template +template +Future::Future( + typename std::enable_if::value, F>::type&& val) + : core_(nullptr) { + Promise p; + p.setValue(std::forward(val)); + *this = p.getFuture(); +} + +template <> +template ::value, int>::type> +Future::Future() : core_(nullptr) { + Promise p; + p.setValue(); + *this = p.getFuture(); +} + + template Future::~Future() { detach(); diff --git a/folly/futures/Future.h b/folly/futures/Future.h index fe570fad..1ad11e5f 100644 --- a/folly/futures/Future.h +++ b/folly/futures/Future.h @@ -181,6 +181,19 @@ class Future { Future(Future&&) noexcept; Future& operator=(Future&&); + // makeFuture + template + /* implicit */ + Future(const typename std::enable_if::value, F>::type& val); + + template + /* implicit */ + Future(typename std::enable_if::value, F>::type&& val); + + template ::value, int>::type = 0> + Future(); + ~Future(); /** Return the reference to result. Should not be called if !isReady(). diff --git a/folly/futures/test/FutureTest.cpp b/folly/futures/test/FutureTest.cpp index 8eec4e31..6527bd37 100644 --- a/folly/futures/test/FutureTest.cpp +++ b/folly/futures/test/FutureTest.cpp @@ -1311,3 +1311,18 @@ TEST(Future, CircularDependencySharedPtrSelfReset) { promise.fulfil([]{return 1l;}); } + +TEST(Future, Constructor) { + auto f1 = []() -> Future { return Future(3); }(); + EXPECT_EQ(f1.value(), 3); + auto f2 = []() -> Future { return Future(); }(); + EXPECT_NO_THROW(f2.value()); +} + +TEST(Future, ImplicitConstructor) { + auto f1 = []() -> Future { return 3; }(); + EXPECT_EQ(f1.value(), 3); + // Unfortunately, the C++ standard does not allow the + // following implicit conversion to work: + //auto f2 = []() -> Future { }(); +} -- 2.34.1