From cc7a5803e4dc766f182f9bb7f507a04b167c131f Mon Sep 17 00:00:00 2001 From: Hans Fugal Date: Thu, 11 Jun 2015 13:28:57 -0700 Subject: [PATCH] Future::unit() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Summary: Discard a result but propagate an exception. cf https://www.facebook.com/groups/715931878455430/permalink/879624552086161/ Reviewed By: @​sammerat Differential Revision: D2144567 --- folly/futures/Future-inl.h | 16 +++++++++++----- folly/futures/Future.h | 16 +++++++++++++--- folly/futures/test/UnitTest.cpp | 28 ++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/folly/futures/Future-inl.h b/folly/futures/Future-inl.h index 59498af9..446a88f3 100644 --- a/folly/futures/Future-inl.h +++ b/folly/futures/Future-inl.h @@ -49,14 +49,10 @@ Future::Future(T2&& val) : core_(new detail::Core(Try(std::forward(val)))) {} template -template ::value, - int>::type> +template Future::Future() : core_(new detail::Core(Try())) {} - template Future::~Future() { detach(); @@ -452,6 +448,16 @@ bool Future::isReady() const { return core_->ready(); } +template +bool Future::hasValue() { + return getTry().hasValue(); +} + +template +bool Future::hasException() { + return getTry().hasException(); +} + template void Future::raise(exception_wrapper exception) { core_->raise(std::move(exception)); diff --git a/folly/futures/Future.h b/folly/futures/Future.h index 40687b42..98e6eabb 100644 --- a/folly/futures/Future.h +++ b/folly/futures/Future.h @@ -60,10 +60,9 @@ class Future { !isFuture::type>::value>::type> /* implicit */ Future(T2&& val); - template ::value, - int>::type = 0> + folly::is_void_or_unit::value>::type> Future(); ~Future(); @@ -111,6 +110,12 @@ class Future { /** True when the result (or exception) is ready. */ bool isReady() const; + /// sugar for getTry().hasValue() + bool hasValue(); + + /// sugar for getTry().hasException() + bool hasException(); + /** A reference to the Try of the value */ Try& getTry(); @@ -416,6 +421,11 @@ class Future { auto thenMultiWithExecutor(Executor* x, Callback&& fn) -> decltype(this->then(std::forward(fn))); + /// Discard a result, but propagate an exception. + Future unit() { + return then([]{ return Unit{}; }); + } + protected: typedef detail::Core* corePtr; diff --git a/folly/futures/test/UnitTest.cpp b/folly/futures/test/UnitTest.cpp index ae49065b..965a830e 100644 --- a/folly/futures/test/UnitTest.cpp +++ b/folly/futures/test/UnitTest.cpp @@ -20,6 +20,8 @@ using namespace folly; +std::runtime_error eggs("eggs"); + TEST(Unit, futureDefaultCtor) { Future(); } @@ -48,3 +50,29 @@ TEST(Unit, liftVoid) { auto v = std::is_same::value; EXPECT_TRUE(v); } + +TEST(Unit, futureToUnit) { + Future fu = makeFuture(42).unit(); + fu.value(); + EXPECT_TRUE(makeFuture(eggs).unit().hasException()); +} + +TEST(Unit, voidFutureToUnit) { + Future fu = makeFuture().unit(); + fu.value(); + EXPECT_TRUE(makeFuture(eggs).unit().hasException()); +} + +TEST(Unit, unitFutureToUnitIdentity) { + Future fu = makeFuture(Unit{}).unit(); + fu.value(); + EXPECT_TRUE(makeFuture(eggs).unit().hasException()); +} + +TEST(Unit, toUnitWhileInProgress) { + Promise p; + Future fu = p.getFuture().unit(); + EXPECT_FALSE(fu.isReady()); + p.setValue(42); + EXPECT_TRUE(fu.isReady()); +} -- 2.34.1