*/
template<class Predicate>
class Map : public Operator<Map<Predicate>> {
- 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 Value,
class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
- return Gen(std::move(source.self()), predicate_);
+ return Gen(std::move(source.self()), pred_);
}
template<class Source,
class Value,
class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
- return Gen(source.self(), predicate_);
+ return Gen(source.self(), pred_);
}
};
*/
template<class Predicate>
class Filter : public Operator<Filter<Predicate>> {
- Predicate predicate_;
+ Predicate pred_;
public:
- explicit Filter(const Predicate& predicate)
- : predicate_(predicate)
+ explicit Filter(const Predicate& pred = Predicate())
+ : pred_(pred)
{ }
template<class Value,
class Value,
class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
- return Gen(std::move(source.self()), predicate_);
+ return Gen(std::move(source.self()), pred_);
}
template<class Source,
class Value,
class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
- return Gen(source.self(), predicate_);
+ return Gen(source.self(), pred_);
}
};
*/
template<class Predicate>
class Until : public Operator<Until<Predicate>> {
- Predicate predicate_;
+ Predicate pred_;
public:
- explicit Until(const Predicate& predicate)
- : predicate_(predicate)
+ explicit Until(const Predicate& pred = Predicate())
+ : pred_(pred)
{ }
template<class Value,
class Value,
class Gen = Generator<Value, Source>>
Gen compose(GenImpl<Value, Source>&& source) const {
- return Gen(std::move(source.self()), predicate_);
+ return Gen(std::move(source.self()), pred_);
}
template<class Source,
class Value,
class Gen = Generator<Value, Source>>
Gen compose(const GenImpl<Value, Source>& source) const {
- return Gen(source.self(), predicate_);
+ return Gen(source.self(), pred_);
}
};
Second second_;
public:
Composed() {}
+
Composed(First first, Second second)
: first_(std::move(first))
, second_(std::move(second)) {}
/**
- * 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<Any> {
public:
};
return any;
}
+
+ /**
+ * Convenience function for use like:
+ *
+ * bool found = gen | any([](int i) { return i * i > 100; });
+ */
+ template<class Predicate,
+ class Filter = Filter<Predicate>,
+ class Composed = Composed<Filter, Any>>
+ 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 Predicate>
+class All : public Operator<All<Predicate>> {
+ Predicate pred_;
+ public:
+ explicit All(const Predicate& pred = Predicate())
+ : pred_(pred)
+ { }
+
+ template<class Source,
+ class Value>
+ bool compose(const GenImpl<Value, Source>& source) const {
+ bool all = true;
+ source | [&](Value v) -> bool {
+ if (!pred_(std::forward<Value>(v))) {
+ all = false;
+ return false;
+ }
+ return true;
+ };
+ return all;
+ }
};
/**
class Fold>
class FoldLeft;
+class First;
+
+class Any;
+
+template<class Predicate>
+class All;
+
template<class Reducer>
class Reduce;
template<class Predicate,
class Filter = detail::Filter<Predicate>>
-Filter filter(const Predicate& pred = Predicate()) {
- return Filter(pred);
+Filter filter(Predicate pred = Predicate()) {
+ return Filter(std::move(pred));
+}
+
+template<class Predicate,
+ class All = detail::All<Predicate>>
+All all(Predicate pred = Predicate()) {
+ return All(std::move(pred));
}
template<class Predicate,
class Until = detail::Until<Predicate>>
-Until until(const Predicate& pred = Predicate()) {
- return Until(pred);
+Until until(Predicate pred = Predicate()) {
+ return Until(std::move(pred));
}
template<class Selector,
class Comparer = Less,
class Order = detail::Order<Selector, Comparer>>
Order orderBy(const Selector& selector,
- const Comparer& comparer = Comparer()) {
+ const Comparer& comparer = Comparer()) {
return Order(selector, comparer);
}
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) {