Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
b9c46947d2
|
|||
412277b3e0
|
|||
e46f8019ec
|
|||
ae952b2166
|
|||
b24dba9a45
|
@@ -74,7 +74,7 @@ func processEnvOverrides(rval reflect.Value, delim string, prefix string) error
|
||||
|
||||
rvfield.Set(reflect.ValueOf(envval))
|
||||
|
||||
fmt.Printf("[CONF] Overwrite config '%s' () with '%s'\n", fullEnvKey, envval)
|
||||
fmt.Printf("[CONF] Overwrite config '%s' with '%s'\n", fullEnvKey, envval)
|
||||
|
||||
} else if rvfield.Type() == reflect.TypeOf(int(0)) {
|
||||
|
||||
|
116
dataext/stack.go
Normal file
116
dataext/stack.go
Normal file
@@ -0,0 +1,116 @@
|
||||
package dataext
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var ErrEmptyStack = errors.New("stack is empty")
|
||||
|
||||
type Stack[T any] struct {
|
||||
lock *sync.Mutex
|
||||
data []T
|
||||
}
|
||||
|
||||
func NewStack[T any](threadsafe bool, initialCapacity int) *Stack[T] {
|
||||
var lck *sync.Mutex = nil
|
||||
if threadsafe {
|
||||
lck = &sync.Mutex{}
|
||||
}
|
||||
return &Stack[T]{
|
||||
lock: lck,
|
||||
data: make([]T, 0, initialCapacity),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Stack[T]) Push(v T) {
|
||||
if s.lock != nil {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
}
|
||||
|
||||
s.data = append(s.data, v)
|
||||
}
|
||||
|
||||
func (s *Stack[T]) Pop() (T, error) {
|
||||
if s.lock != nil {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
}
|
||||
|
||||
l := len(s.data)
|
||||
if l == 0 {
|
||||
return *new(T), ErrEmptyStack
|
||||
}
|
||||
|
||||
result := s.data[l-1]
|
||||
s.data = s.data[:l-1]
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *Stack[T]) OptPop() *T {
|
||||
if s.lock != nil {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
}
|
||||
|
||||
l := len(s.data)
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := s.data[l-1]
|
||||
s.data = s.data[:l-1]
|
||||
|
||||
return langext.Ptr(result)
|
||||
}
|
||||
|
||||
func (s *Stack[T]) Peek() (T, error) {
|
||||
if s.lock != nil {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
}
|
||||
|
||||
l := len(s.data)
|
||||
|
||||
if l == 0 {
|
||||
return *new(T), ErrEmptyStack
|
||||
}
|
||||
|
||||
return s.data[l-1], nil
|
||||
}
|
||||
|
||||
func (s *Stack[T]) OptPeek() *T {
|
||||
if s.lock != nil {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
}
|
||||
|
||||
l := len(s.data)
|
||||
|
||||
if l == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return langext.Ptr(s.data[l-1])
|
||||
}
|
||||
|
||||
func (s *Stack[T]) Length() int {
|
||||
if s.lock != nil {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
}
|
||||
|
||||
return len(s.data)
|
||||
}
|
||||
|
||||
func (s *Stack[T]) Empty() bool {
|
||||
if s.lock != nil {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
}
|
||||
|
||||
return len(s.data) == 0
|
||||
}
|
@@ -37,3 +37,21 @@ func IsSliceSorted[T any](arr []T, less func(v1, v2 T) bool) bool {
|
||||
return less(arr[i1], arr[i2])
|
||||
})
|
||||
}
|
||||
|
||||
func SortBy[TElem any, TSel OrderedConstraint](arr []TElem, selector func(v TElem) TSel) {
|
||||
sort.Slice(arr, func(i1, i2 int) bool {
|
||||
return selector(arr[i1]) < selector(arr[i2])
|
||||
})
|
||||
}
|
||||
|
||||
func SortByStable[TElem any, TSel OrderedConstraint](arr []TElem, selector func(v TElem) TSel) {
|
||||
sort.SliceStable(arr, func(i1, i2 int) bool {
|
||||
return selector(arr[i1]) < selector(arr[i2])
|
||||
})
|
||||
}
|
||||
|
||||
func IsSortedBy[TElem any, TSel OrderedConstraint](arr []TElem, selector func(v TElem) TSel) {
|
||||
sort.SliceStable(arr, func(i1, i2 int) bool {
|
||||
return selector(arr[i1]) < selector(arr[i2])
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user