From 77c9cc673969bb90e92b13b505d38164249dd024 Mon Sep 17 00:00:00 2001 From: Hans Fugal Date: Mon, 30 Mar 2015 08:44:48 -0700 Subject: [PATCH] Future::filter(A => bool) Test Plan: new unit tests Reviewed By: davejwatson@fb.com Subscribers: chalfant, bmatheny, trunkagent, exa, folly-diffs@, yfeldblum, jsedgwick FB internal diff: D1828251 Tasks: 6166893 Signature: t1:1828251:1427475565:512463d5728482a40c1da2548a5bed91e7f92d60 --- folly/futures/Future-inl.h | 13 +++++++++++++ folly/futures/Future.h | 6 ++++++ folly/futures/FutureException.h | 5 +++++ folly/futures/test/SugarTest.cpp | 20 ++++++++++++++++++-- 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/folly/futures/Future-inl.h b/folly/futures/Future-inl.h index 9d37c165..dc842741 100644 --- a/folly/futures/Future-inl.h +++ b/folly/futures/Future-inl.h @@ -825,6 +825,19 @@ Future Future::willEqual(Future& f) { }); } +template +template +Future Future::filter(F predicate) { + auto p = folly::makeMoveWrapper(std::move(predicate)); + return this->then([p](T val) { + T const& valConstRef = val; + if (!(*p)(valConstRef)) { + throw PredicateDoesNotObtain(); + } + return val; + }); +} + namespace futures { namespace { template diff --git a/folly/futures/Future.h b/folly/futures/Future.h index 3d4dff2c..f507748d 100644 --- a/folly/futures/Future.h +++ b/folly/futures/Future.h @@ -474,6 +474,12 @@ class Future { /// exception) Future willEqual(Future&); + /// predicate behaves like std::function + /// If the predicate does not obtain with the value, the result + /// is a folly::PredicateDoesNotObtain exception + template + Future filter(F predicate); + protected: typedef detail::Core* corePtr; diff --git a/folly/futures/FutureException.h b/folly/futures/FutureException.h index dce9e262..1e004dcf 100644 --- a/folly/futures/FutureException.h +++ b/folly/futures/FutureException.h @@ -91,4 +91,9 @@ class TimedOut : public FutureException { TimedOut() : FutureException("Timed out") {} }; +class PredicateDoesNotObtain : public FutureException { + public: + PredicateDoesNotObtain() : FutureException("Predicate does not obtain") {} +}; + } diff --git a/folly/futures/test/SugarTest.cpp b/folly/futures/test/SugarTest.cpp index 152fe546..bbafdebb 100644 --- a/folly/futures/test/SugarTest.cpp +++ b/folly/futures/test/SugarTest.cpp @@ -27,15 +27,31 @@ TEST(Sugar, pollReady) { EXPECT_EQ(42, f.poll().value().value()); } -TEST(SUGAR, pollNotReady) { +TEST(Sugar, pollNotReady) { Promise p; auto f = p.getFuture(); EXPECT_FALSE(f.poll().hasValue()); } -TEST(SUGAR, pollException) { +TEST(Sugar, pollException) { Promise p; auto f = p.getFuture(); p.fulfil([] { throw std::runtime_error("Runtime"); }); EXPECT_TRUE(f.poll().value().hasException()); } + +TEST(Sugar, filterTrue) { + EXPECT_EQ(42, makeFuture(42).filter([](int){ return true; }).get()); +} + +TEST(Sugar, filterFalse) { + EXPECT_THROW(makeFuture(42).filter([](int){ return false; }).get(), + folly::PredicateDoesNotObtain); +} + +TEST(Sugar, filterMoveonly) { + EXPECT_EQ(42, + *makeFuture(folly::make_unique(42)) + .filter([](std::unique_ptr const&) { return true; }) + .get()); +} -- 2.34.1