Commit 77c9cc67 authored by Hans Fugal's avatar Hans Fugal Committed by afrind

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
parent 397a944b
...@@ -825,6 +825,19 @@ Future<bool> Future<T>::willEqual(Future<T>& f) { ...@@ -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 futures {
namespace { namespace {
template <class Z> template <class Z>
......
...@@ -474,6 +474,12 @@ class Future { ...@@ -474,6 +474,12 @@ class Future {
/// exception) /// exception)
Future<bool> willEqual(Future<T>&); 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: protected:
typedef detail::Core<T>* corePtr; typedef detail::Core<T>* corePtr;
......
...@@ -91,4 +91,9 @@ class TimedOut : public FutureException { ...@@ -91,4 +91,9 @@ class TimedOut : public FutureException {
TimedOut() : FutureException("Timed out") {} TimedOut() : FutureException("Timed out") {}
}; };
class PredicateDoesNotObtain : public FutureException {
public:
PredicateDoesNotObtain() : FutureException("Predicate does not obtain") {}
};
} }
...@@ -27,15 +27,31 @@ TEST(Sugar, pollReady) { ...@@ -27,15 +27,31 @@ TEST(Sugar, pollReady) {
EXPECT_EQ(42, f.poll().value().value()); EXPECT_EQ(42, f.poll().value().value());
} }
TEST(SUGAR, pollNotReady) { TEST(Sugar, pollNotReady) {
Promise<int> p; Promise<int> p;
auto f = p.getFuture(); auto f = p.getFuture();
EXPECT_FALSE(f.poll().hasValue()); EXPECT_FALSE(f.poll().hasValue());
} }
TEST(SUGAR, pollException) { TEST(Sugar, pollException) {
Promise<void> p; Promise<void> p;
auto f = p.getFuture(); auto f = p.getFuture();
p.fulfil([] { throw std::runtime_error("Runtime"); }); p.fulfil([] { throw std::runtime_error("Runtime"); });
EXPECT_TRUE(f.poll().value().hasException()); 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());
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment