github.com/15mga/kiwi@v0.0.2-0.20240324021231-b95d5c3ac751/ds/link.go (about) 1 package ds 2 3 import ( 4 "github.com/15mga/kiwi/util" 5 ) 6 7 func NewLink[T any]() *Link[T] { 8 return &Link[T]{} 9 } 10 11 type Link[T any] struct { 12 head *LinkElem[T] 13 tail *LinkElem[T] 14 count uint32 15 } 16 17 func (l *Link[T]) Count() uint32 { 18 return l.count 19 } 20 21 func (l *Link[T]) Head() (T, bool) { 22 if l.count == 0 { 23 return util.Default[T](), false 24 } 25 return l.head.Value, true 26 } 27 28 func (l *Link[T]) Tail() (T, bool) { 29 if l.tail == nil { 30 return util.Default[T](), false 31 } 32 return l.tail.Value, true 33 } 34 35 func (l *Link[T]) Push(a T) { 36 e := &LinkElem[T]{ 37 Value: a, 38 } 39 if l.count == 0 { 40 l.head = e 41 } else { 42 l.tail.Next = e 43 } 44 l.tail = e 45 l.count++ 46 } 47 48 func (l *Link[T]) Pop() (T, bool) { 49 if l.count == 0 { 50 return util.Default[T](), false 51 } 52 e := l.head.Value 53 l.head = l.head.Next 54 l.count-- 55 if l.count == 0 { 56 l.tail = nil 57 } 58 return e, true 59 } 60 61 func (l *Link[T]) Insert(a T, fn func(T) bool) { 62 ne := &LinkElem[T]{ 63 Value: a, 64 } 65 l.count++ 66 if l.count == 0 { 67 l.head = ne 68 l.tail = ne 69 return 70 } 71 var ( 72 pe, ce *LinkElem[T] 73 ) 74 for ce = l.head; ce != nil; ce = ce.Next { 75 if fn(ce.Value) { 76 break 77 } 78 pe = ce 79 } 80 switch { 81 case ce == l.head: 82 ne.Next = ce 83 l.head = ne 84 case ce == nil: 85 l.tail.Next = ne 86 l.tail = ne 87 default: 88 pe.Next = ne 89 ne.Next = ce 90 } 91 } 92 93 func (l *Link[T]) Iter(fn func(T)) { 94 for e := l.head; e != nil; e = e.Next { 95 fn(e.Value) 96 } 97 } 98 99 func (l *Link[T]) Any(fn func(T) bool) bool { 100 for e := l.head; e != nil; e = e.Next { 101 if fn(e.Value) { 102 return true 103 } 104 } 105 return false 106 } 107 108 func (l *Link[T]) Del(fn func(T) bool) bool { 109 if l.count == 0 { 110 return false 111 } 112 if fn(l.head.Value) { 113 l.head = l.head.Next 114 return true 115 } 116 p := l.head 117 for p.Next != nil { 118 if fn(p.Next.Value) { 119 p.Next = p.Next.Next 120 return true 121 } 122 } 123 return false 124 } 125 126 func (l *Link[T]) Values(values *[]T) bool { 127 if l.count == 0 { 128 return false 129 } 130 l.Iter(func(v T) { 131 *values = append(*values, v) 132 }) 133 return true 134 } 135 136 func (l *Link[T]) Dispose() { 137 l.head = nil 138 l.tail = nil 139 l.count = 0 140 } 141 142 func (l *Link[T]) PopAll() *LinkElem[T] { 143 head := l.head 144 l.head = nil 145 l.tail = nil 146 l.count = 0 147 return head 148 } 149 150 func (l *Link[T]) Copy(lnk *Link[T]) { 151 lnk.head = l.head 152 lnk.tail = l.tail 153 lnk.count = l.count 154 } 155 156 func (l *Link[T]) PushLink(lnk *Link[T]) { 157 if lnk.count == 0 { 158 return 159 } 160 if l.tail == nil { 161 l.head = lnk.head 162 l.tail = lnk.tail 163 l.count = lnk.count 164 return 165 } 166 l.tail.Next = lnk.head 167 l.tail = lnk.tail 168 l.count += lnk.count 169 } 170 171 type LinkElem[T any] struct { 172 Next *LinkElem[T] 173 Value T 174 }