mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-06-26 20:29:03 +03:00
165 lines
2.8 KiB
Go
165 lines
2.8 KiB
Go
// 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.
|
|
|
|
package list
|
|
|
|
// Element is an element of a linked list.
|
|
type Element[T any] struct {
|
|
next, prev *Element[T]
|
|
list *List[T]
|
|
Value T
|
|
}
|
|
|
|
func (e *Element[T]) Next() *Element[T] {
|
|
if p := e.next; e.list != nil && p != &e.list.root {
|
|
return p
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (e *Element[T]) Prev() *Element[T] {
|
|
if p := e.prev; e.list != nil && p != &e.list.root {
|
|
return p
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (e *Element[T]) Remove() bool {
|
|
if e.list == nil {
|
|
return false
|
|
}
|
|
e.list.remove(e)
|
|
return true
|
|
}
|
|
|
|
type List[T any] struct {
|
|
root Element[T]
|
|
len int
|
|
}
|
|
|
|
func (l *List[T]) Init() *List[T] {
|
|
l.root.next = &l.root
|
|
l.root.prev = &l.root
|
|
l.len = 0
|
|
return l
|
|
}
|
|
|
|
func New[T any]() *List[T] { return new(List[T]).Init() }
|
|
|
|
func (l *List[T]) Len() int { return l.len }
|
|
|
|
func (l *List[T]) Front() *Element[T] {
|
|
if l.len == 0 {
|
|
return nil
|
|
}
|
|
return l.root.next
|
|
}
|
|
|
|
func (l *List[T]) Back() *Element[T] {
|
|
if l.len == 0 {
|
|
return nil
|
|
}
|
|
return l.root.prev
|
|
}
|
|
|
|
func (l *List[T]) lazyInit() {
|
|
if l.root.next == nil {
|
|
l.Init()
|
|
}
|
|
}
|
|
|
|
func (l *List[T]) insert(e, at *Element[T]) *Element[T] {
|
|
e.prev = at
|
|
e.next = at.next
|
|
e.prev.next = e
|
|
e.next.prev = e
|
|
e.list = l
|
|
l.len++
|
|
return e
|
|
}
|
|
|
|
func (l *List[T]) insertValue(v T, at *Element[T]) *Element[T] {
|
|
return l.insert(&Element[T]{Value: v}, at)
|
|
}
|
|
|
|
func (l *List[T]) remove(e *Element[T]) {
|
|
e.prev.next = e.next
|
|
e.next.prev = e.prev
|
|
e.next = nil
|
|
e.prev = nil
|
|
e.list = nil
|
|
l.len--
|
|
}
|
|
|
|
func (l *List[T]) Remove(e *Element[T]) T {
|
|
if e.list == l {
|
|
l.remove(e)
|
|
}
|
|
return e.Value
|
|
}
|
|
|
|
func (l *List[T]) PushFront(v T) *Element[T] {
|
|
l.lazyInit()
|
|
return l.insertValue(v, &l.root)
|
|
}
|
|
|
|
func (l *List[T]) PushBack(v T) *Element[T] {
|
|
l.lazyInit()
|
|
return l.insertValue(v, l.root.prev)
|
|
}
|
|
|
|
func (l *List[T]) InsertBefore(v T, mark *Element[T]) *Element[T] {
|
|
if mark.list != l {
|
|
return nil
|
|
}
|
|
return l.insertValue(v, mark.prev)
|
|
}
|
|
|
|
func (l *List[T]) InsertAfter(v T, mark *Element[T]) *Element[T] {
|
|
if mark.list != l {
|
|
return nil
|
|
}
|
|
return l.insertValue(v, mark)
|
|
}
|
|
|
|
func (l *List[T]) MoveToFront(e *Element[T]) {
|
|
if e.list != l || l.root.next == e {
|
|
return
|
|
}
|
|
l.move(e, &l.root)
|
|
}
|
|
|
|
func (l *List[T]) MoveToBack(e *Element[T]) {
|
|
if e.list != l || l.root.prev == e {
|
|
return
|
|
}
|
|
l.move(e, l.root.prev)
|
|
}
|
|
|
|
func (l *List[T]) MoveBefore(e, mark *Element[T]) {
|
|
if e.list != l || e == mark || mark.list != l {
|
|
return
|
|
}
|
|
l.move(e, mark.prev)
|
|
}
|
|
|
|
func (l *List[T]) MoveAfter(e, mark *Element[T]) {
|
|
if e.list != l || e == mark || mark.list != l {
|
|
return
|
|
}
|
|
l.move(e, mark)
|
|
}
|
|
|
|
func (l *List[T]) move(e, at *Element[T]) {
|
|
if e == at {
|
|
return
|
|
}
|
|
e.prev.next = e.next
|
|
e.next.prev = e.prev
|
|
e.prev = at
|
|
e.next = at.next
|
|
e.prev.next = e
|
|
e.next.prev = e
|
|
}
|