template<class Body>
void foreach(Body&& body) const {
this->self().apply([&](Value value) -> bool {
+ static_assert(!infinite, "Cannot call foreach on infinite GenImpl");
body(std::forward<Value>(value));
return true;
});
}
+
+ // Child classes should override if the sequence generated is *definitely*
+ // infinite. 'infinite' may be false_type for some infinite sequences
+ // (due the the Halting Problem).
+ static constexpr bool infinite = false;
};
template<class LeftValue,
typename std::enable_if<
IsCompatibleSignature<Handler, void(Value)>::value>::type
operator|(const GenImpl<Value, Gen>& gen, Handler&& handler) {
+ static_assert(!Gen::infinite,
+ "Cannot pull all values from an infinite sequence.");
gen.self().foreach(std::forward<Handler>(handler));
}
body(arg);
}
}
+
+ static constexpr bool infinite = endless;
};
/**
first_.foreach(std::forward<Body>(body));
second_.foreach(std::forward<Body>(body));
}
+
+ static constexpr bool infinite = First::infinite || Second::infinite;
};
/**
return handler(pred_(std::forward<Value>(value)));
});
}
+
+ static constexpr bool infinite = Source::infinite;
};
template<class Source,
return true;
});
}
+
+ static constexpr bool infinite = Source::infinite;
};
template<class Source,
Gen compose(const GenImpl<Value, Source>& source) const {
return Gen(source.self(), pred_);
}
+
+ // Theoretically an 'until' might stop an infinite
+ static constexpr bool infinite = false;
};
/**
return handler(std::forward<Value>(value));
});
}
+
+ static constexpr bool infinite = Source::infinite;
};
template<class Source,
class Generator :
public GenImpl<StorageType&&,
Generator<Value, Source, StorageType, Result>> {
+ static_assert(!Source::infinite, "Cannot sort infinite source!");
Source source_;
Selector selector_;
Comparer comparer_;
template<class Source,
class Value>
Seed compose(const GenImpl<Value, Source>& source) const {
+ static_assert(!Source::infinite, "Cannot foldl infinite source");
Seed accum = seed_;
source | [&](Value v) {
accum = fold_(std::move(accum), std::forward<Value>(v));
template<class Source,
class Value>
bool compose(const GenImpl<Value, Source>& source) const {
+ static_assert(!Source::infinite, "Cannot call 'all' on infinite source");
bool all = true;
source | [&](Value v) -> bool {
if (!pred_(std::forward<Value>(v))) {
template<class Source,
class Value>
size_t compose(const GenImpl<Value, Source>& source) const {
+ static_assert(!Source::infinite, "Cannot count infinite source");
return foldl(size_t(0),
[](size_t accum, Value v) {
return accum + 1;
*/
class Sum : public Operator<Sum> {
public:
- Sum() { }
-
template<class Source,
class Value,
class StorageType = typename std::decay<Value>::type>
StorageType compose(const GenImpl<Value, Source>& source) const {
+ static_assert(!Source::infinite, "Cannot sum infinite source");
return foldl(StorageType(0),
[](StorageType&& accum, Value v) {
return std::move(accum) + std::forward<Value>(v);
class Value,
class StorageType = typename std::decay<Value>::type>
bool compose(const GenImpl<Value, Source>& source) const {
+ static_assert(!Source::infinite,
+ "Calling contains on an infinite source might cause "
+ "an infinite loop.");
return !(source | [this](Value value) {
return !(needle_ == std::forward<Value>(value));
});
inner.foreach(std::forward<Body>(body));
});
}
+
+ static constexpr bool infinite = Source::infinite;
};
template<class Value,