/* list.cpp * Date: 2021-11-20 * Author: Aryadev Chavali */ #include #include #include template struct List { T value; struct List *next; ~List() { if (next == nullptr) return; delete next; } }; template List *append(List *lst, T value) { List *node; if (lst == nullptr) { node = new List; node->value = value; node->next = nullptr; return node; } for (node = lst; node->next != nullptr; node = node->next) continue; node->next = new List; node->next->value = value; node->next->next = nullptr; return lst; } /** Reverse a list */ template List *reverse(List *lst, List *prev = nullptr) { auto next = lst->next; lst->next = prev; if (next == nullptr) return lst; return reverse(next, lst); } template void map(List *lst, U (*f)(T)) { if (!lst) return; lst->value = f(lst->value); map(lst->next, f); } template T reduce(List *lst, T (*reducer) (T, T), T init = 0) { if (!lst) return init; if (!init) init = lst->value; else init = reducer(init, lst->value); return reduce(lst->next, reducer, init); } template List *filter(List *lst, bool (*f)(T), List *new_lst = nullptr) { if (!lst) return new_lst; if (f(lst->value)) new_lst = append(new_lst, lst->value); return filter(lst->next, f, new_lst); } template std::ostream& operator<<(std::ostream& ostream, const List *lst) { if (!lst) return ostream; ostream << "|" << lst->value << lst->next; return ostream; } int main(void) { auto lst = append(nullptr, 1); for (int i = 2; i < 10; ++i) lst = append(lst, i); std::cout << lst << std::endl; lst = reverse(lst); std::cout << lst << std::endl; map(lst = reverse(lst), [](int x){ return x * 2; }); std::cout << lst << std::endl; std::cout << reduce(lst, [](int a, int b) { return a + b; }, 0) << std::endl; delete lst; return 0; }