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  }