6#include "../polyfill/std_optional.hpp"
14template <
typename T,
typename S>
16 std::function<const std::optional<T>(
S &)> lambda;
18 std::optional<T> current_yield;
27 explicit generatorIter(std::function<
const std::optional<T>(
S &)> lambda,
const S &state,
bool dummy =
false) : lambda(lambda), state(state), current_yield(
T()) {
38 return current_yield.value();
46 current_yield = lambda(state);
56 return current_yield.has_value();
70template <
typename T,
typename S>
73 std::function<const std::optional<T>(
S &)> lambda;
111 inline std::optional<T>
next() {
112 return lambda(state);
122 ->
map<
long>([](
const T &state) {
126 .
reduce(0, std::plus<long>());
136 for (
auto i : *
this) {
149 for (
auto _ : *
this) {
169 if (!
item.has_value()) {
188 template <
typename U>
190 auto lambda = this->lambda;
193 auto item = lambda(state);
194 if (!
item.has_value()) {
213 auto lambda = this->lambda;
216 auto val = lambda(state);
217 while (
val.has_value()) {
242 auto result = lambda(state);
244 if (!
result.has_value()) {
248 auto value =
result.value();
252 if (!
result.has_value()) {
273 auto lambda = this->lambda;
274 this->lambda = [lambda,
newLambda](
S &state) {
275 auto item = lambda(state);
276 if (
item.has_value()) {
296 auto lambda = this->lambda;
299 for (
long i = 0;
i < state.count;
i++) {
300 auto item = lambda(state.state);
301 if (!
item.has_value()) {
307 return lambda(state.state);
318 auto lambda = this->lambda;
321 if (state.count <= 0) {
322 return std::optional<T>();
325 auto item = lambda(state.state);
326 if (!
item.has_value()) {
345 template <
typename U,
typename S2>
351 if (!
item1.has_value()) {
352 return std::optional<pair_type>();
356 if (!
item2.has_value()) {
357 return std::optional<pair_type>();
360 return std::optional<pair_type>({
item1.value(),
item2.value()});
376 state.first = !state.first;
381 if (
item.has_value()) {
384 return state.second.next();
388 auto item = state.second.next();
389 if (
item.has_value()) {
405 return generator<std::pair<long, T>, std::pair<long, generator<T, S>>>({0, *
this}, [](std::pair<long, generator<T, S>> &state) -> std::optional<std::pair<long, T>> {
406 auto item = state.second.next();
407 if (!
item.has_value()) {
410 return std::pair<long, T>{state.first++,
item.value()};
435 if (!
item1.has_value()) {
439 if (!state.second.has_value()) {
440 return item1.value();
443 if (
item1.value() != state.second.value()) {
444 return item1.value();
448 state.second = state.first.next();
467 auto item = state.next();
468 if (!
item.has_value()) {
488 std::optional<T> data;
489 std::optional<iterator_value<T>>
iter;
497 if (!state.data || (state.iter.value() == state.data.value().
end())) {
511 state.iter = state.data.value().
begin();
517 return *state.iter.value()++;
535 auto &
gen = state.second;
563 template <
typename U>
568 if (!
item.has_value()) {
608 if (state.second != state.first.
end()) {
609 auto ret = *state.second;
627 if (state.second < state.first.
length()) {
628 return state.first[state.second++];
642template <
typename K,
typename V>
644 return generator<std::pair<K, V>,
typename std::map<K, V>::const_iterator>(map.begin(), [&map](
auto &
iter) -> std::optional<std::pair<K, V>> {
662template <
typename K,
typename V>
664 return generator<std::pair<K, V>, std::pair<typename std::map<K, V>::const_iterator, std::map<K, V>>>({map.begin(), map}, [](
auto &state) -> std::optional<std::pair<K, V>> {
665 if (state.first != state.second.
end()) {
666 auto ret = *state.first;
A wrapper for std::vector.
Definition array.hpp:75
void increase(int newSize) noexcept
Increase the space allocated for this array.
Definition array.hpp:192
int push(const T &object) noexcept
Add an object to the array.
Definition array.hpp:242
int length() const noexcept override
Get the length of the array.
Definition array.hpp:1035
T * begin() const noexcept override
Get pointer to the beginning of the array.
Definition array.hpp:621
T * end() const noexcept override
Get pointer to the end of the array.
Definition array.hpp:633
array< U > map(std::function< U(const T &)> lambda) const
Applies a transformation function to each element of the array and returns a new array with the resul...
Definition array.hpp:1230
Custom iterator for generators to allow for range-based for loops.
Definition generator.hpp:15
bool operator!=(const generatorIter &other) const
Check if the generator can get more data.
Definition generator.hpp:54
generatorIter(std::function< const std::optional< T >(S &)> lambda, const S &state, bool dummy=false)
Constructor.
Definition generator.hpp:27
generatorIter & operator++()
Generate the next value.
Definition generator.hpp:45
const T & operator*() const
Get the current value from the generator.
Definition generator.hpp:37
An arbitrary generator for producing sequential results on-the-fly.
Definition generator.hpp:71
generator filter(std::function< T(const T &)> filterLambda) noexcept
Filters the generatred items based on a predicate and returns a new generator that yields only the it...
Definition generator.hpp:212
generator< array< T >, generator > chunk(long chunkSize) noexcept
Get chunks of items from the generator.
Definition generator.hpp:463
generator & forEach(std::function< void(const T &)> newLambda) noexcept
Binds a function to run each time an item comes out of the generator.
Definition generator.hpp:272
generator(const S &initial, std::function< const std::optional< T >(S &)> lambda)
Constructor with an initial state.
Definition generator.hpp:86
array< T > collect()
Concatenate all generator elements into an array.
Definition generator.hpp:134
generator< T, std::pair< generator, std::optional< T > > > diff(generator &other) noexcept
List the items in this generator which differ from another generator.
Definition generator.hpp:431
generator< T, countedState > skip(long count) noexcept
Skips a certain number of items from the generator.
Definition generator.hpp:295
long count()
Get the total count of items that will be generated.
Definition generator.hpp:120
T reduce(const T &defaultValue, std::function< T(const T &, const T &)> reduceLambda)
Reduces the generator to a single value by applying a binary operation cumulatively to all yielded va...
Definition generator.hpp:241
generator< U, S > map(std::function< U(const T &)> mapLambda) noexcept
Applies a transformation function to each item that comes out of the generator.
Definition generator.hpp:189
generator< T, bool > chain(generator< T, U > &other) noexcept
Chains two generators together.
Definition generator.hpp:564
long consume()
Consume and discard all items from the generator.
Definition generator.hpp:147
generator< T, std::pair< bool, generator & > > zip(generator &other) noexcept
Zip this generator with another generator.
Definition generator.hpp:374
generatorIter< T, S > end() const noexcept override
End iterator (end of the range)
Definition generator.hpp:100
auto flatten() noexcept
Break up a chunked generator into its constituent generated items.
Definition generator.hpp:486
std::optional< T > next()
Get the next item from the generator.
Definition generator.hpp:111
generatorIter< T, S > begin() const noexcept override
Begin iterator (start of the range)
Definition generator.hpp:92
generator< T, countedState > limit(long count) noexcept
Limits the number of items that the generator will std::optional.
Definition generator.hpp:317
generator< std::pair< long, T >, std::pair< long, generator< T, S > > > enumerate() noexcept
Enumerate the items in this generator.
Definition generator.hpp:404
array< T > take(int count)
Take a certain number of items from the generator.
Definition generator.hpp:163
generator< std::pair< T, std::optional< T > >, std::pair< std::optional< T >, generator > > peek() noexcept
Allow peeking at the next item in the generator as items are generated.
Definition generator.hpp:532
generator< std::pair< T, U >, generator< U, S2 > > pair(generator< U, S2 > &other) noexcept
Pair items from this generator with those of another generator.
Definition generator.hpp:346
A base interface for all objects that can be iterated over.
Definition iterable.hpp:10
generator< dereference< T >, const_iterator_value< T > > generatorFrom(const T &list)
Create a generator from an arbitrary iterable.
Definition generator.hpp:587
Utility template definitions to allow for simpler type restrictions.