80 lines
1.5 KiB
Go
80 lines
1.5 KiB
Go
// Copyright (c) 2024 Tulir Asokan
|
|
//
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
package exslices
|
|
|
|
import (
|
|
"iter"
|
|
)
|
|
|
|
type Stack[T comparable] []T
|
|
|
|
func (s *Stack[T]) Push(v ...T) {
|
|
*s = append(*s, v...)
|
|
}
|
|
|
|
// Peek returns the top item from the stack without removing it.
|
|
func (s *Stack[T]) Peek() (v T, ok bool) {
|
|
return s.PeekN(1)
|
|
}
|
|
|
|
// PeekN returns the nth item from the top of the stack (1-based).
|
|
func (s *Stack[T]) PeekN(n int) (v T, ok bool) {
|
|
if len(*s) < n {
|
|
return
|
|
}
|
|
v = (*s)[len(*s)-n]
|
|
ok = true
|
|
return
|
|
}
|
|
|
|
// Pop removes and returns the top item from the stack.
|
|
func (s *Stack[T]) Pop() (v T, ok bool) {
|
|
v, ok = s.Peek()
|
|
if ok {
|
|
*s = (*s)[:len(*s)-1]
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *Stack[T]) PeekValue() T {
|
|
v, _ := s.Peek()
|
|
return v
|
|
}
|
|
|
|
func (s *Stack[T]) PopValue() T {
|
|
v, _ := s.Pop()
|
|
return v
|
|
}
|
|
|
|
// Index returns the highest index of the given value in the stack, or -1 if not found.
|
|
func (s *Stack[T]) Index(val T) int {
|
|
for i := len(*s) - 1; i >= 0; i-- {
|
|
if (*s)[i] == val {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
// Has returns whether the given value is in the stack.
|
|
func (s *Stack[T]) Has(val T) bool {
|
|
return s.Index(val) != -1
|
|
}
|
|
|
|
func (s *Stack[T]) PopIter() iter.Seq[T] {
|
|
return func(yield func(T) bool) {
|
|
for {
|
|
v, ok := s.Pop()
|
|
if !ok {
|
|
return
|
|
}
|
|
if !yield(v) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|