goutils/containers/stacks.go
mstar 09de0a19e1
Change queues and stacks
- Make chain element private
- Remove JSON Marshaller from stack and queue
- Remove access to top chain element
2025-04-24 15:52:43 +02:00

69 lines
1.5 KiB
Go

package containers
import (
"errors"
)
type Stack[T any] struct {
top *chainElem[T]
bottom *chainElem[T]
}
// isValid checks if the stack is valid.
func (s *Stack[T]) isValid() bool {
return s.top != nil &&
s.bottom != nil &&
reachable(s.top, s.bottom)
}
// IsEmpty checks if the stack is currently empty.
func (s *Stack[T]) IsEmpty() bool {
return s.top == s.bottom
}
// Push adds a new element to the top of the stack.
// It errors out if the stack is invalid.
func (s *Stack[T]) Push(e *T) error {
if !s.isValid() {
return errors.New("stack invalid")
}
n := emptyElem[T]()
n.Elem = e
n.Next = s.top
s.top = n
return nil
}
// Pop removes the first element at the top of the stack and returns it.
// It errors out if the stack is invalid or empty.
func (s *Stack[T]) Pop() (*T, error) {
if !s.isValid() {
return nil, errors.New("stack invalid")
}
if s.IsEmpty() {
return nil, errors.New("stack empty")
}
e := s.top.Elem
s.top = s.top.Next
return e, nil
}
// Top returns the first element at the top of the stack without removing it.
// It errors out if the stack is empty or invalid.
func (s *Stack[T]) Top() (*T, error) {
if !s.isValid() {
return nil, errors.New("stack invalid")
}
if s.IsEmpty() {
return nil, errors.New("stack empty")
}
return s.top.Elem, nil
}
func BuildStack[T any]() *Stack[T] {
empty := emptyElem[T]()
return &Stack[T]{
top: empty,
bottom: empty,
}
}