68 lines
1.1 KiB
Go
68 lines
1.1 KiB
Go
package core
|
|
|
|
type Stack[T any] struct {
|
|
Current Pos
|
|
Capacity Pos
|
|
|
|
items []T
|
|
}
|
|
|
|
func NewStack[T any](maxCapacity Pos) *Stack[T] {
|
|
return &Stack[T]{
|
|
items: make([]T, min(maxCapacity, 16)),
|
|
Capacity: maxCapacity,
|
|
Current: 0,
|
|
}
|
|
}
|
|
|
|
func (s *Stack[T]) Push(items ...T) {
|
|
for _, item := range items {
|
|
s.pushItem(item)
|
|
}
|
|
}
|
|
|
|
func (s *Stack[T]) pushItem(item T) {
|
|
if s.Current >= s.Capacity {
|
|
panic("stack overflow")
|
|
}
|
|
if int(s.Current) == len(s.items) {
|
|
s.items = append(s.items, item)
|
|
} else {
|
|
s.items[s.Current] = item
|
|
}
|
|
|
|
s.Current++
|
|
}
|
|
|
|
func (s *Stack[T]) Pop() T {
|
|
if s.Current <= 0 {
|
|
panic("stack underflow")
|
|
}
|
|
|
|
s.Current--
|
|
return s.items[s.Current]
|
|
}
|
|
|
|
func (s *Stack[T]) Peek() T {
|
|
if s.Current <= 0 {
|
|
panic("stack underflow")
|
|
}
|
|
|
|
return s.items[s.Current-1]
|
|
}
|
|
|
|
// check whether the stack is invalid (stack over-/underflow)
|
|
func (s *Stack[T]) check() {
|
|
if s.Current >= s.Capacity {
|
|
panic("stack underflow")
|
|
}
|
|
|
|
if s.Current < 0 {
|
|
panic("stack underflow")
|
|
}
|
|
}
|
|
|
|
// Slice gets a slice of the current items in use
|
|
func (s *Stack[T]) Slice() []T {
|
|
return s.items[:s.Current]
|
|
}
|