github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/internal/xlist/list.go (about) 1 // Package xlist is a copy of standard container/list but uses generics 2 // for strict checks on compile time 3 package xlist 4 5 // Element is an element of a linked list. 6 type Element[T any] struct { 7 // Next and previous pointers in the doubly-linked list of elements. 8 // To simplify the implementation, internally a list l is implemented 9 // as a ring, such that &l.root is both the next element of the last 10 // list element (l.Back()) and the previous element of the first list 11 // element (l.Front()). 12 next, prev *Element[T] 13 14 // The list to which this element belongs. 15 list *list[T] 16 17 // The value stored with this element. 18 Value T 19 } 20 21 // Next returns the next list element or nil. 22 func (e *Element[T]) Next() *Element[T] { 23 if p := e.next; e.list != nil && p != &e.list.root { 24 return p 25 } 26 27 return nil 28 } 29 30 // Prev returns the previous list element or nil. 31 func (e *Element[T]) Prev() *Element[T] { 32 if p := e.prev; e.list != nil && p != &e.list.root { 33 return p 34 } 35 36 return nil 37 } 38 39 // List represents a doubly linked list. 40 // The zero value for List is an empty list ready to use. 41 type ( 42 List[T any] interface { 43 // PushBack inserts a new element e with value v at the back of list l and returns e. 44 PushBack(v T) *Element[T] 45 46 // PushBackList inserts a copy of another list at the back of list l. 47 // The lists l and other may be the same. They must not be nil. 48 PushBackList(other List[T]) 49 50 // PushFront inserts a new element e with value v at the front of list l and returns e. 51 PushFront(v T) *Element[T] 52 53 // PushFrontList inserts a copy of another list at the front of list l. 54 // The lists l and other may be the same. They must not be nil. 55 PushFrontList(other List[T]) 56 57 // MoveToFront moves element e to the front of list l. 58 // If e is not an element of l, the list is not modified. 59 // The element must not be nil. 60 MoveToFront(e *Element[T]) 61 62 // MoveToBack moves element e to the back of list l. 63 // If e is not an element of l, the list is not modified. 64 // The element must not be nil. 65 MoveToBack(e *Element[T]) 66 67 // MoveAfter moves element e to its new position after mark. 68 // If e or mark is not an element of l, or e == mark, the list is not modified. 69 // The element and mark must not be nil. 70 MoveAfter(e, mark *Element[T]) 71 72 // MoveBefore moves element e to its new position before mark. 73 // If e or mark is not an element of l, or e == mark, the list is not modified. 74 // The element and mark must not be nil. 75 MoveBefore(e, mark *Element[T]) 76 77 // Remove removes e from l if e is an element of list l. 78 // It returns the element value e.Value. 79 // The element must not be nil. 80 Remove(e *Element[T]) T 81 82 // InsertBefore inserts a new element e with value v immediately before mark and returns e. 83 // If mark is not an element of l, the list is not modified. 84 // The mark must not be nil. 85 InsertBefore(v T, mark *Element[T]) *Element[T] 86 87 // InsertAfter inserts a new element e with value v immediately after mark and returns e. 88 // If mark is not an element of l, the list is not modified. 89 // The mark must not be nil. 90 InsertAfter(v T, mark *Element[T]) *Element[T] 91 92 // Front returns the first element of list l or nil if the list is empty. 93 Front() *Element[T] 94 95 // Back returns the last element of list l or nil if the list is empty. 96 Back() *Element[T] 97 98 // Len returns the number of elements of list l. 99 // The complexity is O(1). 100 Len() int 101 102 // Clear clears the list l. 103 Clear() 104 } 105 list[T any] struct { 106 root Element[T] // sentinel list element, only &root, root.prev, and root.next are used 107 len int // current list length excluding (this) sentinel element 108 } 109 ) 110 111 // Clear clears the list l. 112 func (l *list[T]) Clear() { 113 l.root.next = &l.root 114 l.root.prev = &l.root 115 l.len = 0 116 } 117 118 // New returns an initialized list. 119 func New[T any]() List[T] { 120 l := &list[T]{} 121 l.root.next = &l.root 122 l.root.prev = &l.root 123 l.len = 0 124 125 return l 126 } 127 128 // Len returns the number of elements of list l. 129 // The complexity is O(1). 130 func (l *list[T]) Len() int { return l.len } 131 132 // Front returns the first element of list l or nil if the list is empty. 133 func (l *list[T]) Front() *Element[T] { 134 if l.len == 0 { 135 return nil 136 } 137 138 return l.root.next 139 } 140 141 // Back returns the last element of list l or nil if the list is empty. 142 func (l *list[T]) Back() *Element[T] { 143 if l.len == 0 { 144 return nil 145 } 146 147 return l.root.prev 148 } 149 150 // insert inserts e after at, increments l.len, and returns e. 151 func (l *list[T]) insert(e, at *Element[T]) *Element[T] { 152 e.prev = at 153 e.next = at.next 154 e.prev.next = e 155 e.next.prev = e 156 e.list = l 157 l.len++ 158 159 return e 160 } 161 162 // insertValue is a convenience wrapper for insert(&Element{Value: v}, at). 163 func (l *list[T]) insertValue(v T, at *Element[T]) *Element[T] { 164 return l.insert(&Element[T]{Value: v}, at) 165 } 166 167 // remove removes e from its list, decrements l.len 168 func (l *list[T]) remove(e *Element[T]) { 169 e.prev.next = e.next 170 e.next.prev = e.prev 171 e.next = nil // avoid memory leaks 172 e.prev = nil // avoid memory leaks 173 e.list = nil 174 l.len-- 175 } 176 177 // move moves e to next to at. 178 func (l *list[T]) move(e, at *Element[T]) { 179 if e == at { 180 return 181 } 182 e.prev.next = e.next 183 e.next.prev = e.prev 184 185 e.prev = at 186 e.next = at.next 187 e.prev.next = e 188 e.next.prev = e 189 } 190 191 // Remove removes e from l if e is an element of list l. 192 // It returns the element value e.Value. 193 // The element must not be nil. 194 func (l *list[T]) Remove(e *Element[T]) T { 195 if e.list == l { 196 // if e.list == l, l must have been initialized when e was inserted 197 // in l or l == nil (e is a zero Element) and l.remove will crash 198 l.remove(e) 199 } 200 201 return e.Value 202 } 203 204 // PushFront inserts a new element e with value v at the front of list l and returns e. 205 func (l *list[T]) PushFront(v T) *Element[T] { 206 return l.insertValue(v, &l.root) 207 } 208 209 // PushBack inserts a new element e with value v at the back of list l and returns e. 210 func (l *list[T]) PushBack(v T) *Element[T] { 211 return l.insertValue(v, l.root.prev) 212 } 213 214 // InsertBefore inserts a new element e with value v immediately before mark and returns e. 215 // If mark is not an element of l, the list is not modified. 216 // The mark must not be nil. 217 func (l *list[T]) InsertBefore(v T, mark *Element[T]) *Element[T] { 218 if mark.list != l { 219 return nil 220 } 221 222 // see comment in List.Remove about initialization of l 223 return l.insertValue(v, mark.prev) 224 } 225 226 // InsertAfter inserts a new element e with value v immediately after mark and returns e. 227 // If mark is not an element of l, the list is not modified. 228 // The mark must not be nil. 229 func (l *list[T]) InsertAfter(v T, mark *Element[T]) *Element[T] { 230 if mark.list != l { 231 return nil 232 } 233 234 // see comment in List.Remove about initialization of l 235 return l.insertValue(v, mark) 236 } 237 238 // MoveToFront moves element e to the front of list l. 239 // If e is not an element of l, the list is not modified. 240 // The element must not be nil. 241 func (l *list[T]) MoveToFront(e *Element[T]) { 242 if e.list != l || l.root.next == e { 243 return 244 } 245 // see comment in List.Remove about initialization of l 246 l.move(e, &l.root) 247 } 248 249 // MoveToBack moves element e to the back of list l. 250 // If e is not an element of l, the list is not modified. 251 // The element must not be nil. 252 func (l *list[T]) MoveToBack(e *Element[T]) { 253 if e.list != l || l.root.prev == e { 254 return 255 } 256 // see comment in List.Remove about initialization of l 257 l.move(e, l.root.prev) 258 } 259 260 // MoveBefore moves element e to its new position before mark. 261 // If e or mark is not an element of l, or e == mark, the list is not modified. 262 // The element and mark must not be nil. 263 func (l *list[T]) MoveBefore(e, mark *Element[T]) { 264 if e.list != l || e == mark || mark.list != l { 265 return 266 } 267 l.move(e, mark.prev) 268 } 269 270 // MoveAfter moves element e to its new position after mark. 271 // If e or mark is not an element of l, or e == mark, the list is not modified. 272 // The element and mark must not be nil. 273 func (l *list[T]) MoveAfter(e, mark *Element[T]) { 274 if e.list != l || e == mark || mark.list != l { 275 return 276 } 277 l.move(e, mark) 278 } 279 280 // PushBackList inserts a copy of another list at the back of list l. 281 // The lists l and other may be the same. They must not be nil. 282 func (l *list[T]) PushBackList(other List[T]) { 283 for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() { 284 l.insertValue(e.Value, l.root.prev) 285 } 286 } 287 288 // PushFrontList inserts a copy of another list at the front of list l. 289 // The lists l and other may be the same. They must not be nil. 290 func (l *list[T]) PushFrontList(other List[T]) { 291 for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() { 292 l.insertValue(e.Value, &l.root) 293 } 294 }