From: Hans Fugal <fugalh@fb.com> Date: Mon, 30 Mar 2015 15:44:48 +0000 (-0700) Subject: Future::filter(A => bool) X-Git-Tag: v0.33.0~20 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=77c9cc673969bb90e92b13b505d38164249dd024;p=folly.git 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 --- 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<bool> Future<T>::willEqual(Future<T>& f) { }); } +template <class T> +template <class F> +Future<T> Future<T>::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 <class Z> 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<bool> willEqual(Future<T>&); + /// predicate behaves like std::function<bool(T const&)> + /// If the predicate does not obtain with the value, the result + /// is a folly::PredicateDoesNotObtain exception + template <class F> + Future<T> filter(F predicate); + protected: typedef detail::Core<T>* 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<int> p; auto f = p.getFuture(); EXPECT_FALSE(f.poll().hasValue()); } -TEST(SUGAR, pollException) { +TEST(Sugar, pollException) { Promise<void> 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<int>(42)) + .filter([](std::unique_ptr<int> const&) { return true; }) + .get()); +}