Commit ffcba177 authored by Marshall Cline's avatar Marshall Cline Committed by Facebook Github Bot

modernize Future::get(): 1/n = add rval-qual overload invalidates *this

Summary: Add rvalue-qualified overloads of Future::get() and get(dur) which invalidate their this-object.

Reviewed By: yfeldblum

Differential Revision: D8242442

fbshipit-source-id: 4dea8a41878d59f6088504df2b8b3e686d581c89
parent edd050b1
......@@ -2025,12 +2025,28 @@ Future<T>&& Future<T>::waitVia(TimedDrivableExecutor* e, Duration dur) && {
}
template <class T>
T Future<T>::get() {
T Future<T>::get() && {
wait();
return copy(std::move(*this)).value();
}
template <class T>
T Future<T>::get() & {
return std::move(wait().value());
}
template <class T>
T Future<T>::get(Duration dur) {
T Future<T>::get(Duration dur) && {
wait(dur);
auto future = copy(std::move(*this));
if (!future.isReady()) {
throw_exception<FutureTimeout>();
}
return std::move(future).value();
}
template <class T>
T Future<T>::get(Duration dur) & {
wait(dur);
if (!this->isReady()) {
throw_exception<FutureTimeout>();
......
......@@ -1519,7 +1519,13 @@ class Future : private futures::detail::FutureBase<T> {
/// Postconditions:
///
/// - `valid() == false`
T get();
T get() &&;
/// Blocks until the future is fulfilled. Returns the value (moved out), or
/// throws the exception. The future must not already have a callback.
///
/// Deprecated in favor of `get() &&`.
T get() &;
/// Blocks until the future is fulfilled, or until `dur` elapses. Returns the
/// value (moved-out), or throws the exception (which might be a FutureTimeout
......@@ -1532,7 +1538,14 @@ class Future : private futures::detail::FutureBase<T> {
/// Postconditions:
///
/// - `valid() == false`
T get(Duration dur);
T get(Duration dur) &&;
/// Blocks until the future is fulfilled, or until `dur` elapses. Returns the
/// value (moved out), or throws the exception (which might be a FutureTimeout
/// exception).
///
/// Deprecated in favor of `get(Duration) &&`.
T get(Duration dur) &;
/// A reference to the Try of the value
///
......
......@@ -82,6 +82,45 @@ TEST(Future, makeFutureWithUnit) {
EXPECT_EQ(1, count);
}
TEST(Future, getRequiresOnlyMoveCtor) {
struct MoveCtorOnly {
MoveCtorOnly(const MoveCtorOnly&) = delete;
MoveCtorOnly(MoveCtorOnly&&) = default;
MoveCtorOnly(int id) : id_(id) {}
void operator=(MoveCtorOnly const&) = delete;
void operator=(MoveCtorOnly&&) = delete;
int id_;
};
{
auto f = makeFuture<MoveCtorOnly>(MoveCtorOnly(42));
EXPECT_TRUE(f.valid());
EXPECT_TRUE(f.isReady());
auto v = f.get();
EXPECT_EQ(v.id_, 42);
}
{
auto f = makeFuture<MoveCtorOnly>(MoveCtorOnly(42));
EXPECT_TRUE(f.valid());
EXPECT_TRUE(f.isReady());
auto v = std::move(f).get();
EXPECT_EQ(v.id_, 42);
}
{
auto f = makeFuture<MoveCtorOnly>(MoveCtorOnly(42));
EXPECT_TRUE(f.valid());
EXPECT_TRUE(f.isReady());
auto v = f.get(std::chrono::milliseconds(10));
EXPECT_EQ(v.id_, 42);
}
{
auto f = makeFuture<MoveCtorOnly>(MoveCtorOnly(42));
EXPECT_TRUE(f.valid());
EXPECT_TRUE(f.isReady());
auto v = std::move(f).get(std::chrono::milliseconds(10));
EXPECT_EQ(v.id_, 42);
}
}
namespace {
auto makeValid() {
auto valid = makeFuture<int>(42);
......@@ -194,6 +233,10 @@ TEST(Future, hasPreconditionValid) {
DOIT(f.isReady());
DOIT(f.result());
DOIT(f.get());
DOIT(f.get(std::chrono::milliseconds(10)));
DOIT(std::move(f).get());
DOIT(std::move(f).get(std::chrono::milliseconds(10)));
DOIT(f.getTry());
DOIT(f.hasValue());
DOIT(f.hasException());
......@@ -227,6 +270,7 @@ TEST(Future, hasPostconditionValid) {
DOIT(f.raise(std::logic_error("foo")));
DOIT(f.cancel());
DOIT(swallow(f.get()));
DOIT(swallow(f.get(std::chrono::milliseconds(10))));
DOIT(swallow(f.getTry()));
DOIT(f.wait());
DOIT(std::move(f.wait()));
......@@ -280,6 +324,8 @@ TEST(Future, hasPostconditionInvalid) {
auto const swallow = [](auto) {};
DOIT(makeValid(), swallow(std::move(f).wait()));
DOIT(makeValid(), swallow(std::move(f.wait())));
DOIT(makeValid(), swallow(std::move(f).get()));
DOIT(makeValid(), swallow(std::move(f).get(std::chrono::milliseconds(10))));
DOIT(makeValid(), swallow(f.semi()));
#undef DOIT
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment