summaryrefslogtreecommitdiff
path: root/libgo/go/container/list/list.go
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /libgo/go/container/list/list.go
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'libgo/go/container/list/list.go')
-rwxr-xr-xlibgo/go/container/list/list.go211
1 files changed, 211 insertions, 0 deletions
diff --git a/libgo/go/container/list/list.go b/libgo/go/container/list/list.go
new file mode 100755
index 000000000..c1ebcddaa
--- /dev/null
+++ b/libgo/go/container/list/list.go
@@ -0,0 +1,211 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The list package implements a doubly linked list.
+//
+// To iterate over a list (where l is a *List):
+// for e := l.Front(); e != nil; e = e.Next() {
+// // do something with e.Value
+// }
+//
+package list
+
+// Element is an element in the linked list.
+type Element struct {
+ // Next and previous pointers in the doubly-linked list of elements.
+ // The front of the list has prev = nil, and the back has next = nil.
+ next, prev *Element
+
+ // The list to which this element belongs.
+ list *List
+
+ // The contents of this list element.
+ Value interface{}
+}
+
+// Next returns the next list element or nil.
+func (e *Element) Next() *Element { return e.next }
+
+// Prev returns the previous list element or nil.
+func (e *Element) Prev() *Element { return e.prev }
+
+// List represents a doubly linked list.
+// The zero value for List is an empty list ready to use.
+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
+}
+
+// New returns an initialized list.
+func New() *List { return new(List) }
+
+// Front returns the first element in the list.
+func (l *List) Front() *Element { return l.front }
+
+// Back returns the last element in the list.
+func (l *List) Back() *Element { return l.back }
+
+// Remove removes the element from the list
+// and returns its Value.
+func (l *List) Remove(e *Element) interface{} {
+ l.remove(e)
+ e.list = nil // do what remove does not
+ return e.Value
+}
+
+// remove the element from the list, but do not clear the Element's list field.
+// This is so that other List methods may use remove when relocating Elements
+// without needing to restore the list field.
+func (l *List) remove(e *Element) {
+ if e.list != l {
+ 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 {
+ // new front of the list
+ 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 {
+ // new back of the list
+ 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 {
+ // empty list
+ 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 {
+ // empty list
+ l.front, l.back = e, e
+ e.prev, e.next = nil, nil
+ l.len = 1
+ return
+ }
+ l.insertAfter(e, l.back)
+}
+
+// PushFront inserts the value at the front of the list and returns a new Element containing the value.
+func (l *List) PushFront(value interface{}) *Element {
+ e := &Element{nil, nil, l, value}
+ l.insertFront(e)
+ return e
+}
+
+// PushBack inserts the value at the back of the list and returns a new Element containing the value.
+func (l *List) PushBack(value interface{}) *Element {
+ e := &Element{nil, nil, l, value}
+ l.insertBack(e)
+ return e
+}
+
+// InsertBefore inserts the value immediately before mark and returns a new Element containing the value.
+func (l *List) InsertBefore(value interface{}, mark *Element) *Element {
+ if mark.list != l {
+ return nil
+ }
+ e := &Element{nil, nil, l, value}
+ l.insertBefore(e, mark)
+ return e
+}
+
+// InsertAfter inserts the value immediately after mark and returns a new Element containing the value.
+func (l *List) InsertAfter(value interface{}, mark *Element) *Element {
+ if mark.list != l {
+ return nil
+ }
+ e := &Element{nil, nil, l, value}
+ l.insertAfter(e, mark)
+ return e
+}
+
+// MoveToFront moves the element to the front of the list.
+func (l *List) MoveToFront(e *Element) {
+ if e.list != l || l.front == e {
+ return
+ }
+ l.remove(e)
+ l.insertFront(e)
+}
+
+// MoveToBack moves the element to the back of the list.
+func (l *List) MoveToBack(e *Element) {
+ if e.list != l || l.back == e {
+ return
+ }
+ l.remove(e)
+ l.insertBack(e)
+}
+
+// Len returns the number of elements in the list.
+func (l *List) Len() int { return l.len }
+
+// PushBackList inserts each element of ol at the back of the list.
+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
+ }
+ }
+}
+
+// PushFrontList inserts each element of ol at the front of the list. The ordering of the passed list is preserved.
+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
+ }
+ }
+}