170 lines
2.7 KiB
Plaintext
170 lines
2.7 KiB
Plaintext
module std/list;
|
|
|
|
import std/io;
|
|
import std/heap;
|
|
|
|
|
|
trait Queue<T> : Collection<T> {
|
|
put(item: &T) void;
|
|
take() &T;
|
|
poll() &T?;
|
|
peek() &T?;
|
|
}
|
|
|
|
pub trait Collection<T> {
|
|
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();
|
|
}
|
|
});
|
|
|
|
ret res;
|
|
}
|
|
|
|
all(fn: (&T) -> bool) bool {
|
|
let mut res = true;
|
|
|
|
self.each((item, break) -> {
|
|
if !fn(item) {
|
|
res = false;
|
|
break();
|
|
}
|
|
});
|
|
|
|
ret res;
|
|
}
|
|
|
|
// map<S>(fn: (&T) -> &S) -> Collection<S>;
|
|
// filter(fn: (&T) -> bool) -> Collection<T>;
|
|
}
|
|
|
|
trait Stack<T> : Collection<T> {
|
|
push(item: &T) void;
|
|
pop() &T;
|
|
peek() &T?;
|
|
}
|
|
|
|
pub struct LinkedList<T> {
|
|
pub mut head: &T?;
|
|
pub mut tail: &LinkedList<T>?;
|
|
mut size: u64;
|
|
|
|
init() void {
|
|
self.head = null;
|
|
self.tail = null;
|
|
self.size = 0;
|
|
}
|
|
}
|
|
|
|
impl Collection<T> for LinkedList<T> {
|
|
add(item: &T) void {
|
|
if self.head == null {
|
|
self.head = item;
|
|
self.size = self.size + 1;
|
|
ret;
|
|
}
|
|
|
|
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 {
|
|
ret;
|
|
}
|
|
|
|
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;
|
|
ret;
|
|
}
|
|
|
|
self.tail.remove(item);
|
|
self.size = self.size - 1;
|
|
}
|
|
|
|
contains(item: &T) bool {
|
|
if self.head == null {
|
|
ret false;
|
|
}
|
|
|
|
if self.head == item {
|
|
ret true;
|
|
}
|
|
|
|
ret self.tail.contains(item);
|
|
}
|
|
|
|
size() u64 {
|
|
ret self.size;
|
|
}
|
|
|
|
each(fn: (item: &T, break: () -> void) -> void) void {
|
|
if self.head == null {
|
|
ret;
|
|
}
|
|
|
|
let mut continue = true;
|
|
fn(self.head, () -> continue = false);
|
|
|
|
if continue && self.tail != null {
|
|
self.tail.each(fn);
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Queue<T> for LinkedList<T> {
|
|
put(item: &T) void = self.add(item);
|
|
|
|
take() &T {
|
|
if head == null {
|
|
// TODO: wait for item to be available
|
|
ret null;
|
|
}
|
|
|
|
let item = self.head;
|
|
self.remove(item);
|
|
ret item;
|
|
}
|
|
|
|
poll() &T? {
|
|
if self.head == null {
|
|
ret null;
|
|
}
|
|
|
|
let item = self.head;
|
|
self.remove(item);
|
|
ret item;
|
|
}
|
|
|
|
peek() &T? = self.head;
|
|
}
|