gob/collection/list.go

126 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}