From: Tom Jackson Date: Thu, 7 Feb 2013 18:18:15 +0000 (-0800) Subject: all(), better any() X-Git-Tag: v0.22.0~1066 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=0e21224b1ca689045806121a6df08eecbced8ce7;p=folly.git all(), better any() Summary: TSIA Test Plan: Unit tests Reviewed By: tulloch@fb.com FB internal diff: D701890 --- diff --git a/folly/experimental/Gen-inl.h b/folly/experimental/Gen-inl.h index 6937fbb6..13478395 100644 --- a/folly/experimental/Gen-inl.h +++ b/folly/experimental/Gen-inl.h @@ -528,10 +528,10 @@ class Yield : public GenImpl> { */ template class Map : public Operator> { - Predicate predicate_; + Predicate pred_; public: - explicit Map(const Predicate& predicate = Predicate()) - : predicate_(predicate) + explicit Map(const Predicate& pred = Predicate()) + : pred_(pred) { } template> { class Value, class Gen = Generator> Gen compose(GenImpl&& source) const { - return Gen(std::move(source.self()), predicate_); + return Gen(std::move(source.self()), pred_); } template> Gen compose(const GenImpl& source) const { - return Gen(source.self(), predicate_); + return Gen(source.self(), pred_); } }; @@ -590,10 +590,10 @@ class Map : public Operator> { */ template class Filter : public Operator> { - Predicate predicate_; + Predicate pred_; public: - explicit Filter(const Predicate& predicate) - : predicate_(predicate) + explicit Filter(const Predicate& pred = Predicate()) + : pred_(pred) { } template> { class Value, class Gen = Generator> Gen compose(GenImpl&& source) const { - return Gen(std::move(source.self()), predicate_); + return Gen(std::move(source.self()), pred_); } template> Gen compose(const GenImpl& source) const { - return Gen(source.self(), predicate_); + return Gen(source.self(), pred_); } }; @@ -651,10 +651,10 @@ class Filter : public Operator> { */ template class Until : public Operator> { - Predicate predicate_; + Predicate pred_; public: - explicit Until(const Predicate& predicate) - : predicate_(predicate) + explicit Until(const Predicate& pred = Predicate()) + : pred_(pred) { } template> { class Value, class Gen = Generator> Gen compose(GenImpl&& source) const { - return Gen(std::move(source.self()), predicate_); + return Gen(std::move(source.self()), pred_); } template> Gen compose(const GenImpl& source) const { - return Gen(source.self(), predicate_); + return Gen(source.self(), pred_); } }; @@ -935,6 +935,7 @@ class Composed : public Operator> { Second second_; public: Composed() {} + Composed(First first, Second second) : first_(std::move(first)) , second_(std::move(second)) {} @@ -1027,11 +1028,16 @@ class First : public Operator { /** - * Any - For determining whether any values are contained in a sequence. + * Any - For determining whether any values in a sequence satisfy a predicate. * * This type is primarily used through the 'any' static value, like: * * bool any20xPrimes = seq(200, 210) | filter(isPrime) | any; + * + * Note that it may also be used like so: + * + * bool any20xPrimes = seq(200, 210) | any(isPrime); + * */ class Any : public Operator { public: @@ -1047,6 +1053,50 @@ class Any : public Operator { }; return any; } + + /** + * Convenience function for use like: + * + * bool found = gen | any([](int i) { return i * i > 100; }); + */ + template, + class Composed = Composed> + Composed operator()(Predicate pred) const { + return Composed(Filter(std::move(pred)), Any()); + } +}; + +/** + * All - For determining whether all values in a sequence satisfy a predicate. + * + * This type is primarily used through the 'any' static value, like: + * + * bool valid = from(input) | all(validate); + * + * Note: Passing an empty sequence through 'all()' will always return true. + */ +template +class All : public Operator> { + Predicate pred_; + public: + explicit All(const Predicate& pred = Predicate()) + : pred_(pred) + { } + + template + bool compose(const GenImpl& source) const { + bool all = true; + source | [&](Value v) -> bool { + if (!pred_(std::forward(v))) { + all = false; + return false; + } + return true; + }; + return all; + } }; /** diff --git a/folly/experimental/Gen.h b/folly/experimental/Gen.h index 444fb8ef..b44cfde0 100644 --- a/folly/experimental/Gen.h +++ b/folly/experimental/Gen.h @@ -223,6 +223,13 @@ template class FoldLeft; +class First; + +class Any; + +template +class All; + template class Reduce; @@ -342,21 +349,27 @@ Map map(const Predicate& pred = Predicate()) { template> -Filter filter(const Predicate& pred = Predicate()) { - return Filter(pred); +Filter filter(Predicate pred = Predicate()) { + return Filter(std::move(pred)); +} + +template> +All all(Predicate pred = Predicate()) { + return All(std::move(pred)); } template> -Until until(const Predicate& pred = Predicate()) { - return Until(pred); +Until until(Predicate pred = Predicate()) { + return Until(std::move(pred)); } template> Order orderBy(const Selector& selector, - const Comparer& comparer = Comparer()) { + const Comparer& comparer = Comparer()) { return Order(selector, comparer); } diff --git a/folly/experimental/test/GenTest.cpp b/folly/experimental/test/GenTest.cpp index 355cd41d..4e08fbd0 100644 --- a/folly/experimental/test/GenTest.cpp +++ b/folly/experimental/test/GenTest.cpp @@ -416,11 +416,24 @@ TEST(Gen, Get) { TEST(Gen, Any) { EXPECT_TRUE(seq(0) | any); EXPECT_TRUE(seq(0, 1) | any); + EXPECT_TRUE(seq(0, 10) | any([](int i) { return i == 7; })); + EXPECT_FALSE(seq(0, 10) | any([](int i) { return i == 11; })); + EXPECT_TRUE(from({1}) | any); EXPECT_FALSE(range(0, 0) | any); EXPECT_FALSE(from({1}) | take(0) | any); } +TEST(Gen, All) { + EXPECT_TRUE(seq(0, 10) | all([](int i) { return i < 11; })); + EXPECT_FALSE(seq(0, 10) | all([](int i) { return i < 5; })); + EXPECT_FALSE(seq(0) | all([](int i) { return i < 10; })); + + // empty lists satisfies all + EXPECT_TRUE(seq(0) | take(0) | all([](int i) { return i < 50; })); + EXPECT_TRUE(seq(0) | take(0) | all([](int i) { return i > 50; })); +} + TEST(Gen, Yielders) { auto gen = GENERATOR(int) { for (int i = 1; i <= 5; ++i) {