From 09de0a19e1a24133bfa14d2c472370fe4bfd6d81 Mon Sep 17 00:00:00 2001 From: mstar Date: Thu, 24 Apr 2025 15:52:43 +0200 Subject: [PATCH] Change queues and stacks - Make chain element private - Remove JSON Marshaller from stack and queue - Remove access to top chain element --- containers/generics.go | 12 ++++++------ containers/queues.go | 42 ++++++++++-------------------------------- containers/stacks.go | 16 ++-------------- 3 files changed, 18 insertions(+), 52 deletions(-) diff --git a/containers/generics.go b/containers/generics.go index 17c1c4d..9465afd 100644 --- a/containers/generics.go +++ b/containers/generics.go @@ -1,15 +1,15 @@ package containers -type ChainElem[T any] struct { +type chainElem[T any] struct { Elem *T - Next *ChainElem[T] + Next *chainElem[T] } // reachable checks if you can reach elem l when starting from elem f. // It detects loops and returns false if it runs into one. -func reachable[T any](f, l *ChainElem[T]) bool { +func reachable[T any](f, l *chainElem[T]) bool { // Map to keep track of nodes already visited - checks := make(map[*ChainElem[T]]bool) + checks := make(map[*chainElem[T]]bool) for w := f; w != l; w = w.Next { if w == nil { return false @@ -26,8 +26,8 @@ func reachable[T any](f, l *ChainElem[T]) bool { } // emptyElem creates a new ChainElem[T] with empty values. -func emptyElem[T any]() *ChainElem[T] { - return &ChainElem[T]{ +func emptyElem[T any]() *chainElem[T] { + return &chainElem[T]{ Elem: nil, Next: nil, } diff --git a/containers/queues.go b/containers/queues.go index b528692..f590293 100644 --- a/containers/queues.go +++ b/containers/queues.go @@ -1,13 +1,15 @@ package containers import ( - "encoding/json" "errors" ) +var ErrInvalidQueue = errors.New("invalid queue") +var ErrEmptyQueue = errors.New("empty queue") + type Queue[T any] struct { - head *ChainElem[T] - tail *ChainElem[T] + head *chainElem[T] + tail *chainElem[T] } // isValid checks if the queue is still valid. @@ -25,7 +27,7 @@ func (q *Queue[T]) IsEmpty() bool { // Push adds a new element to the end of the queue. func (q *Queue[T]) Push(elem *T) error { if !q.isValid() { - return errors.New("invalid queue") + return ErrInvalidQueue } e := emptyElem[T]() @@ -40,10 +42,10 @@ func (q *Queue[T]) Push(elem *T) error { // It errors out if there is no element or the queue is invalid. func (q *Queue[T]) Pop() (*T, error) { if !q.isValid() { - return nil, errors.New("invalid queue") + return nil, ErrInvalidQueue } if q.IsEmpty() { - return nil, errors.New("empty queue") + return nil, ErrEmptyQueue } Elem := q.head.Elem q.head = q.head.Next @@ -54,38 +56,14 @@ func (q *Queue[T]) Pop() (*T, error) { // It errors out if there is no element or the queue is invalid. func (q *Queue[T]) Top() (*T, error) { if !q.isValid() { - return nil, errors.New("queue invalid") + return nil, ErrInvalidQueue } if q.IsEmpty() { - return nil, errors.New("queue empty") + return nil, ErrEmptyQueue } return q.head.Elem, nil } -// HeadElem returns the first ChainElem of the queue without removing it. -// It errors out if there is no element or the queue is invalid. -func (q *Queue[T]) HeadElem() (*ChainElem[T], error) { - if !q.isValid() { - return nil, errors.New("queue invalid") - } - if q.IsEmpty() { - return nil, errors.New("queue empty") - } - return q.head, nil -} - -// MarshalJSON is used for generating json data when using json.Marshal. -func (q *Queue[T]) MarshalJSON() ([]byte, error) { - if !q.isValid() { - return nil, errors.New("queue invalid") - } - if q.IsEmpty() { - return nil, errors.New("queue empty") - } - - return json.Marshal(q.head) -} - func BuildQueue[T any]() *Queue[T] { empty := emptyElem[T]() return &Queue[T]{ diff --git a/containers/stacks.go b/containers/stacks.go index 57a4b55..101b820 100644 --- a/containers/stacks.go +++ b/containers/stacks.go @@ -1,13 +1,12 @@ package containers import ( - "encoding/json" "errors" ) type Stack[T any] struct { - top *ChainElem[T] - bottom *ChainElem[T] + top *chainElem[T] + bottom *chainElem[T] } // isValid checks if the stack is valid. @@ -61,17 +60,6 @@ func (s *Stack[T]) Top() (*T, error) { return s.top.Elem, nil } -// MarshalJSON is used by json.Marshal to create a json representation. -func (s *Stack[T]) MarshalJSON() ([]byte, error) { - if !s.isValid() { - return nil, errors.New("queue invalid") - } - if s.IsEmpty() { - return nil, errors.New("queue empty") - } - - return json.Marshal(s.top) -} func BuildStack[T any]() *Stack[T] { empty := emptyElem[T]() return &Stack[T]{