-
Notifications
You must be signed in to change notification settings - Fork 77
/
ulist_iter.go
82 lines (74 loc) · 2 KB
/
ulist_iter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package ulist
import (
"github.com/zyedidia/generic/list"
)
// A UListIter points to an element in the UList.
type UListIter[V any] struct {
node *list.Node[ulistBlk[V]]
index int
}
// newIterFront returns a UListIter pointing to the first entry in 'ul'.
// If 'ul' is empty, an invalid iterator is returned.
func newIterFront[V any](ul *UList[V]) *UListIter[V] {
return &UListIter[V]{
node: ul.ll.Front,
index: 0,
}
}
// newIterBack returns a UListIter pointing to the last entry in 'ul'.
// If 'ul' is empty, an invalid iterator is returned.
func newIterBack[V any](ul *UList[V]) *UListIter[V] {
iter := UListIter[V]{
node: ul.ll.Back,
index: 0,
}
if iter.node != nil {
blk := iter.node.Value
iter.index = len(blk) - 1
}
return &iter
}
// IsValid returns true if the iterator points to a valid entry in the UList.
func (iter *UListIter[V]) IsValid() bool {
if iter.node == nil {
return false
}
blk := iter.node.Value
return iter.index >= 0 && iter.index < len(blk)
}
// Get returns the entry in the UList that the 'iter' is pointing to.
// This call should only ever be made when iter.IsValid() is true.
func (iter *UListIter[V]) Get() V {
blk := iter.node.Value
return blk[iter.index]
}
// Next moves the iterator one step forward and returns true if the iterator is valid.
func (iter *UListIter[V]) Next() bool {
iter.index++
blk := iter.node.Value
if iter.index >= len(blk) {
if iter.node.Next != nil {
iter.node = iter.node.Next
iter.index = 0
} else {
// By not going past len, we can recover to the end using Prev().
iter.index = len(blk)
}
}
return iter.IsValid()
}
// Prev moves the iterator one step back and returns true if the iterator is valid.
func (iter *UListIter[V]) Prev() bool {
iter.index--
if iter.index < 0 {
if iter.node.Prev != nil {
iter.node = iter.node.Prev
blk := iter.node.Value
iter.index = len(blk) - 1
} else {
// By not going further past -1, we can recover to the begin using Next().
iter.index = -1
}
}
return iter.IsValid()
}