Future constructor
authorDave Watson <davejwatson@fb.com>
Wed, 4 Feb 2015 18:52:49 +0000 (10:52 -0800)
committerAndrew Cox <andrewcox@fb.com>
Wed, 4 Feb 2015 21:03:47 +0000 (13:03 -0800)
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
folly/futures/Future.h
folly/futures/test/FutureTest.cpp

index e7d6954e5ff17223e90fcdaa50a8c5eb93f61fca..893aa020f7ede3e89cef2c573d019da814809ccb 100644 (file)
@@ -42,6 +42,36 @@ Future<T>& Future<T>::operator=(Future<T>&& other) {
   return *this;
 }
 
+template <class T>
+template <class F>
+Future<T>::Future(
+  const typename std::enable_if<!std::is_void<F>::value, F>::type& val)
+    : core_(nullptr) {
+  Promise<F> p;
+  p.setValue(val);
+  *this = p.getFuture();
+}
+
+template <class T>
+template <class F>
+Future<T>::Future(
+  typename std::enable_if<!std::is_void<F>::value, F>::type&& val)
+    : core_(nullptr) {
+  Promise<F> p;
+  p.setValue(std::forward<F>(val));
+  *this = p.getFuture();
+}
+
+template <>
+template <class F,
+          typename std::enable_if<std::is_void<F>::value, int>::type>
+Future<void>::Future() : core_(nullptr) {
+  Promise<void> p;
+  p.setValue();
+  *this = p.getFuture();
+}
+
+
 template <class T>
 Future<T>::~Future() {
   detach();
index fe570fad3fabf30117aa820ed7f11522d7a3e5d9..1ad11e5f2442be222c3560a898c4419c9a46f35b 100644 (file)
@@ -181,6 +181,19 @@ class Future {
   Future(Future&&) noexcept;
   Future& operator=(Future&&);
 
+  // makeFuture
+  template <class F = T>
+  /* implicit */
+  Future(const typename std::enable_if<!std::is_void<F>::value, F>::type& val);
+
+  template <class F = T>
+  /* implicit */
+  Future(typename std::enable_if<!std::is_void<F>::value, F>::type&& val);
+
+  template <class F = T,
+            typename std::enable_if<std::is_void<F>::value, int>::type = 0>
+  Future();
+
   ~Future();
 
   /** Return the reference to result. Should not be called if !isReady().
index 8eec4e31cd9f99afa6eadae504658bd29539921a..6527bd375a89ad3deed57280231ffffd42e0126f 100644 (file)
@@ -1311,3 +1311,18 @@ TEST(Future, CircularDependencySharedPtrSelfReset) {
 
   promise.fulfil([]{return 1l;});
 }
+
+TEST(Future, Constructor) {
+  auto f1 = []() -> Future<int> { return Future<int>(3); }();
+  EXPECT_EQ(f1.value(), 3);
+  auto f2 = []() -> Future<void> { return Future<void>(); }();
+  EXPECT_NO_THROW(f2.value());
+}
+
+TEST(Future, ImplicitConstructor) {
+  auto f1 = []() -> Future<int> { return 3; }();
+  EXPECT_EQ(f1.value(), 3);
+  // Unfortunately, the C++ standard does not allow the
+  // following implicit conversion to work:
+  //auto f2 = []() -> Future<void> { }();
+}