feat(util/list): add map2 for list<T1> -> list<T2>, where T1 and T2 may be different, we still keep map because compiler can automatically infer all template arguments, this is not the case for map2

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-05-17 19:18:18 -07:00
parent f818c1a63e
commit 4325b126d4

View file

@ -137,17 +137,17 @@ list<T> append(list<T> const & l1, list<T> const & l2) {
/**
\brief Given list <tt>(a_0, ..., a_k)</tt>, return list <tt>(f(a_0), ..., f(a_k))</tt>.
*/
template<typename T, typename F>
list<T> map(list<T> const & l, F && f) {
static_assert(std::is_same<typename std::result_of<F(T const &)>::type, T>::value,
template<typename To, typename From, typename F>
list<To> map2(list<From> const & l, F && f) {
static_assert(std::is_same<typename std::result_of<F(From const &)>::type, To>::value,
"map: return type of f is not equal to input type");
if (is_nil(l)) {
return l;
return list<To>();
} else {
buffer<typename list<T>::cell*> tmp;
buffer<typename list<From>::cell*> tmp;
to_buffer(l, tmp);
unsigned i = tmp.size();
list<T> r;
list<To> r;
while (i > 0) {
--i;
r = cons(f(tmp[i]->head()), r);
@ -156,6 +156,14 @@ list<T> map(list<T> const & l, F && f) {
}
}
/**
\brief Given list <tt>(a_0, ..., a_k)</tt>, return list <tt>(f(a_0), ..., f(a_k))</tt>.
*/
template<typename T, typename F>
list<T> map(list<T> const & l, F && f) {
return map2<T, T, F>(l, std::move(f));
}
/**
\brief Filter/Remove elements from the list
that do not satisfy the given predicate.