/*
- * Copyright 2017 Facebook, Inc.
+ * Copyright 2017-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
#pragma once
#include <algorithm>
template <class T>
T& FutureBase<T>::value() & {
+ return result().value();
+}
+
+template <class T>
+T const& FutureBase<T>::value() const& {
+ return result().value();
+}
+
+template <class T>
+T&& FutureBase<T>::value() && {
+ return std::move(result().value());
+}
+
+template <class T>
+T const&& FutureBase<T>::value() const&& {
+ return std::move(result().value());
+}
+
+template <class T>
+Try<T>& FutureBase<T>::result() & {
throwIfInvalid();
- return core_->getTry().value();
+ return core_->getTry();
}
template <class T>
-T const& FutureBase<T>::value() const& {
+Try<T> const& FutureBase<T>::result() const& {
throwIfInvalid();
- return core_->getTry().value();
+ return core_->getTry();
}
template <class T>
-T&& FutureBase<T>::value() && {
+Try<T>&& FutureBase<T>::result() && {
throwIfInvalid();
- return std::move(core_->getTry().value());
+ return std::move(core_->getTry());
}
template <class T>
-T const&& FutureBase<T>::value() const&& {
+Try<T> const&& FutureBase<T>::result() const&& {
throwIfInvalid();
- return std::move(core_->getTry().value());
+ return std::move(core_->getTry());
}
template <class T>
template <class T>
T SemiFuture<T>::get() && {
- return std::move(wait().value());
+ return std::move(wait()).value();
}
template <class T>
template <class T>
Try<T> SemiFuture<T>::getTry() && {
- wait();
- return std::move(this->core_->getTry());
+ return std::move(wait()).result();
+}
+
+template <class T>
+Try<T> SemiFuture<T>::getTry(Duration dur) && {
+ wait(dur);
+ if (this->isReady()) {
+ return std::move(this->result());
+ } else {
+ throwTimedOut();
+ }
}
template <class T>
T SemiFuture<T>::getVia(DrivableExecutor* e) && {
- return std::move(waitVia(e).value());
+ return std::move(waitVia(e)).value();
}
template <class T>
Try<T> SemiFuture<T>::getTryVia(DrivableExecutor* e) && {
- waitVia(e);
- return std::move(this->core_->getTry());
+ return std::move(waitVia(e)).result();
}
template <class T>
template <class T>
Try<T>& Future<T>::getTry() {
- throwIfInvalid();
-
- return this->core_->getTry();
+ return result();
}
template <class T>
/*
- * Copyright 2017 Facebook, Inc.
+ * Copyright 2017-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
#pragma once
#include <algorithm>
T&& value() &&;
T const&& value() const&&;
+ /// Returns a reference to the try of the result. Throws as for value if
+ /// future is not valid.
+ Try<T>& result() &;
+ Try<T> const& result() const&;
+ Try<T>&& result() &&;
+ Try<T> const&& result() const&&;
+
/** True when the result (or exception) is ready. */
bool isReady() const;
using Base::raise;
using Base::setCallback_;
using Base::value;
+ using Base::result;
SemiFuture& operator=(SemiFuture const&) = delete;
SemiFuture& operator=(SemiFuture&&) noexcept;
/// Try of the value (moved out).
Try<T> getTry() &&;
+ /// Block until the future is fulfilled, or until timed out. Returns the
+ /// Try of the value (moved out) or may throw a TimedOut exception.
+ Try<T> getTry(Duration dur) &&;
+
/// Call e->drive() repeatedly until the future is fulfilled. Examples
/// of DrivableExecutor include EventBase and ManualExecutor. Returns the
/// value (moved out), or throws the exception.
using Base::raise;
using Base::setCallback_;
using Base::value;
+ using Base::result;
static Future<T> makeEmpty(); // equivalent to moved-from
/*
- * Copyright 2017 Facebook, Inc.
+ * Copyright 2017-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
#include <folly/Executor.h>
#include <folly/Memory.h>
#include <folly/Unit.h>
ASSERT_EQ(result, 42);
}
+TEST(SemiFuture, SimpleGet) {
+ EventBase e2;
+ Promise<int> p;
+ auto sf = p.getSemiFuture();
+ p.setValue(3);
+ auto v = std::move(sf).get();
+ ASSERT_EQ(v, 3);
+}
+
+TEST(SemiFuture, SimpleGetTry) {
+ EventBase e2;
+ Promise<int> p;
+ auto sf = p.getSemiFuture();
+ p.setValue(3);
+ auto v = std::move(sf).getTry();
+ ASSERT_EQ(v.value(), 3);
+}
+
+TEST(SemiFuture, SimpleTimedGet) {
+ EventBase e2;
+ Promise<folly::Unit> p;
+ auto sf = p.getSemiFuture();
+ EXPECT_THROW(std::move(sf).get(std::chrono::seconds(1)), TimedOut);
+}
+
+TEST(SemiFuture, SimpleTimedGetTry) {
+ EventBase e2;
+ Promise<folly::Unit> p;
+ auto sf = p.getSemiFuture();
+ EXPECT_THROW(std::move(sf).getTry(std::chrono::seconds(1)), TimedOut);
+}
+
+TEST(SemiFuture, SimpleValue) {
+ EventBase e2;
+ Promise<int> p;
+ auto sf = p.getSemiFuture();
+ p.setValue(3);
+ auto v = std::move(sf).value();
+ ASSERT_EQ(v, 3);
+}
+
+TEST(SemiFuture, SimpleValueThrow) {
+ EventBase e2;
+ Promise<folly::Unit> p;
+ auto sf = p.getSemiFuture();
+ EXPECT_THROW(std::move(sf).value(), FutureNotReady);
+}
+
+TEST(SemiFuture, SimpleResult) {
+ EventBase e2;
+ Promise<int> p;
+ auto sf = p.getSemiFuture();
+ p.setValue(3);
+ auto v = std::move(sf).result();
+ ASSERT_EQ(v.value(), 3);
+}
+
+TEST(SemiFuture, SimpleResultThrow) {
+ EventBase e2;
+ Promise<folly::Unit> p;
+ auto sf = p.getSemiFuture();
+ EXPECT_THROW(std::move(sf).result(), FutureNotReady);
+}
+
TEST(SemiFuture, SimpleDefer) {
std::atomic<int> innerResult{0};
Promise<folly::Unit> p;