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] }