package list
type Element struct {
next, prev *Element
id *byte
Value interface{}
}
func (e *Element) Next() *Element { return e.next }
func (e *Element) Prev() *Element { return e.prev }
type List struct {
front, back *Element
len int
id *byte
}
func (l *List) Init() *List {
l.front = nil
l.back = nil
l.len = 0
l.id = new(byte)
return l
}
func New() *List { return new(List).Init() }
func (l *List) Front() *Element { return l.front }
func (l *List) Back() *Element { return l.back }
func (l *List) Remove(e *Element) {
if e.id != l.id {
return
}
if e.prev == nil {
l.front = e.next
} else {
e.prev.next = e.next
}
if e.next == nil {
l.back = e.prev
} else {
e.next.prev = e.prev
}
e.prev = nil
e.next = nil
l.len--
}
func (l *List) insertBefore(e *Element, mark *Element) {
if mark.prev == nil {
l.front = e
} else {
mark.prev.next = e
}
e.prev = mark.prev
mark.prev = e
e.next = mark
l.len++
}
func (l *List) insertAfter(e *Element, mark *Element) {
if mark.next == nil {
l.back = e
} else {
mark.next.prev = e
}
e.next = mark.next
mark.next = e
e.prev = mark
l.len++
}
func (l *List) insertFront(e *Element) {
if l.front == nil {
l.front, l.back = e, e
e.prev, e.next = nil, nil
l.len = 1
return
}
l.insertBefore(e, l.front)
}
func (l *List) insertBack(e *Element) {
if l.back == nil {
l.front, l.back = e, e
e.prev, e.next = nil, nil
l.len = 1
return
}
l.insertAfter(e, l.back)
}
func (l *List) PushFront(value interface{}) *Element {
if l.id == nil {
l.Init()
}
e := &Element{nil, nil, l.id, value}
l.insertFront(e)
return e
}
func (l *List) PushBack(value interface{}) *Element {
if l.id == nil {
l.Init()
}
e := &Element{nil, nil, l.id, value}
l.insertBack(e)
return e
}
func (l *List) InsertBefore(value interface{}, mark *Element) *Element {
if mark.id != l.id {
return nil
}
e := &Element{nil, nil, l.id, value}
l.insertBefore(e, mark)
return e
}
func (l *List) InsertAfter(value interface{}, mark *Element) *Element {
if mark.id != l.id {
return nil
}
e := &Element{nil, nil, l.id, value}
l.insertAfter(e, mark)
return e
}
func (l *List) MoveToFront(e *Element) {
if e.id != l.id || l.front == e {
return
}
l.Remove(e)
l.insertFront(e)
}
func (l *List) MoveToBack(e *Element) {
if e.id != l.id || l.back == e {
return
}
l.Remove(e)
l.insertBack(e)
}
func (l *List) Len() int { return l.len }
func (l *List) iterate(c chan<- interface{}) {
for e := l.front; e != nil; e = e.next {
c <- e.Value
}
close(c)
}
func (l *List) Iter() <-chan interface{} {
c := make(chan interface{})
go l.iterate(c)
return c
}
func (l *List) PushBackList(ol *List) {
last := ol.Back()
for e := ol.Front(); e != nil; e = e.Next() {
l.PushBack(e.Value)
if e == last {
break
}
}
}
func (l *List) PushFrontList(ol *List) {
first := ol.Front()
for e := ol.Back(); e != nil; e = e.Prev() {
l.PushFront(e.Value)
if e == first {
break
}
}
}