Future::filter(A => bool)
authorHans Fugal <fugalh@fb.com>
Mon, 30 Mar 2015 15:44:48 +0000 (08:44 -0700)
committerafrind <afrind@fb.com>
Thu, 2 Apr 2015 19:00:20 +0000 (12:00 -0700)
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
folly/futures/Future.h
folly/futures/FutureException.h
folly/futures/test/SugarTest.cpp

index 9d37c1659b6cb9d5a42aa4a5ebe3515aa39ddd95..dc842741bb1b0f81203c95e98300ae935a25ccd2 100644 (file)
@@ -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>
index 3d4dff2c4ede18f6e9be3bc6c545549d8185d08a..f507748df2aee09da78b0b903aeda78d445d0ab1 100644 (file)
@@ -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;
 
index dce9e2620e486a404e7bacd6362934bbc08955a5..1e004dcf167a88b37a9a97762aa3b3370669244e 100644 (file)
@@ -91,4 +91,9 @@ class TimedOut : public FutureException {
   TimedOut() : FutureException("Timed out") {}
 };
 
+class PredicateDoesNotObtain : public FutureException {
+ public:
+  PredicateDoesNotObtain() : FutureException("Predicate does not obtain") {}
+};
+
 }
index 152fe546310a6c1190babae4cf8f851ef594fa69..bbafdebbda415fa54310c497dd011e2b4fd3f1da 100644 (file)
@@ -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());
+}