// List represents a doubly linked list.
type List struct {
front, back *Element;
+ len int;
}
// Init initializes or clears a List.
func (l *List) Init() *List {
l.front = nil;
l.back = nil;
+ l.len = 0;
return l
}
e.prev = nil;
e.next = nil;
+ l.len--;
}
func (l *List) insertFront(e *Element) {
} else {
l.back = e;
}
+ l.len++;
}
func (l *List) insertBack(e *Element) {
} else {
l.front = e;
}
+ l.len++;
}
// PushFront inserts the value at the front of the list, and returns a new Element containing it.
l.insertBack(e);
}
+// Len returns the number of elements in the list.
+func (l *List) Len() int {
+ return l.len
+}
+
func (l *List) iterate(c chan <- *Element) {
var next *Element;
for e := l.front; e != nil; e = next {
}
}
+func checkListLen(t *testing.T, l *List, n int) {
+ if an := l.Len(); an != n {
+ t.Errorf("l.Len() = %d, want %d", an, n);
+ }
+}
+
func TestList(t *testing.T) {
l := New();
checkListPointers(t, l, []*Element{});
+ checkListLen(t, l, 0);
// Single element list
e := l.PushFront("a");
+ checkListLen(t, l, 1);
checkListPointers(t, l, []*Element{ e });
l.MoveToFront(e);
checkListPointers(t, l, []*Element{ e });
l.MoveToBack(e);
checkListPointers(t, l, []*Element{ e });
+ checkListLen(t, l, 1);
l.Remove(e);
checkListPointers(t, l, []*Element{});
+ checkListLen(t, l, 0);
// Bigger list
e2 := l.PushFront(2);
e3 := l.PushBack(3);
e4 := l.PushBack("banana");
checkListPointers(t, l, []*Element{ e1, e2, e3, e4 });
+ checkListLen(t, l, 4);
l.Remove(e2);
checkListPointers(t, l, []*Element{ e1, e3, e4 });
+ checkListLen(t, l, 3);
l.MoveToFront(e3); // move from middle
checkListPointers(t, l, []*Element{ e3, e1, e4 });
l.Remove(e);
}
checkListPointers(t, l, []*Element{});
+ checkListLen(t, l, 0);
}