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 }