From 943408f56211217a90ebaeec87af88f7969be87a Mon Sep 17 00:00:00 2001 From: Yedidya Feldblum Date: Mon, 16 Oct 2017 10:56:48 -0700 Subject: [PATCH] 4-way overloads for SemiFuture::value Summary: [Folly] 4-way overloads for `SemiFuture::value`. Overload on the receiver reference category and `const`-qualification, deriving the return type reference category and `const`-qualification. Like `Optional`, `Try`, etc. Differential Revision: D6062006 fbshipit-source-id: d7396cd4d4bb62e99445d5f61cb360898fa1c3f3 --- folly/futures/Future-inl.h | 18 ++++++++++++++++-- folly/futures/Future.h | 21 +++++++++++++-------- folly/futures/test/SemiFutureTest.cpp | 5 +++++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/folly/futures/Future-inl.h b/folly/futures/Future-inl.h index 7a4f073f..cdd38f7b 100644 --- a/folly/futures/Future-inl.h +++ b/folly/futures/Future-inl.h @@ -247,19 +247,33 @@ SemiFuture::~SemiFuture() { } template -typename std::add_lvalue_reference::type SemiFuture::value() { +T& SemiFuture::value() & { throwIfInvalid(); return core_->getTry().value(); } template -typename std::add_lvalue_reference::type SemiFuture::value() const { +T const& SemiFuture::value() const& { throwIfInvalid(); return core_->getTry().value(); } +template +T&& SemiFuture::value() && { + throwIfInvalid(); + + return std::move(core_->getTry().value()); +} + +template +T const&& SemiFuture::value() const&& { + throwIfInvalid(); + + return std::move(core_->getTry().value()); +} + template inline Future SemiFuture::via(Executor* executor, int8_t priority) && { throwIfInvalid(); diff --git a/folly/futures/Future.h b/folly/futures/Future.h index 5159062d..f5c3190f 100644 --- a/folly/futures/Future.h +++ b/folly/futures/Future.h @@ -82,14 +82,19 @@ class SemiFuture { ~SemiFuture(); - /** Return the reference to result. Should not be called if !isReady(). - Will rethrow the exception if an exception has been - captured. - */ - typename std::add_lvalue_reference::type - value(); - typename std::add_lvalue_reference::type - value() const; + /// Returns a reference to the result, with a reference category and const- + /// qualification equivalent to the reference category and const-qualification + /// of the receiver. + /// + /// If moved-from, throws NoState. + /// + /// If !isReady(), throws FutureNotReady. + /// + /// If an exception has been captured, throws that exception. + T& value() &; + T const& value() const&; + T&& value() &&; + T const&& value() const&&; /// Returns an inactive Future which will call back on the other side of /// executor (when it is activated). diff --git a/folly/futures/test/SemiFutureTest.cpp b/folly/futures/test/SemiFutureTest.cpp index d3cb1a26..64527adf 100644 --- a/folly/futures/test/SemiFutureTest.cpp +++ b/folly/futures/test/SemiFutureTest.cpp @@ -77,6 +77,11 @@ TEST(SemiFuture, value) { EXPECT_EQ(42, *up); EXPECT_THROW(makeSemiFuture(eggs).value(), eggs_t); + + EXPECT_TYPE(std::declval&>().value(), int&); + EXPECT_TYPE(std::declval const&>().value(), int const&); + EXPECT_TYPE(std::declval&&>().value(), int&&); + EXPECT_TYPE(std::declval const&&>().value(), int const&&); } TEST(SemiFuture, hasException) { -- 2.34.1