gob/collection/list.go

126 lines
2.3 KiB
Go
Raw Normal View History

2023-09-23 13:39:05 +00:00
package collection
import (
. "gitea.zaclys.com/bvaudour/gob/option"
)
// List représente une collection délément qui peut être modifiée (ajout/suppression) par chaque bout.
// Elle peut donc se comporter à la fois comme une pile et une file.
type List[T any] struct {
first *dualChain[T]
last *dualChain[T]
size uint
}
// Len retourne le nombre déléments de la liste.
func (l *List[T]) Len() uint {
return l.size
}
func (l *List[T]) push_front(e T) {
var (
c = newDual(e)
oldFirst Option[*dualChain[T]]
)
if l.size == 0 {
l.last = c
} else {
oldFirst = Some(l.first)
}
link(Some(c), oldFirst)
l.first = c
l.size++
}
func (l *List[T]) push_back(e T) {
var (
c = newDual(e)
oldLast Option[*dualChain[T]]
)
if l.size == 0 {
l.first = c
} else {
oldLast = Some(l.last)
}
link(oldLast, Some(c))
l.last = c
l.size++
}
// PushFront ajoute tous les éléments dentrée en début de liste.
func (l *List[T]) PushFront(elems ...T) {
for _, e := range elems {
l.push_front(e)
}
}
// PushBack ajoute tous les éléments dentrée en fin de liste.
func (l *List[T]) PushBack(elems ...T) {
for _, e := range elems {
l.push_back(e)
}
}
// PopFront supprime le premier élément de la liste.
func (l *List[T]) PopFront() (e Option[T]) {
if l.size > 0 {
e = Some(l.first.value)
l.first = l.first.next
l.size--
link(None[*dualChain[T]](), Some(l.first))
if l.size == 0 {
l.last = l.first
}
}
return
}
// PopLast supprime le dernier élément de la liste.
func (l *List[T]) PopLast() (e Option[T]) {
if l.size > 0 {
e = Some(l.last.value)
l.last = l.last.prev
l.size--
link(Some(l.last), None[*dualChain[T]]())
if l.size == 0 {
l.first = l.last
}
}
return
}
// Concatenate concatène deux listes.
func (q1 *List[T]) Concatenate(l2 *List[T]) {
c, l := l2.first, l2.size
for i := uint(0); i < l; i++ {
q1.push_back(c.value)
c = c.next
}
}
// ToSlice convertit une liste en slice.
func (l *List[T]) ToSlice() (sl []T) {
sl = make([]T, l.size)
c := l.first
for i := uint(0); i < l.size; i++ {
sl[i] = c.value
c = c.next
}
return
}
// NewList retourne une liste initialisée à partir des données dentrées.
func NewList[T any](elems ...T) (l *List[T]) {
l = new(List[T])
l.PushBack(elems...)
return
}