From: Yedidya Feldblum Date: Mon, 16 Oct 2017 17:56:48 +0000 (-0700) Subject: 4-way overloads for SemiFuture::value X-Git-Tag: v2017.10.23.00~41 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=943408f56211217a90ebaeec87af88f7969be87a;p=folly.git 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 --- 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) {