feat(util/list): add map_filter template
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
f6bfd11aed
commit
8515821d56
2 changed files with 44 additions and 0 deletions
|
@ -161,6 +161,23 @@ static void tst12() {
|
||||||
lean_assert(sum == 30);
|
lean_assert(sum == 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tst13() {
|
||||||
|
list<int> l({1, 2, 3, 4, 5, 6, 7});
|
||||||
|
list<int> l2 = map_filter(l, [](int in, int & out) {
|
||||||
|
if (in % 2 == 0) {
|
||||||
|
out = in + 10;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
std::cout << l2 << "\n";
|
||||||
|
list<int> l3({12, 14, 16});
|
||||||
|
lean_assert_eq(l2, l3);
|
||||||
|
lean_assert(empty(map_filter(l, [](int, int &) { return false; })));
|
||||||
|
lean_assert(empty(map_filter(list<int>(), [](int in, int & out) { out = in; return true; })));
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
tst1();
|
tst1();
|
||||||
tst2();
|
tst2();
|
||||||
|
@ -174,5 +191,6 @@ int main() {
|
||||||
tst10(1000, 5);
|
tst10(1000, 5);
|
||||||
tst11(1000, 5);
|
tst11(1000, 5);
|
||||||
tst12();
|
tst12();
|
||||||
|
tst13();
|
||||||
return has_violations() ? 1 : 0;
|
return has_violations() ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,6 +156,32 @@ list<T> map(list<T> const & l, F && f) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Similar to \c map but \c f has signature
|
||||||
|
|
||||||
|
<tt>bool f(T const & in, T & out)</tt>
|
||||||
|
|
||||||
|
If \c out becomes part of the result iff \c f returns true.
|
||||||
|
*/
|
||||||
|
template<typename T, typename F>
|
||||||
|
list<T> map_filter(list<T> const & l, F && f) {
|
||||||
|
if (is_nil(l)) {
|
||||||
|
return l;
|
||||||
|
} else {
|
||||||
|
buffer<typename list<T>::cell*> tmp;
|
||||||
|
to_buffer(l, tmp);
|
||||||
|
unsigned i = tmp.size();
|
||||||
|
list<T> r;
|
||||||
|
while (i > 0) {
|
||||||
|
--i;
|
||||||
|
T out;
|
||||||
|
if (f(tmp[i]->head(), out))
|
||||||
|
r = cons(out, r);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Semantically equivalent to \c map, but it tries to reuse
|
\brief Semantically equivalent to \c map, but it tries to reuse
|
||||||
list cells. The elements are compared using the predicate \c eq.
|
list cells. The elements are compared using the predicate \c eq.
|
||||||
|
|
Loading…
Reference in a new issue