cmake: add checks to generate folly-config.h correctly
[folly.git] / folly / futures / Promise-inl.h
index 4d3d0dbe0d91ce913b47ba81423b130079812902..45e6929a9152a7bc0bf4750cf7583e8da4a684e3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <atomic>
 #include <thread>
 
+#include <folly/executors/InlineExecutor.h>
 #include <folly/futures/FutureException.h>
 #include <folly/futures/detail/Core.h>
 
 namespace folly {
 
 template <class T>
-Promise<T>::Promise() : retrieved_(false), core_(new detail::Core<T>())
-{}
+Promise<T> Promise<T>::makeEmpty() noexcept {
+  return Promise<T>(futures::detail::EmptyConstruct{});
+}
+
+template <class T>
+Promise<T>::Promise()
+    : retrieved_(false), core_(new futures::detail::Core<T>()) {}
 
 template <class T>
 Promise<T>::Promise(Promise<T>&& other) noexcept
@@ -44,21 +50,25 @@ Promise<T>& Promise<T>::operator=(Promise<T>&& other) noexcept {
 
 template <class T>
 void Promise<T>::throwIfFulfilled() {
-  if (UNLIKELY(!core_)) {
-    throw NoState();
+  if (!core_) {
+    throwNoState();
   }
-  if (UNLIKELY(core_->ready())) {
-    throw PromiseAlreadySatisfied();
+  if (core_->ready()) {
+    throwPromiseAlreadySatisfied();
   }
 }
 
 template <class T>
 void Promise<T>::throwIfRetrieved() {
-  if (UNLIKELY(retrieved_)) {
-    throw FutureAlreadyRetrieved();
+  if (retrieved_) {
+    throwFutureAlreadyRetrieved();
   }
 }
 
+template <class T>
+Promise<T>::Promise(futures::detail::EmptyConstruct) noexcept
+    : retrieved_(false), core_(nullptr) {}
+
 template <class T>
 Promise<T>::~Promise() {
   detach();
@@ -67,18 +77,26 @@ Promise<T>::~Promise() {
 template <class T>
 void Promise<T>::detach() {
   if (core_) {
-    if (!retrieved_)
+    if (!retrieved_) {
       core_->detachFuture();
+    }
     core_->detachPromise();
     core_ = nullptr;
   }
 }
 
 template <class T>
-Future<T> Promise<T>::getFuture() {
+SemiFuture<T> Promise<T>::getSemiFuture() {
   throwIfRetrieved();
   retrieved_ = true;
-  return Future<T>(core_);
+  return SemiFuture<T>(core_);
+}
+
+template <class T>
+Future<T> Promise<T>::getFuture() {
+  // An InlineExecutor approximates the old behaviour of continuations
+  // running inine on setting the value of the promise.
+  return getSemiFuture().via(&InlineExecutor::instance());
 }
 
 template <class T>
@@ -90,13 +108,7 @@ Promise<T>::setException(E const& e) {
 
 template <class T>
 void Promise<T>::setException(std::exception_ptr const& ep) {
-  try {
-    std::rethrow_exception(ep);
-  } catch (const std::exception& e) {
-    setException(exception_wrapper(std::current_exception(), e));
-  } catch (...) {
-    setException(exception_wrapper(std::current_exception()));
-  }
+  setException(exception_wrapper::from_exception_ptr(ep));
 }
 
 template <class T>
@@ -134,11 +146,11 @@ void Promise<T>::setWith(F&& func) {
 }
 
 template <class T>
-bool Promise<T>::isFulfilled() {
+bool Promise<T>::isFulfilled() const noexcept {
   if (core_) {
     return core_->hasResult();
   }
   return true;
 }
 
-}
+} // namespace folly