-
Notifications
You must be signed in to change notification settings - Fork 0
/
lq+.hh
92 lines (84 loc) · 2.53 KB
/
lq+.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <vector>
#include <functional>
#include <iostream>
#include <memory>
namespace lq {
template<typename T>
class enumerable {
std::function<bool()> next_func;
std::function<T()> current_func;
public:
bool next() {
return next_func();
}
T current() {
return current_func();
}
enumerable(std::function<bool()> next_func, std::function<T()> current_func)
: next_func(next_func), current_func(current_func)
{ }
class iterator {
bool end_iterator;
bool ended;
enumerable<T>& e;
public:
iterator(enumerable<T>& e, bool end_iterator = false) : e(e), ended(false), end_iterator(end_iterator) { }
iterator& operator++() {
if(!ended) {
ended = !e.next();
}
return *this;
}
T operator*() const {
return e.current();
}
bool operator==(iterator& iter) {
if(iter.end_iterator) {
return ended;
} else {
return false;
}
}
bool operator!=(iterator& iter) {
return !(*this == iter);
}
};
iterator begin() {
return iterator(*this);
}
iterator end() {
return iterator(*this, true);
}
template<typename U>
enumerable<T> where(U pred) {
return enumerable<T>([this, pred]() -> bool {
if(!next()) return false;
while(!pred(current())) {
if(!next()) return false;
}
return true;
}, [this]() {
return current();
});
}
};
template<typename U>
struct _lambda_params {
U xs;
typename U::iterator iter;
_lambda_params(U xs, typename U::iterator iter) : xs(xs), iter(iter) { }
};
template<typename T, typename U>
enumerable<T> _from_iterable(U xs) {
auto t = std::shared_ptr<_lambda_params<U> >(new _lambda_params<U>(xs, xs.begin()));
return enumerable<T>([t]() -> bool {
return ++(t->iter) != t->xs.end();
}, [t]() -> T {
return *t->iter;
});
}
template<typename T>
enumerable<T> from(std::initializer_list<T> xs) {
return _from_iterable<T>(xs);
}
};