module test; import stdlib/io; import stdlib/heap; import stdlib/err; trait Collection { add(item: &T) -> void; remove(item: &T) -> void; contains(item: &T) -> bool; size() -> u64; isEmpty() -> bool = self.size() > 0; isNotEmpty() -> bool = self.size() <= 0; each(fn: (item: &T, break: () -> void) -> void) -> void; any(fn: (&T) -> bool) -> bool { let mut res = false; self.each((item, break) -> { if fn(item) { res = true; break(); } }); return res; } all(fn: (&T) -> bool) -> bool { let mut res = true; self.each((item, break) -> { if !fn(item) { res = false; break(); } }); return res; } // map(fn: (&T) -> &S) -> Collection; // filter(fn: (&T) -> bool) -> Collection; } trait Queue : Collection { put(item: &T) -> void; take() -> &T; poll() -> &T?; peek() -> &T?; } trait Stack : Collection { push(item: &T) -> void; pop() -> &T; peek() -> &T?; } struct LinkedList { pub mut head: &T?; pub mut tail: &LinkedList?; mut size: u64; init() -> void { self.head = null; self.tail = null; self.size = 0; } } impl Collection for LinkedList { add(item: &T) -> void { if self.head == null { self.head = item; self.size = self.size + 1; return; } if self.tail == null { self.tail = heap.new(LinkedList); self.tail.init(); } self.tail.add(item); self.size = self.size + 1; } remove(item: &T) -> void { if self.head == null { return; } if self.head == item { let next = self.tail; if next != null { self.head = self.tail.head; self.tail = self.tail.tail; heap.free(next); } else { self.head = null; } self.size = self.size - 1; return; } self.tail.remove(item); self.size = self.size - 1; } contains(item: &T) -> bool { if self.head == null { return false; } if self.head == item { return true; } return self.tail.contains(item); } size() -> u64 { return self.size; } each(fn: (item: &T, break: () -> void) -> void) -> void { if self.head == null { return; } let mut continue = true; fn(self.head, () -> { continue = false; }); if continue && self.tail != null { self.tail.each(fn); } } } impl Queue for LinkedList { put(item: &T) -> void = self.add(item); take() -> &T { if head == null { // TODO: wait for item to be available return null; } let item = self.head; self.remove(item); return item; } poll() -> &T? { if self.head == null { return null; } let item = self.head; self.remove(item); return item; } peek() -> &T? = self.head; }