From: Monica Lee Date: Fri, 27 Feb 2015 17:37:25 +0000 (-0800) Subject: Add willEqual to C++ Futures Code X-Git-Tag: v0.27.0~9 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=42ab246273a3c4f63b3645207818d0ea698eadc0;p=folly.git Add willEqual to C++ Futures Code Summary: Added willEqual function and wrote unit tests for it. Test Plan: fbconfig --clang folly/futures && fbmake runtests Reviewed By: hans@fb.com Subscribers: hannesr, trunkagent, folly-diffs@, jsedgwick, yfeldblum FB internal diff: D1859840 Tasks: 6166911 Signature: t1:1859840:1424967149:865ee96ab4d3f5dbf17eb371b2ac3ccb5066ac87 --- diff --git a/folly/futures/Future-inl.h b/folly/futures/Future-inl.h index 78f3d86b..6dd7a155 100644 --- a/folly/futures/Future-inl.h +++ b/folly/futures/Future-inl.h @@ -743,8 +743,18 @@ inline void Future::getVia(DrivableExecutor* e) { waitVia(e).value(); } -namespace futures { +template +Future Future::willEqual(Future& f) { + return whenAll(*this, f).then([](const std::tuple, Try>& t) { + if (std::get<0>(t).hasValue() && std::get<1>(t).hasValue()) { + return std::get<0>(t).value() == std::get<1>(t).value(); + } else { + return false; + } + }); +} +namespace futures { namespace { template Future chainHelper(Future f) { diff --git a/folly/futures/Future.h b/folly/futures/Future.h index 935fe15a..7021f4f2 100644 --- a/folly/futures/Future.h +++ b/folly/futures/Future.h @@ -455,7 +455,12 @@ class Future { /// Overload of waitVia() for rvalue Futures Future&& waitVia(DrivableExecutor* e) &&; - protected: + /// If the value in this Future is equal to the given Future, when they have + /// both completed, the value of the resulting Future will be true. It + /// will be false otherwise (including when one or both Futures have an + /// exception) + Future willEqual(Future&); + typedef detail::Core* corePtr; // shared core state object diff --git a/folly/futures/test/FutureTest.cpp b/folly/futures/test/FutureTest.cpp index 48358e16..ed696f9a 100644 --- a/folly/futures/test/FutureTest.cpp +++ b/folly/futures/test/FutureTest.cpp @@ -1329,3 +1329,84 @@ TEST(Future, ensure) { EXPECT_THROW(f.get(), std::runtime_error); EXPECT_EQ(2, count); } + +TEST(Future, willEqual) { + //both p1 and p2 already fulfilled + { + Promise p1; + Promise p2; + p1.setValue(27); + p2.setValue(27); + auto f1 = p1.getFuture(); + auto f2 = p2.getFuture(); + EXPECT_TRUE(f1.willEqual(f2).get()); + }{ + Promise p1; + Promise p2; + p1.setValue(27); + p2.setValue(36); + auto f1 = p1.getFuture(); + auto f2 = p2.getFuture(); + EXPECT_FALSE(f1.willEqual(f2).get()); + } + //both p1 and p2 not yet fulfilled + { + Promise p1; + Promise p2; + auto f1 = p1.getFuture(); + auto f2 = p2.getFuture(); + auto f3 = f1.willEqual(f2); + p1.setValue(27); + p2.setValue(27); + EXPECT_TRUE(f3.get()); + }{ + Promise p1; + Promise p2; + auto f1 = p1.getFuture(); + auto f2 = p2.getFuture(); + auto f3 = f1.willEqual(f2); + p1.setValue(27); + p2.setValue(36); + EXPECT_FALSE(f3.get()); + } + //p1 already fulfilled, p2 not yet fulfilled + { + Promise p1; + Promise p2; + p1.setValue(27); + auto f1 = p1.getFuture(); + auto f2 = p2.getFuture(); + auto f3 = f1.willEqual(f2); + p2.setValue(27); + EXPECT_TRUE(f3.get()); + }{ + Promise p1; + Promise p2; + p1.setValue(27); + auto f1 = p1.getFuture(); + auto f2 = p2.getFuture(); + auto f3 = f1.willEqual(f2); + p2.setValue(36); + EXPECT_FALSE(f3.get()); + } + //p2 already fulfilled, p1 not yet fulfilled + { + Promise p1; + Promise p2; + p2.setValue(27); + auto f1 = p1.getFuture(); + auto f2 = p2.getFuture(); + auto f3 = f1.willEqual(f2); + p1.setValue(27); + EXPECT_TRUE(f3.get()); + }{ + Promise p1; + Promise p2; + p2.setValue(36); + auto f1 = p1.getFuture(); + auto f2 = p2.getFuture(); + auto f3 = f1.willEqual(f2); + p1.setValue(27); + EXPECT_FALSE(f3.get()); + } +}