feat(util/list): add remove_last template

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2013-12-14 23:08:10 -08:00
parent 1b1032eb99
commit 5aa9264091
2 changed files with 35 additions and 0 deletions

View file

@ -218,6 +218,16 @@ static void tst17() {
lean_assert(is_eqp(tail(tail(l)), tail(l2)));
}
static void tst18() {
list<int> l({1, 2, 3, 4, 5});
lean_assert_eq(remove_last(l, [](int v) { return v % 2 == 0; }), list<int>({1, 2, 3, 5}));
lean_assert_eq(remove_last(l, [](int v) { return v < 0; }), l);
lean_assert(is_eqp(remove_last(l, [](int v) { return v < 0; }), l));
list<int> l2 = remove_last(l, [](int v) { return v < 3; });
lean_assert_eq(l2, list<int>({1, 3, 4, 5}));
lean_assert(is_eqp(tail(tail(l)), tail(l2)));
}
int main() {
tst1();
tst2();
@ -236,5 +246,6 @@ int main() {
tst15();
tst16();
tst17();
tst18();
return has_violations() ? 1 : 0;
}

View file

@ -184,6 +184,30 @@ list<T> filter(list<T> const & l, P && p) {
}
}
/**
\brief Remove the last element that satisfies \c p.
*/
template<typename T, typename P>
list<T> remove_last(list<T> const & l, P && p) {
if (!is_nil(l)) {
buffer<typename list<T>::cell*> tmp;
to_buffer(l, tmp);
unsigned i = tmp.size();
while (i > 0) {
--i;
if (p(tmp[i]->head())) {
list<T> r = tmp[i]->tail();
while (i > 0) {
--i;
r = cons(tmp[i]->head(), r);
}
return r;
}
}
}
return l;
}
/**
\brief Similar to \c map but \c f has signature