6 #include <initializer_list>
17 Item(T v, std::shared_ptr<const Item> tail)
18 : _val(v), _next(std::move(tail))
21 explicit Item(T v) : _val(v) {}
24 std::shared_ptr<const Item> _next;
27 explicit List(std::shared_ptr<const Item> items)
28 : _head(std::move(items)) {}
34 : _head(std::make_shared<Item>(v, tail._head)) {}
36 explicit List(T v) : _head(std::make_shared<Item>(v)) {}
38 bool isEmpty()
const {
return !_head; }
44 List popped_front()
const
47 return List(_head->_next);
50 List pushed_front(T v)
const
52 return List(v, *
this);
56 if (n <= 0 || isEmpty())
return List();
57 return popped_front().take(n - 1).pushed_front(front());
59 List insertedAt(
int i, T v)
const
62 return pushed_front(v);
65 return List<T>(front(), popped_front().insertedAt(i - 1, v));
68 List removed(T v)
const
70 if (isEmpty())
return List();
72 return popped_front().removed(v);
73 return List(front(), popped_front().removed(v));
75 List removed1(T v)
const
77 if (isEmpty())
return List();
79 return popped_front();
80 return List(front(), popped_front().removed(v));
82 bool member(T v)
const
84 if (isEmpty())
return false;
85 if (v == front())
return true;
86 return popped_front().member(v);
89 void forEach(F f)
const
91 Item
const * it = _head.get();
101 int headCount()
const {
return _head.use_count(); }
103 std::shared_ptr<const Item> _head;
106 template<
class T,
class P>
107 bool all(
List<T> const & lst, P & p)
113 return all(lst.popped_front(), p);
117 class FwdListIter :
public std::iterator<std::forward_iterator_tag, T>
123 T operator*()
const {
return _cur->_val; }
131 return _cur == other._cur;
135 return !(*
this == other);
138 std::shared_ptr<const typename List<T>::Item> _cur;
142 class OutListIter :
public std::iterator<std::output_iterator_tag, T>
146 T & operator*() {
return _val; }
152 List<T> getList()
const {
return _lst; }
178 return List<T>(a.front(), concat(a.popped_front(), b));
181 template<
class T,
class F>
182 auto fmap(F f,
List<T> lst) ->
List<decltype(f(lst.front()))>
184 using U = decltype(f(lst.front()));
185 static_assert(std::is_convertible<F, std::function<U(T)>>::value,
186 "fmap requires a function type U(T)");
190 return List<U>(f(lst.front()), fmap(f, lst.popped_front()));
193 template<
class T,
class P>
196 static_assert(std::is_convertible<P, std::function<
bool(T)>>::value,
197 "filter requires a function type bool(T)");
201 return List<T>(lst.front(), filter(p, lst.popped_front()));
203 return filter(p, lst.popped_front());
206 template<
class T,
class U,
class F>
207 U foldr(F f, U acc,
List<T> lst)
209 static_assert(std::is_convertible<F, std::function<U(T, U)>>::value,
210 "foldr requires a function type U(T, U)");
214 return f(lst.front(), foldr(f, acc, lst.popped_front()));
217 template<
class T,
class U,
class F>
218 U foldl(F f, U acc,
List<T> lst)
220 static_assert(std::is_convertible<F, std::function<U(U, T)>>::value,
221 "foldl requires a function type U(U, T)");
225 return foldl(f, f(acc, lst.front()), lst.popped_front());
232 return foldl([](
List<T> const & acc, T x) {
233 return acc.removed(x);
244 auto trimmed = foldl([](
List<T> const & acc, T x) {
245 return acc.removed(x);
247 return concat(trimmed, xs);
253 if (xss.isEmpty())
return List<T>();
254 return concat(xss.front(), concatAll(xss.popped_front()));
260 template<
class T,
class F>
263 static_assert(std::is_convertible<F, std::function<
void(T)>>::value,
264 "forEach requires a function type void(T)");
265 while (!lst.isEmpty()) {
267 lst = lst.popped_front();
271 template<
class Beg,
class End>
274 typedef typename Beg::value_type T;
278 return List<T>(item, fromIt(++it, end));
281 template<
class T,
class F>
282 List<T> iterateN(F f, T init,
int count)
284 if (count <= 0)
return List<T>();
285 return iterateN(f, f(init), count - 1).pushed_front(init);
293 std::cout << std::endl;
295 std::cout <<
"(" << lst.front() <<
", " << lst.headCount() - 1 <<
") ";
296 printRaw(lst.popped_front());
301 std::ostream& operator<<(std::ostream& os,
List<T> const & lst)
304 forEach(lst, [&os](T v) {
314 return foldl([](
List<T> const & acc, T v)