Really fix the clang warning in Format-inl.h
[folly.git] / folly / wangle / Promise-inl.h
index 190d9cd04168725b71146239a11c30157ac239e0..68d696411f184d37640a0024fabdfcc3a520564c 100644 (file)
 #include <atomic>
 #include <thread>
 
-#include "WangleException.h"
-#include "detail/State.h"
+#include <folly/wangle/WangleException.h>
+#include <folly/wangle/detail/Core.h>
 
 namespace folly { namespace wangle {
 
 template <class T>
-Promise<T>::Promise() : retrieved_(false), state_(new detail::State<T>())
+Promise<T>::Promise() : retrieved_(false), core_(new detail::Core<T>())
 {}
 
 template <class T>
-Promise<T>::Promise(Promise<T>&& other) :
-retrieved_(other.retrieved_), state_(other.state_) {
-  other.state_ = nullptr;
+Promise<T>::Promise(Promise<T>&& other) : core_(nullptr) {
+  *this = std::move(other);
 }
 
 template <class T>
 Promise<T>& Promise<T>::operator=(Promise<T>&& other) {
-  std::swap(state_, other.state_);
+  std::swap(core_, other.core_);
   std::swap(retrieved_, other.retrieved_);
   return *this;
 }
 
 template <class T>
 void Promise<T>::throwIfFulfilled() {
-  if (!state_)
+  if (!core_)
+    throw NoState();
+  if (core_->ready())
     throw PromiseAlreadySatisfied();
 }
 
@@ -55,44 +56,48 @@ void Promise<T>::throwIfRetrieved() {
 
 template <class T>
 Promise<T>::~Promise() {
-  if (state_) {
-    setException(BrokenPromise());
+  detach();
+}
+
+template <class T>
+void Promise<T>::detach() {
+  if (core_) {
+    if (!retrieved_)
+      core_->detachFuture();
+    core_->detachPromise();
+    core_ = nullptr;
   }
 }
 
 template <class T>
 Future<T> Promise<T>::getFuture() {
   throwIfRetrieved();
-  throwIfFulfilled();
   retrieved_ = true;
-  return Future<T>(state_);
+  return Future<T>(core_);
 }
 
 template <class T>
 template <class E>
 void Promise<T>::setException(E const& e) {
-  throwIfFulfilled();
   setException(std::make_exception_ptr<E>(e));
 }
 
 template <class T>
 void Promise<T>::setException(std::exception_ptr const& e) {
   throwIfFulfilled();
-  state_->setException(e);
-  if (!retrieved_) {
-    delete state_;
-  }
-  state_ = nullptr;
+  core_->setResult(Try<T>(e));
+}
+
+template <class T>
+void Promise<T>::setInterruptHandler(
+  std::function<void(std::exception_ptr const&)> fn) {
+  core_->setInterruptHandler(std::move(fn));
 }
 
 template <class T>
 void Promise<T>::fulfilTry(Try<T>&& t) {
   throwIfFulfilled();
-  state_->fulfil(std::move(t));
-  if (!retrieved_) {
-    delete state_;
-  }
-  state_ = nullptr;
+  core_->setResult(std::move(t));
 }
 
 template <class T>
@@ -101,12 +106,7 @@ void Promise<T>::setValue(M&& v) {
   static_assert(!std::is_same<T, void>::value,
                 "Use setValue() instead");
 
-  throwIfFulfilled();
-  state_->fulfil(Try<T>(std::forward<M>(v)));
-  if (!retrieved_) {
-    delete state_;
-  }
-  state_ = nullptr;
+  fulfilTry(Try<T>(std::forward<M>(v)));
 }
 
 template <class T>
@@ -114,47 +114,14 @@ void Promise<T>::setValue() {
   static_assert(std::is_same<T, void>::value,
                 "Use setValue(value) instead");
 
-  throwIfFulfilled();
-  state_->fulfil(Try<void>());
-  if (!retrieved_) {
-    delete state_;
-  }
-  state_ = nullptr;
+  fulfilTry(Try<void>());
 }
 
 template <class T>
 template <class F>
 void Promise<T>::fulfil(F&& func) {
-  fulfilHelper(std::forward<F>(func));
-}
-
-template <class T>
-template <class F>
-typename std::enable_if<
-  std::is_convertible<typename std::result_of<F()>::type, T>::value &&
-  !std::is_same<T, void>::value>::type
-inline Promise<T>::fulfilHelper(F&& func) {
-  throwIfFulfilled();
-  try {
-    setValue(func());
-  } catch (...) {
-    setException(std::current_exception());
-  }
-}
-
-template <class T>
-template <class F>
-typename std::enable_if<
-  std::is_same<typename std::result_of<F()>::type, void>::value &&
-  std::is_same<T, void>::value>::type
-inline Promise<T>::fulfilHelper(F&& func) {
   throwIfFulfilled();
-  try {
-    func();
-    setValue();
-  } catch (...) {
-    setException(std::current_exception());
-  }
+  fulfilTry(makeTryFunction(std::forward<F>(func)));
 }
 
 }}