~ubuntu-branches/ubuntu/saucy/golang/saucy

« back to all changes in this revision

Viewing changes to src/pkg/container/list/list.go

  • Committer: Package Import Robot
  • Author(s): Adam Conrad
  • Date: 2013-07-08 05:52:37 UTC
  • mfrom: (29.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20130708055237-at01839e0hp8z3ni
Tags: 2:1.1-1ubuntu1
016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
//
12
12
package list
13
13
 
14
 
// Element is an element in the linked list.
 
14
// Element is an element of a linked list.
15
15
type Element struct {
16
16
        // Next and previous pointers in the doubly-linked list of elements.
17
 
        // The front of the list has prev = nil, and the back has next = nil.
 
17
        // To simplify the implementation, internally a list l is implemented
 
18
        // as a ring, such that &l.root is both the next element of the last
 
19
        // list element (l.Back()) and the previous element of the first list
 
20
        // element (l.Front()).
18
21
        next, prev *Element
19
22
 
20
23
        // The list to which this element belongs.
21
24
        list *List
22
25
 
23
 
        // The contents of this list element.
 
26
        // The value stored with this element.
24
27
        Value interface{}
25
28
}
26
29
 
27
30
// Next returns the next list element or nil.
28
 
func (e *Element) Next() *Element { return e.next }
 
31
func (e *Element) Next() *Element {
 
32
        if p := e.next; p != &e.list.root {
 
33
                return p
 
34
        }
 
35
        return nil
 
36
}
29
37
 
30
38
// Prev returns the previous list element or nil.
31
 
func (e *Element) Prev() *Element { return e.prev }
 
39
func (e *Element) Prev() *Element {
 
40
        if p := e.prev; p != &e.list.root {
 
41
                return p
 
42
        }
 
43
        return nil
 
44
}
32
45
 
33
46
// List represents a doubly linked list.
34
47
// The zero value for List is an empty list ready to use.
35
48
type List struct {
36
 
        front, back *Element
37
 
        len         int
 
49
        root Element // sentinel list element, only &root, root.prev, and root.next are used
 
50
        len  int     // current list length excluding (this) sentinel element
38
51
}
39
52
 
40
 
// Init initializes or clears a List.
 
53
// Init initializes or clears list l.
41
54
func (l *List) Init() *List {
42
 
        l.front = nil
43
 
        l.back = nil
 
55
        l.root.next = &l.root
 
56
        l.root.prev = &l.root
44
57
        l.len = 0
45
58
        return l
46
59
}
47
60
 
48
61
// New returns an initialized list.
49
 
func New() *List { return new(List) }
50
 
 
51
 
// Front returns the first element in the list.
52
 
func (l *List) Front() *Element { return l.front }
53
 
 
54
 
// Back returns the last element in the list.
55
 
func (l *List) Back() *Element { return l.back }
56
 
 
57
 
// Remove removes the element from the list
58
 
// and returns its Value.
 
62
func New() *List { return new(List).Init() }
 
63
 
 
64
// Len returns the number of elements of list l.
 
65
func (l *List) Len() int { return l.len }
 
66
 
 
67
// Front returns the first element of list l or nil
 
68
func (l *List) Front() *Element {
 
69
        if l.len == 0 {
 
70
                return nil
 
71
        }
 
72
        return l.root.next
 
73
}
 
74
 
 
75
// Back returns the last element of list l or nil.
 
76
func (l *List) Back() *Element {
 
77
        if l.len == 0 {
 
78
                return nil
 
79
        }
 
80
        return l.root.prev
 
81
}
 
82
 
 
83
// lazyInit lazily initializes a zero List value.
 
84
func (l *List) lazyInit() {
 
85
        if l.root.next == nil {
 
86
                l.Init()
 
87
        }
 
88
}
 
89
 
 
90
// insert inserts e after at, increments l.len, and returns e.
 
91
func (l *List) insert(e, at *Element) *Element {
 
92
        n := at.next
 
93
        at.next = e
 
94
        e.prev = at
 
95
        e.next = n
 
96
        n.prev = e
 
97
        e.list = l
 
98
        l.len++
 
99
        return e
 
100
}
 
101
 
 
102
// insertValue is a convenience wrapper for insert(&Element{Value: v}, at).
 
103
func (l *List) insertValue(v interface{}, at *Element) *Element {
 
104
        return l.insert(&Element{Value: v}, at)
 
105
}
 
106
 
 
107
// remove removes e from its list, decrements l.len, and returns e.
 
108
func (l *List) remove(e *Element) *Element {
 
109
        e.prev.next = e.next
 
110
        e.next.prev = e.prev
 
111
        e.next = nil // avoid memory leaks
 
112
        e.prev = nil // avoid memory leaks
 
113
        e.list = nil
 
114
        l.len--
 
115
        return e
 
116
}
 
117
 
 
118
// Remove removes e from l if e is an element of list l.
 
119
// It returns the element value e.Value.
59
120
func (l *List) Remove(e *Element) interface{} {
60
 
        l.remove(e)
61
 
        e.list = nil // do what remove does not
 
121
        if e.list == l {
 
122
                // if e.list == l, l must have been initialized when e was inserted
 
123
                // in l or l == nil (e is a zero Element) and l.remove will crash
 
124
                l.remove(e)
 
125
        }
62
126
        return e.Value
63
127
}
64
128
 
65
 
// remove the element from the list, but do not clear the Element's list field.
66
 
// This is so that other List methods may use remove when relocating Elements
67
 
// without needing to restore the list field.
68
 
func (l *List) remove(e *Element) {
69
 
        if e.list != l {
70
 
                return
71
 
        }
72
 
        if e.prev == nil {
73
 
                l.front = e.next
74
 
        } else {
75
 
                e.prev.next = e.next
76
 
        }
77
 
        if e.next == nil {
78
 
                l.back = e.prev
79
 
        } else {
80
 
                e.next.prev = e.prev
81
 
        }
82
 
 
83
 
        e.prev = nil
84
 
        e.next = nil
85
 
        l.len--
86
 
}
87
 
 
88
 
func (l *List) insertBefore(e *Element, mark *Element) {
89
 
        if mark.prev == nil {
90
 
                // new front of the list
91
 
                l.front = e
92
 
        } else {
93
 
                mark.prev.next = e
94
 
        }
95
 
        e.prev = mark.prev
96
 
        mark.prev = e
97
 
        e.next = mark
98
 
        l.len++
99
 
}
100
 
 
101
 
func (l *List) insertAfter(e *Element, mark *Element) {
102
 
        if mark.next == nil {
103
 
                // new back of the list
104
 
                l.back = e
105
 
        } else {
106
 
                mark.next.prev = e
107
 
        }
108
 
        e.next = mark.next
109
 
        mark.next = e
110
 
        e.prev = mark
111
 
        l.len++
112
 
}
113
 
 
114
 
func (l *List) insertFront(e *Element) {
115
 
        if l.front == nil {
116
 
                // empty list
117
 
                l.front, l.back = e, e
118
 
                e.prev, e.next = nil, nil
119
 
                l.len = 1
120
 
                return
121
 
        }
122
 
        l.insertBefore(e, l.front)
123
 
}
124
 
 
125
 
func (l *List) insertBack(e *Element) {
126
 
        if l.back == nil {
127
 
                // empty list
128
 
                l.front, l.back = e, e
129
 
                e.prev, e.next = nil, nil
130
 
                l.len = 1
131
 
                return
132
 
        }
133
 
        l.insertAfter(e, l.back)
134
 
}
135
 
 
136
 
// PushFront inserts the value at the front of the list and returns a new Element containing the value.
137
 
func (l *List) PushFront(value interface{}) *Element {
138
 
        e := &Element{nil, nil, l, value}
139
 
        l.insertFront(e)
140
 
        return e
141
 
}
142
 
 
143
 
// PushBack inserts the value at the back of the list and returns a new Element containing the value.
144
 
func (l *List) PushBack(value interface{}) *Element {
145
 
        e := &Element{nil, nil, l, value}
146
 
        l.insertBack(e)
147
 
        return e
148
 
}
149
 
 
150
 
// InsertBefore inserts the value immediately before mark and returns a new Element containing the value.
151
 
func (l *List) InsertBefore(value interface{}, mark *Element) *Element {
152
 
        if mark.list != l {
153
 
                return nil
154
 
        }
155
 
        e := &Element{nil, nil, l, value}
156
 
        l.insertBefore(e, mark)
157
 
        return e
158
 
}
159
 
 
160
 
// InsertAfter inserts the value immediately after mark and returns a new Element containing the value.
161
 
func (l *List) InsertAfter(value interface{}, mark *Element) *Element {
162
 
        if mark.list != l {
163
 
                return nil
164
 
        }
165
 
        e := &Element{nil, nil, l, value}
166
 
        l.insertAfter(e, mark)
167
 
        return e
168
 
}
169
 
 
170
 
// MoveToFront moves the element to the front of the list.
 
129
// Pushfront inserts a new element e with value v at the front of list l and returns e.
 
130
func (l *List) PushFront(v interface{}) *Element {
 
131
        l.lazyInit()
 
132
        return l.insertValue(v, &l.root)
 
133
}
 
134
 
 
135
// PushBack inserts a new element e with value v at the back of list l and returns e.
 
136
func (l *List) PushBack(v interface{}) *Element {
 
137
        l.lazyInit()
 
138
        return l.insertValue(v, l.root.prev)
 
139
}
 
140
 
 
141
// InsertBefore inserts a new element e with value v immediately before mark and returns e.
 
142
// If mark is not an element of l, the list is not modified.
 
143
func (l *List) InsertBefore(v interface{}, mark *Element) *Element {
 
144
        if mark.list != l {
 
145
                return nil
 
146
        }
 
147
        // see comment in List.Remove about initialization of l
 
148
        return l.insertValue(v, mark.prev)
 
149
}
 
150
 
 
151
// InsertAfter inserts a new element e with value v immediately after mark and returns e.
 
152
// If mark is not an element of l, the list is not modified.
 
153
func (l *List) InsertAfter(v interface{}, mark *Element) *Element {
 
154
        if mark.list != l {
 
155
                return nil
 
156
        }
 
157
        // see comment in List.Remove about initialization of l
 
158
        return l.insertValue(v, mark)
 
159
}
 
160
 
 
161
// MoveToFront moves element e to the front of list l.
 
162
// If e is not an element of l, the list is not modified.
171
163
func (l *List) MoveToFront(e *Element) {
172
 
        if e.list != l || l.front == e {
 
164
        if e.list != l || l.root.next == e {
173
165
                return
174
166
        }
175
 
        l.remove(e)
176
 
        l.insertFront(e)
 
167
        // see comment in List.Remove about initialization of l
 
168
        l.insert(l.remove(e), &l.root)
177
169
}
178
170
 
179
 
// MoveToBack moves the element to the back of the list.
 
171
// MoveToBack moves element e to the back of list l.
 
172
// If e is not an element of l, the list is not modified.
180
173
func (l *List) MoveToBack(e *Element) {
181
 
        if e.list != l || l.back == e {
 
174
        if e.list != l || l.root.prev == e {
182
175
                return
183
176
        }
184
 
        l.remove(e)
185
 
        l.insertBack(e)
 
177
        // see comment in List.Remove about initialization of l
 
178
        l.insert(l.remove(e), l.root.prev)
186
179
}
187
180
 
188
 
// Len returns the number of elements in the list.
189
 
func (l *List) Len() int { return l.len }
190
 
 
191
 
// PushBackList inserts each element of ol at the back of the list.
192
 
func (l *List) PushBackList(ol *List) {
193
 
        last := ol.Back()
194
 
        for e := ol.Front(); e != nil; e = e.Next() {
195
 
                l.PushBack(e.Value)
196
 
                if e == last {
197
 
                        break
198
 
                }
 
181
// PushBackList inserts a copy of an other list at the back of list l.
 
182
// The lists l and other may be the same.
 
183
func (l *List) PushBackList(other *List) {
 
184
        l.lazyInit()
 
185
        for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() {
 
186
                l.insertValue(e.Value, l.root.prev)
199
187
        }
200
188
}
201
189
 
202
 
// PushFrontList inserts each element of ol at the front of the list. The ordering of the passed list is preserved.
203
 
func (l *List) PushFrontList(ol *List) {
204
 
        first := ol.Front()
205
 
        for e := ol.Back(); e != nil; e = e.Prev() {
206
 
                l.PushFront(e.Value)
207
 
                if e == first {
208
 
                        break
209
 
                }
 
190
// PushFrontList inserts a copy of an other list at the front of list l.
 
191
// The lists l and other may be the same.
 
192
func (l *List) PushFrontList(other *List) {
 
193
        l.lazyInit()
 
194
        for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() {
 
195
                l.insertValue(e.Value, &l.root)
210
196
        }
211
197
}