126 lines
2.3 KiB
Go
126 lines
2.3 KiB
Go
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 d’entré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 d’entré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 d’entrées.
|
||
func NewList[T any](elems ...T) (l *List[T]) {
|
||
l = new(List[T])
|
||
l.PushBack(elems...)
|
||
|
||
return
|
||
}
|