Documentation ¶
Overview ¶
Package typ includes generic types that are missing from the Go standard library. This includes types for sets, sorted slices, trees, etc.
Index ¶
- Variables
- func Abs[T Real](v T) T
- func All[T any](slice []T, cond func(value T) bool) bool
- func Any[T any](slice []T, cond func(value T) bool) bool
- func Chunk[T any](slice []T, size int) [][]T
- func ChunkIter[T any](slice []T, size int, callback func(chunk []T))
- func Clamp[T constraints.Ordered](v, min, max T) T
- func Clamp01[T Real](v T) T
- func Coal[T comparable](values ...T) T
- func Compare[T constraints.Ordered](a, b T) int
- func Concat[T any](a, b []T) []T
- func Contains[T comparable](slice []T, value T) bool
- func ContainsFunc[T any](slice []T, value T, equals func(a, b T) bool) bool
- func ContainsValue[K comparable, V comparable](m map[K]V, value V) bool
- func Digits10[T constraints.Integer](v T) int
- func DigitsSign10[T constraints.Integer](v T) int
- func Distinct[T comparable](slice []T) []T
- func DistinctFunc[T any](slice []T, equals func(a, b T) bool) []T
- func Except[T comparable](slice []T, exclude []T) []T
- func ExceptSet[T comparable](slice []T, exclude Set[T]) []T
- func Fill[T any](slice []T, value T)
- func Filter[T any](slice []T, match func(value T) bool) []T
- func Fold[TState, T any](slice []T, seed TState, acc func(state TState, value T) TState) TState
- func FoldReverse[TState, T any](slice []T, seed TState, acc func(state TState, value T) TState) TState
- func Index[T comparable](slice []T, value T) int
- func IndexFunc[T any](slice []T, f func(value T) bool) int
- func Insert[T any](slice *[]T, index int, value T)
- func InsertSlice[T any](slice *[]T, index int, values []T)
- func IsNil[T any](value T) bool
- func Last[T any](slice []T) T
- func MakeChanOf[T any](_ T, size ...int) chan T
- func MakeChanOfChan[T any](_ chan T, size ...int) chan T
- func MakeMapOf[K comparable, V any](_ K, _ V, size ...int) map[K]V
- func MakeMapOfMap[K comparable, V any](_ map[K]V, size ...int) map[K]V
- func MakeSliceOf[T any](_ T, size ...int) []T
- func MakeSliceOfKey[K comparable, V any](_ map[K]V, size ...int) []K
- func MakeSliceOfSlice[T any](_ []T, size ...int) []T
- func MakeSliceOfValue[K comparable, V any](_ map[K]V, size ...int) []V
- func Map[TA any, TB any](slice []TA, conv func(value TA) TB) []TB
- func MapErr[TA any, TB any](slice []TA, conv func(value TA) (TB, error)) ([]TB, error)
- func Max[T constraints.Ordered](v ...T) T
- func Min[T constraints.Ordered](v ...T) T
- func NewOf[T any](*T) *T
- func Pairs[T any](slice []T) [][2]T
- func PairsIter[T any](slice []T, callback func(a, b T))
- func Product[T Number](v ...T) T
- func Ptr[T any](value T) *T
- func RecvContext[T any](ctx context.Context, ch <-chan T) (T, bool)
- func RecvQueued[T any](ch <-chan T, maxValues int) []T
- func RecvQueuedFull[T any](ch <-chan T, buf []T) int
- func RecvTimeout[T any](ch <-chan T, timeout time.Duration) (T, bool)
- func Remove[T any](slice *[]T, index int)
- func RemoveSlice[T any](slice *[]T, index int, length int)
- func Repeat[T any](value T, count int) []T
- func Reverse[T any](slice []T)
- func SafeGet[T any](slice []T, index int) T
- func SafeGetOr[T any](slice []T, index int, fallback T) T
- func Search[T constraints.Ordered](slice []T, value T) int
- func SendContext[T any](ctx context.Context, ch chan<- T, value T) bool
- func SendTimeout[T any](ch chan<- T, value T, timeout time.Duration) bool
- func Shuffle[T any](slice []T)
- func ShuffleRand[T any](slice []T, rand *rand.Rand)
- func Sort[T constraints.Ordered](slice []T)
- func SortDesc[T constraints.Ordered](slice []T)
- func Sum[T Number](v ...T) T
- func Tern[T any](cond bool, ifTrue, ifFalse T) T
- func TernCast[T any](cond bool, value any, ifFalse T) T
- func Trim[T comparable](slice []T, unwanted []T) []T
- func TrimFunc[T any](slice []T, unwanted func(value T) bool) []T
- func TrimLeft[T comparable](slice []T, unwanted []T) []T
- func TrimLeftFunc[T any](slice []T, unwanted func(value T) bool) []T
- func TrimRight[T comparable](slice []T, unwanted []T) []T
- func TrimRightFunc[T any](slice []T, unwanted func(value T) bool) []T
- func TryGet[T any](slice []T, index int) (T, bool)
- func Windowed[T any](slice []T, size int) [][]T
- func WindowedIter[T any](slice []T, size int, callback func(window []T))
- func Zero[T any]() T
- func ZeroOf[T any](T) T
- type Array2D
- func (a Array2D[T]) Clone() Array2D[T]
- func (a Array2D[T]) Fill(x1, y1, x2, y2 int, value T)
- func (a Array2D[T]) Get(x, y int) T
- func (a Array2D[T]) Height() int
- func (a Array2D[T]) Row(y int) []T
- func (a Array2D[T]) RowSpan(x1, x2, y int) []T
- func (a Array2D[T]) Set(x, y int, value T)
- func (a Array2D[T]) String() string
- func (a Array2D[T]) Width() int
- type AtomicValue
- type Counting
- type Element
- type Grouping
- type KeyedLocker
- type KeyedMutex
- type KeyedRWMutex
- func (km *KeyedRWMutex[T]) ClearKey(key T)
- func (km *KeyedRWMutex[T]) LockKey(key T)
- func (km *KeyedRWMutex[T]) RLockKey(key T)
- func (km *KeyedRWMutex[T]) RUnlockKey(key T)
- func (km *KeyedRWMutex[T]) TryLockKey(key T) bool
- func (km *KeyedRWMutex[T]) TryRLockKey(key T) bool
- func (km *KeyedRWMutex[T]) UnlockKey(key T)
- type List
- func (l *List[T]) Back() *Element[T]
- func (l *List[T]) Front() *Element[T]
- func (l *List[T]) Init() *List[T]
- func (l *List[T]) InsertAfter(v T, mark *Element[T]) *Element[T]
- func (l *List[T]) InsertBefore(v T, mark *Element[T]) *Element[T]
- func (l *List[T]) Len() int
- func (l *List[T]) MoveAfter(e, mark *Element[T])
- func (l *List[T]) MoveBefore(e, mark *Element[T])
- func (l *List[T]) MoveToBack(e *Element[T])
- func (l *List[T]) MoveToFront(e *Element[T])
- func (l *List[T]) PushBack(v T) *Element[T]
- func (l *List[T]) PushBackList(other *List[T])
- func (l *List[T]) PushFront(v T) *Element[T]
- func (l *List[T]) PushFrontList(other *List[T])
- func (l *List[T]) Remove(e *Element[T]) T
- type Null
- func (n Null[T]) IsSet() bool
- func (n Null[T]) IsValid() bool
- func (n Null[T]) IsZero() bool
- func (n Null[T]) MarshalJSON() ([]byte, error)
- func (n Null[T]) MarshalText() ([]byte, error)
- func (n Null[T]) Ptr() *T
- func (n *Null[T]) Scan(value any) error
- func (n *Null[T]) SetValid(value T)
- func (n *Null[T]) UnmarshalJSON(data []byte) error
- func (n *Null[T]) UnmarshalText(text []byte) error
- func (n Null[T]) Value() (driver.Value, error)
- type Number
- type OrderedSlice
- func (s *OrderedSlice[T]) Add(value T) int
- func (s *OrderedSlice[T]) Contains(value T) bool
- func (s *OrderedSlice[T]) Get(index int) T
- func (s *OrderedSlice[T]) Index(value T) int
- func (s *OrderedSlice[T]) Len() int
- func (s *OrderedSlice[T]) Remove(value T) int
- func (s *OrderedSlice[T]) RemoveAt(index int)
- func (s OrderedSlice[T]) String() string
- type OrderedTree
- func (n *OrderedTree[T]) Add(value T)
- func (n *OrderedTree[T]) Clear()
- func (n *OrderedTree[T]) Clone() OrderedTree[T]
- func (n *OrderedTree[T]) Contains(value T) bool
- func (n *OrderedTree[T]) Len() int
- func (n *OrderedTree[T]) Remove(value T) bool
- func (n *OrderedTree[T]) SliceInOrder() []T
- func (n *OrderedTree[T]) SlicePostOrder() []T
- func (n *OrderedTree[T]) SlicePreOrder() []T
- func (n OrderedTree[T]) String() string
- func (n *OrderedTree[T]) WalkInOrder(walker func(value T))
- func (n *OrderedTree[T]) WalkPostOrder(walker func(value T))
- func (n *OrderedTree[T]) WalkPreOrder(walker func(value T))
- type Pool
- type Publisher
- func (o *Publisher[T]) Pub(ev T)
- func (o *Publisher[T]) PubSlice(evs []T)
- func (o *Publisher[T]) PubSliceSync(evs []T)
- func (o *Publisher[T]) PubSliceWait(evs []T)
- func (o *Publisher[T]) PubSync(ev T)
- func (o *Publisher[T]) PubWait(ev T)
- func (o *Publisher[T]) Sub() <-chan T
- func (o *Publisher[T]) SubBuf(size int) <-chan T
- func (o *Publisher[T]) Unsub(sub <-chan T) error
- func (o *Publisher[T]) UnsubAll() error
- type Queue
- type Real
- type Ring
- type Set
- func (s Set[T]) Add(value T) bool
- func (s Set[T]) AddSet(set Set[T]) int
- func (s Set[T]) Clone() Set[T]
- func (s Set[T]) Has(value T) bool
- func (s Set[T]) Intersect(other Set[T]) Set[T]
- func (s Set[T]) Remove(value T) bool
- func (s Set[T]) RemoveSet(set Set[T]) int
- func (s Set[T]) SetDiff(other Set[T]) Set[T]
- func (s Set[T]) Slice() []T
- func (s Set[T]) String() string
- func (s Set[T]) SymDiff(other Set[T]) Set[T]
- func (s Set[T]) Union(other Set[T]) Set[T]
- type SetProduct
- type SortOrdered
- type SortedSlice
- func (s *SortedSlice[T]) Add(value T) int
- func (s *SortedSlice[T]) Contains(value T) bool
- func (s *SortedSlice[T]) Get(index int) T
- func (s *SortedSlice[T]) Index(value T) int
- func (s *SortedSlice[T]) Len() int
- func (s *SortedSlice[T]) Remove(value T) int
- func (s *SortedSlice[T]) RemoveAt(index int)
- func (s SortedSlice[T]) String() string
- type Stack
- type SyncMap
- func (m *SyncMap[K, V]) Delete(key K)
- func (m *SyncMap[K, V]) Load(key K) (value V, ok bool)
- func (m *SyncMap[K, V]) LoadAndDelete(key K) (value V, loaded bool)
- func (m *SyncMap[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool)
- func (m *SyncMap[K, V]) Range(f func(key K, value V) bool)
- func (m *SyncMap[K, V]) Store(key K, value V)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrAlreadyUnsubscribed = errors.New("already unsubscribed") ErrSubscriptionNotInitalized = errors.New("subscription is not initialized") )
Errors specific for the listener and subscriptions.
Functions ¶
func Abs ¶
func Abs[T Real](v T) T
Abs returns the absolute value of a number, in other words removing the sign, in other words (again) changing negative numbers to positive and leaving positive numbers as-is.
Abs(0) // => 0 Abs(15) // => 15 Abs(-15) // => 15
func Chunk ¶
Chunk divides the slice up into chunks with a size limit. The last chunk may be smaller than size if the slice is not evenly divisible.
func ChunkIter ¶
ChunkIter divides the slice up into chunks and invokes the callback on each chunk. The last chunk may be smaller than size if the slice is not evenly divisible.
func Clamp ¶
func Clamp[T constraints.Ordered](v, min, max T) T
Clamp returns the value clamped between the minimum and maximum values.
func Clamp01 ¶
func Clamp01[T Real](v T) T
Clamp01 returns the value clamped between 0 (zero) and 1 (one).
func Coal ¶
func Coal[T comparable](values ...T) T
Coal will return the first non-zero value. Equivalent to the "null coalescing" operator from other languages, or the SQL "COALESCE(...)" expression.
var result = null ?? myDefaultValue; // C#, JavaScript, PHP, etc var result = typ.Coal(nil, myDefaultValue) // Go
Example ¶
bindAddressFromUser := "" bindAddressDefault := "localhost:8080" fmt.Println("Adress 1:", typ.Coal(bindAddressFromUser, bindAddressDefault)) bindAddressFromUser = "192.168.1.10:80" fmt.Println("Adress 2:", typ.Coal(bindAddressFromUser, bindAddressDefault))
Output: Adress 1: localhost:8080 Adress 2: 192.168.1.10:80
func Compare ¶
func Compare[T constraints.Ordered](a, b T) int
Compare checks if either value is greater or equal to the other. The result will be 0 if a == b, -1 if a < b, and +1 if a > b.
func Concat ¶
func Concat[T any](a, b []T) []T
Concat returns a new slice with the values from the two slices concatenated.
func Contains ¶
func Contains[T comparable](slice []T, value T) bool
Contains checks if a value exists inside a slice of values.
func ContainsFunc ¶
ContainsFunc checks if a value exists inside a slice of values with a custom equals operation.
func ContainsValue ¶
func ContainsValue[K comparable, V comparable](m map[K]V, value V) bool
ContainsValue checks if a value exists inside a map.
func Digits10 ¶
func Digits10[T constraints.Integer](v T) int
Digits10 returns the number of digits in the number as if it would be converted to a string in base 10. This is computed by comparing its value to all orders of 10, making it increadibly faster than calculating logaritms or by performing divisions.
func DigitsSign10 ¶
func DigitsSign10[T constraints.Integer](v T) int
DigitsSign10 returns the number of digits in the number as if it would be converted to a string in base 10, plus 1 if the number is negative to account for the negative sign. This is computed by comparing its value to all orders of 10, making it increadibly faster than calculating logaritms or by performing divisions.
func Distinct ¶
func Distinct[T comparable](slice []T) []T
Distinct returns a new slice of only unique values.
Example ¶
values := []string{"a", "b", "b", "a"} fmt.Printf("All: %v\n", values) fmt.Printf("Distinct: %v\n", typ.Distinct(values))
Output: All: [a b b a] Distinct: [a b]
func DistinctFunc ¶
DistinctFunc returns a new slice of only unique values.
func Except ¶
func Except[T comparable](slice []T, exclude []T) []T
Except returns a new slice for all items that are not found in the slice of items to exclude.
func ExceptSet ¶
func ExceptSet[T comparable](slice []T, exclude Set[T]) []T
ExceptSet returns a new slice for all items that are not found in the set of items to exclude.
func Fill ¶
func Fill[T any](slice []T, value T)
Fill populates a whole slice with the same value using exponential copy.
func Fold ¶
func Fold[TState, T any](slice []T, seed TState, acc func(state TState, value T) TState) TState
Fold will accumulate an answer based on all values in a slice. Returns the seed value as-is if the slice is empty.
func FoldReverse ¶
func FoldReverse[TState, T any](slice []T, seed TState, acc func(state TState, value T) TState) TState
FoldReverse will accumulate an answer based on all values in a slice, starting with the last element and accumulating backwards. Returns the seed value as-is if the slice is empty.
func Index ¶
func Index[T comparable](slice []T, value T) int
Index returns the index of a value, or -1 if none found.
This differs from Search as Index doesn't require the slice to be sorted.
func IndexFunc ¶
IndexFunc returns the index of the first occurence where the function returns true, or -1 if none found.
This differs from Search as Index doesn't require the slice to be sorted.
func Insert ¶
Insert inserts a value at a given index in the slice and shifts all following values to the right.
func InsertSlice ¶
InsertSlice inserts a slice of values at a given index in the slice and shifts all following values to the right.
func Last ¶
func Last[T any](slice []T) T
Last returns the last item in a slice. Will panic with an out of bound error if the slice is empty.
func MakeChanOf ¶
MakeChanOf returns the result of make(chan T) for the same type as the first argument.
Useful when wanting to call make() on a channel of anonymous types by making use of type inference to skip having to declare the full anonymous type multiple times, which is quite common when writing tests.
func MakeChanOfChan ¶
MakeChanOfChan returns the result of make(chan T) for the same type as the channel type in the first argument.
Useful when wanting to call make() on a channel of anonymous types by making use of type inference to skip having to declare the full anonymous type multiple times, which is quite common when writing tests.
func MakeMapOf ¶
func MakeMapOf[K comparable, V any](_ K, _ V, size ...int) map[K]V
MakeMapOf returns the result of make(map[K]V) for the same type as the first arguments.
Useful when wanting to call make() on a map of anonymous types by making use of type inference to skip having to declare the full anonymous type multiple times, which is quite common when writing tests.
func MakeMapOfMap ¶
func MakeMapOfMap[K comparable, V any](_ map[K]V, size ...int) map[K]V
MakeMapOfMap returns the result of make(map[K]V) for the same type as the key and value types of the first argument.
Useful when wanting to call make() on a map of anonymous types by making use of type inference to skip having to declare the full anonymous type multiple times, which is quite common when writing tests.
Example ¶
files := map[string]struct { SizeMB int CreatedAt time.Time UpdatedAt time.Time }{ "/root/gopher.png": { SizeMB: 10, CreatedAt: time.Now(), UpdatedAt: time.Now(), }, "/root/meaningoflife.txt": { SizeMB: 0, CreatedAt: time.Now(), UpdatedAt: time.Now(), }, } filteredFiles := typ.MakeMapOfMap(files) for path, f := range files { if ok, _ := filepath.Match("/root/*.txt", path); ok { filteredFiles[path] = f } } fmt.Println("Filtered:") for path, f := range filteredFiles { fmt.Println(path, ":", f.SizeMB, "MB") }
Output: Filtered: /root/meaningoflife.txt : 0 MB
func MakeSliceOf ¶
MakeSliceOf returns the result of make([]T) for the same type as the first argument.
Useful when wanting to call make() on a slice of anonymous types by making use of type inference to skip having to declare the full anonymous type multiple times, which is quite common when writing tests.
func MakeSliceOfKey ¶
func MakeSliceOfKey[K comparable, V any](_ map[K]V, size ...int) []K
MakeSliceOfKey returns the result of make([]T) for the same type as the map key type of the first argument.
Useful when wanting to call make() on a slice of anonymous types by making use of type inference to skip having to declare the full anonymous type multiple times, which is quite common when writing tests.
func MakeSliceOfSlice ¶
MakeSliceOfSlice returns the result of make([]T) for the same type as the slice element type of the first argument.
Useful when wanting to call make() on a slice of anonymous types by making use of type inference to skip having to declare the full anonymous type multiple times, which is quite common when writing tests.
Example ¶
var users = []struct { ID int Username string Admin bool }{ {1, "foo", true}, {2, "bar", false}, } var admins = typ.MakeSliceOfSlice(users) for _, u := range users { if u.Admin { admins = append(admins, u) } } fmt.Println("users:", len(users)) fmt.Println("admins:", len(admins))
Output: users: 2 admins: 1
func MakeSliceOfValue ¶
func MakeSliceOfValue[K comparable, V any](_ map[K]V, size ...int) []V
MakeSliceOfValue returns the result of make([]T) for the same type as the map value type of the first argument.
Useful when wanting to call make() on a slice of anonymous types by making use of type inference to skip having to declare the full anonymous type multiple times, which is quite common when writing tests.
func Map ¶
Map will apply a conversion function to all elements in a slice and return the new slice with converted values.
func MapErr ¶
MapErr will apply a conversion function to all elements in a slice and return the new slice with converted values. Will cancel the conversion on the first error occurrence.
func NewOf ¶
func NewOf[T any](*T) *T
NewOf returns the result of new() for the same type as the first argument. Useful when wanting to call new() on an anonymous type.
Example ¶
myVector := new(struct { X int Y int Z int }) otherVector := typ.NewOf(myVector) fmt.Println("myVector:", myVector) fmt.Println("otherVector:", otherVector) fmt.Println("same?:", myVector == otherVector) // different pointers
Output: myVector: &{0 0 0} otherVector: &{0 0 0} same?: false
func Pairs ¶
func Pairs[T any](slice []T) [][2]T
Pairs returns a slice of pairs for the given slice. If the slice has less than two items, then an empty slice is returned.
func PairsIter ¶
func PairsIter[T any](slice []T, callback func(a, b T))
PairsIter invokes the provided callback for all pairs for the given slice. If the slice has less than two items, then no invokation is performed.
func Product ¶
func Product[T Number](v ...T) T
Product multiplies together all numbers from the arguments. Returns 1 if no arguments.
func Ptr ¶
func Ptr[T any](value T) *T
Ptr returns a pointer to the value. Useful when working with literals.
func RecvContext ¶
RecvContext receives a value from a channel, or cancels when the given context is cancelled.
func RecvQueued ¶
RecvQueued will receive all values from a channel until either there's no more values in the channel's queue buffer, or it has received maxValues values, or until the channel is closed, whichever comes first.
func RecvQueuedFull ¶
RecvQueuedFull will receive all values from a channel until either there's no more values in the channel's queue buffer, or it has filled buf with values, or until the channel is closed, whichever comes first, and then returns the number of values that was received.
func RecvTimeout ¶
RecvTimeout receives a value from a channel, or cancels after a given timeout. If the timeout duration is zero or negative, then no limit is used.
func Remove ¶
Remove takes out a value at a given index and shifts all following values to the left.
func RemoveSlice ¶
RemoveSlice takes out a slice of values at a given index and length and shifts all following values to the left.
func Reverse ¶
func Reverse[T any](slice []T)
Reverse will reverse all elements inside a slice, in place.
func SafeGet ¶
SafeGet will get a value from a slice, or the zero value for the type if the index is outside the bounds of the slice. Passing a nil slice is equivalent to passing an empty slice.
func SafeGetOr ¶
SafeGetOr will get a value from a slice, or the fallback value for the type if the index is outside the bounds of the slice. Passing a nil slice is equivalent to passing an empty slice.
func Search ¶
func Search[T constraints.Ordered](slice []T, value T) int
Search performs a binary search to find the index of a value in a sorted slice of ordered values. The index of the first match is returned, or the index where it insert the value if the value is not present. The slice must be sorted in ascending order.
func SendContext ¶
SendContext receives a value from a channel, or cancels when the given context is cancelled.
func SendTimeout ¶
SendTimeout sends a value to a channel, or cancels after a given duration.
func Shuffle ¶
func Shuffle[T any](slice []T)
Shuffle will randomize the order of all elements inside a slice. It uses the rand package for random number generation, so you are expected to have called rand.Seed beforehand.
func ShuffleRand ¶
ShuffleRand will randomize the order of all elements inside a slice using the Fisher-Yates shuffle algoritm. It uses the rand argument for random number generation.
func Sort ¶
func Sort[T constraints.Ordered](slice []T)
Sort will sort a slice using the default less-than operator.
func SortDesc ¶
func SortDesc[T constraints.Ordered](slice []T)
SortDesc will sort a slice using the default less-than operator in descending order.
func Sum ¶
func Sum[T Number](v ...T) T
Sum adds upp all numbers from the arguments. Returns 0 if no arguments.
func Tern ¶
Tern returns different values depending on the given conditional boolean. Equivalent to the "ternary" operator from other languages.
var result = 1 > 2 ? "yes" : "no"; // C#, JavaScript, PHP, etc var result = typ.Tern(1 > 2, "yes", "no") // Go
Example ¶
age := 16 fmt.Println("To drink I want a glass of", typ.Tern(age >= 18, "wine", "milk"))
Output: To drink I want a glass of milk
func TernCast ¶
TernCast will cast the value if condition is true. Otherwise the last argument is returned.
func Trim ¶
func Trim[T comparable](slice []T, unwanted []T) []T
Trim returns a slice of the slice that has had all unwanted values trimmed away from both the start and the end.
Example ¶
x := []int{0, 1, 2, 3, 1, 2, 1} fmt.Printf("All: %v\n", x) fmt.Printf("Trimmed: %v\n", typ.Trim(x, []int{0, 1}))
Output: All: [0 1 2 3 1 2 1] Trimmed: [2 3 1 2]
func TrimFunc ¶
TrimFunc returns a slice of the slice that has had all unwanted values trimmed away from both the start and the end. Values are considered unwanted if the callback returns false.
func TrimLeft ¶
func TrimLeft[T comparable](slice []T, unwanted []T) []T
TrimLeft returns a slice of the slice that has had all unwanted values trimmed away from the start of the slice.
func TrimLeftFunc ¶
TrimLeftFunc returns a slice of the slice that has had all unwanted values trimmed away from the start of the slice. Values are considered unwanted if the callback returns false.
func TrimRight ¶
func TrimRight[T comparable](slice []T, unwanted []T) []T
TrimRight returns a slice of the slice that has had all unwanted values trimmed away from the end of the slice.
func TrimRightFunc ¶
TrimRightFunc returns a slice of the slice that has had all unwanted values trimmed away from the end of the slice. Values are considered unwanted if the callback returns false.
func TryGet ¶
TryGet will get a value from a slice, or return false on the second return value if the index is outside the bounds of the slice. Passing a nil slice is equivalent to passing an empty slice.
func Windowed ¶
Windowed returns a slice of windows, where each window is a slice of the specified size from the specified slice.
func WindowedIter ¶
WindowedIter invokes the provided callback for all windows, where each window is a slice of the specified size from the specified slice.
Types ¶
type Array2D ¶
type Array2D[T any] struct { // contains filtered or unexported fields }
Array2D is a 2-dimensional array.
Example ¶
// SPDX-FileCopyrightText: 2022 Kalle Fagerberg // // SPDX-License-Identifier: MIT package main import ( "fmt" "strings" "gopkg.in/typ.v1" ) type Sudoku struct { arr typ.Array2D[byte] } func (s Sudoku) PrintBoard() { var sb strings.Builder for y := 0; y < s.arr.Height(); y++ { if y%3 == 0 { sb.WriteString("+-------+-------+-------+\n") } for x := 0; x < s.arr.Width(); x++ { if x%3 == 0 { sb.WriteString("| ") } val := s.arr.Get(x, y) if val == 0 { sb.WriteByte(' ') } else { fmt.Fprint(&sb, val) } sb.WriteByte(' ') } sb.WriteString("|\n") } sb.WriteString("+-------+-------+-------+\n") fmt.Print(sb.String()) } func main() { s := Sudoku{ arr: typ.NewArray2DFromSlice(9, 9, [][]byte{ {5, 3, 0, 0, 7, 0, 0, 0, 0}, {6, 0, 0, 1, 9, 5, 0, 0, 0}, {0, 9, 8, 0, 0, 0, 0, 6, 0}, {8, 0, 0, 0, 6, 0, 0, 0, 3}, {4, 0, 0, 8, 0, 3, 0, 0, 1}, {7, 0, 0, 0, 2, 0, 0, 0, 6}, {0, 6, 0, 0, 0, 0, 2, 8, 0}, {0, 0, 0, 4, 1, 9, 0, 0, 5}, {0, 0, 0, 0, 8, 0, 0, 7, 9}, }), } s.arr.Set(2, 5, 3) s.PrintBoard() }
Output: +-------+-------+-------+ | 5 3 | 7 | | | 6 | 1 9 5 | | | 9 8 | | 6 | +-------+-------+-------+ | 8 | 6 | 3 | | 4 | 8 3 | 1 | | 7 3 | 2 | 6 | +-------+-------+-------+ | 6 | | 2 8 | | | 4 1 9 | 5 | | | 8 | 7 9 | +-------+-------+-------+
func NewArray2D ¶
NewArray2D initializes a 2-dimensional array with all zero values.
func NewArray2DFromSlice ¶
NewArray2DFromSlice initializes a 2-dimensional array based on a jagged slice of rows of values. Values from the jagged slice that are out of bounds are ignored.
func NewArray2DFromValue ¶
NewArray2DFromValue initializes a 2-dimensional array with a value.
func (Array2D[T]) Fill ¶
Fill will assign all values inside the region to the specified value. The coordinates are inclusive, meaning all values from [x1,y1] including [x1,y1] to [x2,y2] including [x2,y2] are set.
The method sorts the arguments, so x2 may be lower than x1 and y2 may be lower than y1.
func (Array2D[T]) Height ¶
Height returns the height of this array. The maximum y value is Height()-1.
func (Array2D[T]) Row ¶
Row returns a mutable slice for an entire row. Changing values in this slice will affect the array.
func (Array2D[T]) RowSpan ¶
RowSpan returns a mutable slice for part of a row. Changing values in this slice will affect the array.
type AtomicValue ¶
type AtomicValue[T any] struct { // contains filtered or unexported fields }
AtomicValue is a wrapper around sync/atomic.Value from the Go stdlib.
An AtomicValue must not be copied after first use.
func (*AtomicValue[T]) CompareAndSwap ¶
func (v *AtomicValue[T]) CompareAndSwap(old, new T) (swapped bool)
CompareAndSwap executes the compare-and-swap operation for the AtomicValue.
Using nil as the new value will result in panic.
func (*AtomicValue[T]) Load ¶
func (v *AtomicValue[T]) Load() (val T)
Load returns the value set by the most recent call to Store, or the zero value for this type if there has been no call to Store.
func (*AtomicValue[T]) Store ¶
func (v *AtomicValue[T]) Store(val T)
Store sets the value of the AtomicValue.
Using nil as the new value will result in panic.
func (*AtomicValue[T]) Swap ¶
func (v *AtomicValue[T]) Swap(new T) (old T)
Swap stores the new value into the AtomicValue and returns the previous value. It returns a zero value if the AtomicValue is empty.
Using nil as the new value will result in panic.
type Counting ¶
Counting is a key-count store returned by the CountBy function.
func CountBy ¶
func CountBy[K comparable, V any](slice []V, keyer func(value V) K) []Counting[K]
CountBy will count the number of occurrences for each key, using the key from the function provided.
type Element ¶
type Element[T any] struct { // The value stored with this element. Value T // contains filtered or unexported fields }
Element is an element of a linked list.
type Grouping ¶
type Grouping[K, V any] struct { Key K Values []V }
Grouping is a key-values store returned by the GroupBy functions.
func GroupBy ¶
func GroupBy[K comparable, V any](slice []V, keyer func(value V) K) []Grouping[K, V]
GroupBy will group all elements in the slice and return a slice of groups, using the key from the function provided.
type KeyedLocker ¶
type KeyedLocker[T comparable] interface { LockKey(key T) UnlockKey(key T) }
KeyedLocker represents an object that can be locked and unlocked on a per-key basis.
type KeyedMutex ¶
type KeyedMutex[T comparable] struct { // contains filtered or unexported fields }
KeyedMutex is a keyed mutual exclusion lock. The zero value for a KeyedMutex is an unlocked mutex for any key.
The KeyedMutex does not clear its own cache, so it will continue to grow for every new key that is used, unless you call the ClearKey method.
A KeyedMutex must not be copied after first use.
func (*KeyedMutex[T]) ClearKey ¶
func (km *KeyedMutex[T]) ClearKey(key T)
func (*KeyedMutex[T]) LockKey ¶
func (km *KeyedMutex[T]) LockKey(key T)
func (*KeyedMutex[T]) TryLockKey ¶
func (km *KeyedMutex[T]) TryLockKey(key T) bool
func (*KeyedMutex[T]) UnlockKey ¶
func (km *KeyedMutex[T]) UnlockKey(key T)
type KeyedRWMutex ¶
type KeyedRWMutex[T comparable] struct { // contains filtered or unexported fields }
KeyedRWMutex is a keyed reader/writer mutual exclusion lock. The lock can be held on a per-unique-key basis by an arbitrary number of readers or a single writer. The zero value for a KeyedRWMutex is an unlocked mutex for any key.
The KeyedRWMutex does not clear its own cache, so it will continue to grow for every new key that is used, unless you call the ClearKey method.
A KeyedRWMutex must not be copied after first use.
func (*KeyedRWMutex[T]) ClearKey ¶
func (km *KeyedRWMutex[T]) ClearKey(key T)
func (*KeyedRWMutex[T]) LockKey ¶
func (km *KeyedRWMutex[T]) LockKey(key T)
func (*KeyedRWMutex[T]) RLockKey ¶
func (km *KeyedRWMutex[T]) RLockKey(key T)
func (*KeyedRWMutex[T]) RUnlockKey ¶
func (km *KeyedRWMutex[T]) RUnlockKey(key T)
func (*KeyedRWMutex[T]) TryLockKey ¶
func (km *KeyedRWMutex[T]) TryLockKey(key T) bool
func (*KeyedRWMutex[T]) TryRLockKey ¶
func (km *KeyedRWMutex[T]) TryRLockKey(key T) bool
func (*KeyedRWMutex[T]) UnlockKey ¶
func (km *KeyedRWMutex[T]) UnlockKey(key T)
type List ¶
type List[T any] struct { // contains filtered or unexported fields }
List represents a doubly linked list. The zero value for List is an empty list ready to use.
This list is a fork of the official Go implementation, with the change of making it generic.
Example ¶
// Create a new list and put some numbers in it. l := typ.NewList[int]() e4 := l.PushBack(4) e1 := l.PushFront(1) l.InsertBefore(3, e4) l.InsertAfter(2, e1) // Iterate through list and print its contents. for e := l.Front(); e != nil; e = e.Next() { fmt.Println(e.Value) }
Output: 1 2 3 4
func (*List[T]) InsertAfter ¶
InsertAfter inserts a new element e with value v immediately after mark and returns e. If mark is not an element of l, the list is not modified. The mark must not be nil.
func (*List[T]) InsertBefore ¶
InsertBefore inserts a new element e with value v immediately before mark and returns e. If mark is not an element of l, the list is not modified. The mark must not be nil.
func (*List[T]) MoveAfter ¶
MoveAfter moves element e to its new position after mark. If e or mark is not an element of l, or e == mark, the list is not modified. The element and mark must not be nil.
func (*List[T]) MoveBefore ¶
MoveBefore moves element e to its new position before mark. If e or mark is not an element of l, or e == mark, the list is not modified. The element and mark must not be nil.
func (*List[T]) MoveToBack ¶
MoveToBack moves element e to the back of list l. If e is not an element of l, the list is not modified. The element must not be nil.
func (*List[T]) MoveToFront ¶
MoveToFront moves element e to the front of list l. If e is not an element of l, the list is not modified. The element must not be nil.
func (*List[T]) PushBack ¶
PushBack inserts a new element e with value v at the back of list l and returns e.
func (*List[T]) PushBackList ¶
PushBackList inserts a copy of another list at the back of list l. The lists l and other may be the same. They must not be nil.
func (*List[T]) PushFront ¶
PushFront inserts a new element e with value v at the front of list l and returns e.
func (*List[T]) PushFrontList ¶
PushFrontList inserts a copy of another list at the front of list l. The lists l and other may be the same. They must not be nil.
type Null ¶
Null is a nullable value that stores its nullable state inside its struct, meaning you never have to deal with pointers and possible nil dereferences.
It also means the types can live on the stack and never require to be allocated on the heap and managed by the garbage collector, which is unnecessary optimization for most, but requirement for others.
The type implements the following interfaces, making it possible to use in serialization:
encoding.TextMarshaler encoding.TextUnmarshaler encoding/json.Marshaler encoding/json.Unmarshaler
Note that while the type is generic, the JSON serialization logic still uses reflection and interface{} casting, as it relies on the built in encoding/json package.
The type also implements the following types, making it possible to be used in place of sql.NullXXX:
database/sql.Scanner database/sql/driver.Valuer
This Null implementation is forked from github.com/volatiletech/null/v9 to make it generic.
Example ¶
type User struct { FirstName string `json:"firstName"` MiddleName Null[string] `json:"middleName"` LastName string `json:"lastName"` DateOfBirth Null[time.Time] `json:"dob"` DateOfDeath Null[time.Time] `json:"dod"` } user := User{ FirstName: "John", MiddleName: Null[string]{}, LastName: "Doe", DateOfBirth: NullFrom(time.Date(1980, 5, 13, 0, 0, 0, 0, time.UTC)), DateOfDeath: Null[time.Time]{}, } bytes, _ := json.MarshalIndent(&user, "", " ") fmt.Println(string(bytes))
Output: { "firstName": "John", "middleName": null, "lastName": "Doe", "dob": "1980-05-13T00:00:00Z", "dod": null }
func NullFrom ¶
NullFrom creates a new nullable value that will be marked invalid if nil, and will always be valid if type is not nullable.
func NullFromPtr ¶
NullFromPtr creates a new nullable value that will be marked invalid if nil.
func (Null[T]) MarshalJSON ¶
MarshalJSON implements json.Marshaler.
func (Null[T]) MarshalText ¶
MarshalText implements encoding.TextMarshaler.
func (Null[T]) Ptr ¶
func (n Null[T]) Ptr() *T
Ptr returns a pointer to the inner value, or a nil pointer if this value is null.
func (*Null[T]) SetValid ¶
func (n *Null[T]) SetValid(value T)
SetValid changes the inner value and also sets it to be non-null.
func (*Null[T]) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler.
func (*Null[T]) UnmarshalText ¶
UnmarshalText implements encoding.TextUnmarshaler.
type Number ¶
type Number interface { constraints.Integer | constraints.Float | constraints.Complex }
Number is a type constraint for any Go numbers, including complex numbers.
type OrderedSlice ¶
type OrderedSlice[T constraints.Ordered] struct { // contains filtered or unexported fields }
OrderedSlice is a slice of ordered values. The slice is always sorted thanks to only inserting values in a sorted order.
Example ¶
var slice typ.OrderedSlice[string] slice.Add("f") slice.Add("b") slice.Add("e") slice.Add("a") slice.Add("d") slice.Add("c") slice.Add("g") fmt.Println(slice) fmt.Println("Contains a?", slice.Contains("a")) slice.Remove("d") fmt.Println(slice)
Output: [a b c d e f g] Contains a? true [a b c e f g]
func NewOrderedSlice ¶
func NewOrderedSlice[T constraints.Ordered](values []T) OrderedSlice[T]
NewOrderedSlice returns a new sorted slice based on a slice of values. Only ordered types are allowed. The values are sorted on insertion.
func (*OrderedSlice[T]) Add ¶
func (s *OrderedSlice[T]) Add(value T) int
func (*OrderedSlice[T]) Contains ¶
func (s *OrderedSlice[T]) Contains(value T) bool
func (*OrderedSlice[T]) Get ¶
func (s *OrderedSlice[T]) Get(index int) T
func (*OrderedSlice[T]) Index ¶
func (s *OrderedSlice[T]) Index(value T) int
func (*OrderedSlice[T]) Len ¶
func (s *OrderedSlice[T]) Len() int
func (*OrderedSlice[T]) Remove ¶
func (s *OrderedSlice[T]) Remove(value T) int
func (*OrderedSlice[T]) RemoveAt ¶
func (s *OrderedSlice[T]) RemoveAt(index int)
func (OrderedSlice[T]) String ¶
func (s OrderedSlice[T]) String() string
type OrderedTree ¶
type OrderedTree[T constraints.Ordered] struct { // contains filtered or unexported fields }
OrderedTree is a binary search tree (BST) for ordered Go types (numbers & strings), implemented as an AVL tree (Adelson-Velsky and Landis tree), a type of self-balancing BST. This guarantees O(log n) operations on insertion, searching, and deletion.
Example ¶
var tree typ.OrderedTree[string] // Unordered input tree.Add("E") tree.Add("B") tree.Add("D") tree.Add("C") tree.Add("A") // Sorted output fmt.Println(tree.Len(), tree)
Output: 5 [A B C D E]
func (*OrderedTree[T]) Add ¶
func (n *OrderedTree[T]) Add(value T)
Add will add another value to this tree. Duplicate values are allowed and are not dismissed.
func (*OrderedTree[T]) Clear ¶
func (n *OrderedTree[T]) Clear()
Clear will reset this tree to an empty tree.
func (*OrderedTree[T]) Clone ¶
func (n *OrderedTree[T]) Clone() OrderedTree[T]
Clone will return a copy of this tree, with a new set of nodes. The values are copied as-is, so no pointers inside your value type gets a deep clone.
func (*OrderedTree[T]) Contains ¶
func (n *OrderedTree[T]) Contains(value T) bool
Contains checks if a value exists in this tree by iterating the binary search tree.
func (*OrderedTree[T]) Len ¶
func (n *OrderedTree[T]) Len() int
Len returns the number of nodes in this tree.
func (*OrderedTree[T]) Remove ¶
func (n *OrderedTree[T]) Remove(value T) bool
Remove will try to remove the first occurrence of a value from the tree.
func (*OrderedTree[T]) SliceInOrder ¶
func (n *OrderedTree[T]) SliceInOrder() []T
SliceInOrder returns a slice of values by walking the tree in in-order. This returns all values in sorted order. See WalkInOrder for more details.
func (*OrderedTree[T]) SlicePostOrder ¶
func (n *OrderedTree[T]) SlicePostOrder() []T
SlicePostOrder returns a slice of values by walking the tree in post-order. See WalkPostOrder for more details.
func (*OrderedTree[T]) SlicePreOrder ¶
func (n *OrderedTree[T]) SlicePreOrder() []T
SlicePreOrder returns a slice of values by walking the tree in pre-order. See WalkPreOrder for more details.
func (OrderedTree[T]) String ¶
func (n OrderedTree[T]) String() string
func (*OrderedTree[T]) WalkInOrder ¶
func (n *OrderedTree[T]) WalkInOrder(walker func(value T))
WalkInOrder will iterate all values in this tree by first visiting each node's left branch, followed by the its own value, and then its right branch.
This is useful when reading a tree's values in order, as this guarantees iterating them in a sorted order.
func (*OrderedTree[T]) WalkPostOrder ¶
func (n *OrderedTree[T]) WalkPostOrder(walker func(value T))
WalkPostOrder will iterate all values in this tree by first visiting each node's left branch, followed by the its right branch, and then its own value.
This is useful when deleting values from a tree, as this guarantees to always delete leaf nodes.
func (*OrderedTree[T]) WalkPreOrder ¶
func (n *OrderedTree[T]) WalkPreOrder(walker func(value T))
WalkPreOrder will iterate all values in this tree by first visiting each node's value, followed by the its left branch, and then its right branch.
This is useful when copying binary search trees, as inserting back in this order will guarantee the clone will have the exact same layout.
type Pool ¶
type Pool[T any] struct { New func() T // contains filtered or unexported fields }
Pool is a wrapper around sync.Pool to allow generic and type safe access.
Example ¶
// SPDX-FileCopyrightText: 2022 Kalle Fagerberg // // SPDX-License-Identifier: MIT package main import ( "bytes" "io" "os" "time" "gopkg.in/typ.v1" ) var bufPool = typ.Pool[*bytes.Buffer]{ New: func() *bytes.Buffer { // The Pool's New function should generally only return pointer // types, since a pointer can be put into the return interface // value without an allocation: return new(bytes.Buffer) }, } // timeNow is a fake version of time.Now for tests. func timeNow() time.Time { return time.Unix(1136214245, 0) } func Log(w io.Writer, key, val string) { b := bufPool.Get() b.Reset() // Replace this with time.Now() in a real logger. b.WriteString(timeNow().UTC().Format(time.RFC3339)) b.WriteByte(' ') b.WriteString(key) b.WriteByte('=') b.WriteString(val) w.Write(b.Bytes()) bufPool.Put(b) } func main() { Log(os.Stdout, "path", "/search?q=flowers") }
Output: 2006-01-02T15:04:05Z path=/search?q=flowers
type Publisher ¶
type Publisher[T any] struct { OnPubTimeout func(ev T) // called if Pub or PubWait times out PubTimeoutAfter time.Duration // times out Pub & PubWait, if positive // contains filtered or unexported fields }
Publisher is a type that allows publishing an event which will be sent out to all subscribed channels. A sort of "fan-out message queue".
Example ¶
// SPDX-FileCopyrightText: 2022 Kalle Fagerberg // // SPDX-License-Identifier: MIT package main import ( "fmt" "sync" "gopkg.in/typ.v1" ) func printMessages(prefix string, ch <-chan string, wg *sync.WaitGroup) { for msg := range ch { fmt.Println(prefix, msg) } wg.Done() } func main() { var pub typ.Publisher[string] var wg sync.WaitGroup sub1 := pub.Sub() sub2 := pub.Sub() wg.Add(2) go printMessages("sub1:", sub1, &wg) go printMessages("sub2:", sub2, &wg) pub.PubWait("hello there") pub.UnsubAll() wg.Wait() }
Output: sub1: hello there sub2: hello there
func (*Publisher[T]) Pub ¶
func (o *Publisher[T]) Pub(ev T)
Pub sends the event to all subscriptions in their own goroutines and returns immediately without waiting for any of the channels to finish sending.
func (*Publisher[T]) PubSlice ¶
func (o *Publisher[T]) PubSlice(evs []T)
PubSlice sends a slice of events to all subscriptions in their own goroutines and returns immediately without waiting for any of the channels to finish sending.
func (*Publisher[T]) PubSliceSync ¶
func (o *Publisher[T]) PubSliceSync(evs []T)
PubSliceSync blocks while sending a slice of events syncronously to all subscriptions without starting a single goroutine. Useful in performance-critical use cases where there are a low expected number of subscribers (0-3).
func (*Publisher[T]) PubSliceWait ¶
func (o *Publisher[T]) PubSliceWait(evs []T)
PubSliceWait blocks while sending a slice of events to all subscriptions in their own goroutines, and waits until all have received the message or timed out.
func (*Publisher[T]) PubSync ¶
func (o *Publisher[T]) PubSync(ev T)
PubSync blocks while sending the event syncronously to all subscriptions without starting a single goroutine. Useful in performance-critical use cases where there are a low expected number of subscribers (0-3).
func (*Publisher[T]) PubWait ¶
func (o *Publisher[T]) PubWait(ev T)
PubWait blocks while sending the event to all subscriptions in their own goroutines, and waits until all have received the message or timed out.
func (*Publisher[T]) Sub ¶
func (o *Publisher[T]) Sub() <-chan T
Sub subscribes to events in a newly created channel with no buffer.
func (*Publisher[T]) SubBuf ¶
SubBuf subscribes to events in a newly created channel with a specified buffer size.
type Queue ¶
type Queue[T any] struct { // contains filtered or unexported fields }
Queue is a first-in-first-out collection.
The implementation is done via a linked-list.
Example ¶
var q Queue[string] q.Enqueue("tripp") q.Enqueue("trapp") q.Enqueue("trull") fmt.Println(q.Len()) // 3 fmt.Println(q.Dequeue()) // tripp, true fmt.Println(q.Dequeue()) // trapp, true fmt.Println(q.Dequeue()) // trull, true fmt.Println(q.Dequeue()) // "", false
Output: 3 tripp true trapp true trull true false
func (*Queue[T]) Enqueue ¶
func (q *Queue[T]) Enqueue(value T)
Enqueue adds a value to the start of the queue.
type Real ¶
type Real interface { constraints.Integer | constraints.Float }
Real is a type constraint for any real numbers. That being integers or floats.
type Ring ¶
type Ring[T any] struct { Value T // for use by client; untouched by this library // contains filtered or unexported fields }
A Ring is an element of a circular list, or ring. Rings do not have a beginning or end; a pointer to any ring element serves as reference to the entire ring. Empty rings are represented as nil Ring pointers. The zero value for a Ring is a one-element ring with a nil Value.
This list is a fork of the official Go implementation, with the change of making it generic.
func (*Ring[T]) Do ¶
func (r *Ring[T]) Do(f func(T))
Do calls function f on each element of the ring, in forward order. The behavior of Do is undefined if f changes *r.
Example ¶
// Create a new ring of size 5 r := typ.NewRing[int](5) // Get the length of the ring n := r.Len() // Initialize the ring with some integer values for i := 0; i < n; i++ { r.Value = i r = r.Next() } // Iterate through the ring and print its contents r.Do(func(p int) { fmt.Println(p) })
Output: 0 1 2 3 4
func (*Ring[T]) Len ¶
Len computes the number of elements in ring r. It executes in time proportional to the number of elements.
Example ¶
// Create a new ring of size 4 r := typ.NewRing[int](4) // Print out its length fmt.Println(r.Len())
Output: 4
func (*Ring[T]) Link ¶
Link connects ring r with ring s such that r.Next() becomes s and returns the original value for r.Next(). r must not be empty.
If r and s point to the same ring, linking them removes the elements between r and s from the ring. The removed elements form a subring and the result is a reference to that subring (if no elements were removed, the result is still the original value for r.Next(), and not nil).
If r and s point to different rings, linking them creates a single ring with the elements of s inserted after r. The result points to the element following the last element of s after insertion.
Example ¶
// Create two rings, r and s, of size 2 r := typ.NewRing[int](2) s := typ.NewRing[int](2) // Get the length of the ring lr := r.Len() ls := s.Len() // Initialize r with 0s for i := 0; i < lr; i++ { r.Value = 0 r = r.Next() } // Initialize s with 1s for j := 0; j < ls; j++ { s.Value = 1 s = s.Next() } // Link ring r and ring s rs := r.Link(s) // Iterate through the combined ring and print its contents rs.Do(func(p int) { fmt.Println(p) })
Output: 0 0 1 1
func (*Ring[T]) Move ¶
Move moves n % r.Len() elements backward (n < 0) or forward (n >= 0) in the ring and returns that ring element. r must not be empty.
Example ¶
// Create a new ring of size 5 r := typ.NewRing[int](5) // Get the length of the ring n := r.Len() // Initialize the ring with some integer values for i := 0; i < n; i++ { r.Value = i r = r.Next() } // Move the pointer forward by three steps r = r.Move(3) // Iterate through the ring and print its contents r.Do(func(p int) { fmt.Println(p) })
Output: 3 4 0 1 2
func (*Ring[T]) Next ¶
Next returns the next ring element. r must not be empty.
Example ¶
// Create a new ring of size 5 r := typ.NewRing[int](5) // Get the length of the ring n := r.Len() // Initialize the ring with some integer values for i := 0; i < n; i++ { r.Value = i r = r.Next() } // Iterate through the ring and print its contents for j := 0; j < n; j++ { fmt.Println(r.Value) r = r.Next() }
Output: 0 1 2 3 4
func (*Ring[T]) Prev ¶
Prev returns the previous ring element. r must not be empty.
Example ¶
// Create a new ring of size 5 r := typ.NewRing[int](5) // Get the length of the ring n := r.Len() // Initialize the ring with some integer values for i := 0; i < n; i++ { r.Value = i r = r.Next() } // Iterate through the ring backwards and print its contents for j := 0; j < n; j++ { r = r.Prev() fmt.Println(r.Value) }
Output: 4 3 2 1 0
func (*Ring[T]) Unlink ¶
Unlink removes n % r.Len() elements from the ring r, starting at r.Next(). If n % r.Len() == 0, r remains unchanged. The result is the removed subring. r must not be empty.
Example ¶
// Create a new ring of size 6 r := typ.NewRing[int](6) // Get the length of the ring n := r.Len() // Initialize the ring with some integer values for i := 0; i < n; i++ { r.Value = i r = r.Next() } // Unlink three elements from r, starting from r.Next() r.Unlink(3) // Iterate through the remaining ring and print its contents r.Do(func(p int) { fmt.Println(p) })
Output: 0 4 5
type Set ¶
type Set[T comparable] map[T]struct{}
Set holds a collection of values with no duplicates. Its methods are based on the mathmatical branch of set theory, and its implementation is using a Go map[T]struct{}.
Example ¶
set := make(typ.Set[string]) set.Add("A") set.Add("B") set.Add("C") for value := range set { fmt.Println("Value:", value) }
Output: Value: A Value: B Value: C
Example (SetOperations) ¶
set1 := make(typ.Set[string]) set1.Add("A") set1.Add("B") set1.Add("C") fmt.Println("set1:", set1) // {A B C} set2 := make(typ.Set[string]) set2.Add("B") set2.Add("C") set2.Add("D") fmt.Println("set2:", set2) // {B C D} fmt.Println("union:", set1.Union(set2)) // {A B C D} fmt.Println("intersect:", set1.Intersect(set2)) // {B C} fmt.Println("set diff:", set1.SetDiff(set2)) // {A} fmt.Println("sym diff:", set1.SymDiff(set2)) // {A D} // Please note: the Set.String() output is not sorted!
Output:
func CartesianProduct ¶
func CartesianProduct[TA comparable, TB comparable](a Set[TA], b Set[TB]) Set[SetProduct[TA, TB]]
CartesianProduct performs a "Cartesian product" on two sets and returns a new set. A Cartesian product of two sets is a set of all possible combinations between two sets. In mathmatics it's denoted as:
A × B
Example:
{1 2 3} × {a b c} = {1a 1b 1c 2a 2b 2c 3a 3b 3c}
This operation is noncommutative, meaning you will get different results depending on the order of the operands. In other words:
A.CartesianProduct(B) != B.CartesianProduct(A)
This noncommutative attribute of the Cartesian product operation is due to the pairs being in reverse order if you reverse the order of the operands. Example:
{1 2 3} × {a b c} = {1a 1b 1c 2a 2b 2c 3a 3b 3c} {a b c} × {1 2 3} = {a1 a2 a3 b1 b2 b3 c1 c2 c3} {1a 1b 1c 2a 2b 2c 3a 3b 3c} != {a1 a2 a3 b1 b2 b3 c1 c2 c3}
func NewSetOfKeys ¶
func NewSetOfKeys[K comparable, V any](m map[K]V) Set[K]
NewSetOfKeys returns a Set with all keys from a map added to it.
func NewSetOfSlice ¶
func NewSetOfSlice[T comparable](slice []T) Set[T]
NewSetOfSlice returns a Set with all values from a slice added to it.
func NewSetOfValues ¶
func NewSetOfValues[K comparable, V comparable](m map[K]V) Set[V]
NewSetOfValues returns a Set with all values from a map added to it.
func (Set[T]) Add ¶
Add will add an element to the set, and return true if it was added or false if the value already existed in the set.
func (Set[T]) AddSet ¶
AddSet will add all element found in specified set to this set, and return the number of values that was added.
func (Set[T]) Intersect ¶
Intersect performs an "intersection" on the sets and returns a new set. An intersection is a set of all elements that appear in both sets. In mathmatics it's denoted as:
A ∩ B
Example:
{1 2 3} ∩ {3 4 5} = {3}
This operation is commutative, meaning you will get the same result no matter the order of the operands. In other words:
A.Intersect(B) == B.Intersect(A)
func (Set[T]) Remove ¶
Remove will remove an element from the set, and return true if it was removed or false if no such value existed in the set.
func (Set[T]) RemoveSet ¶
RemoveSet will remove all element found in specified set from this set, and return the number of values that was removed.
func (Set[T]) SetDiff ¶
SetDiff performs a "set difference" on the sets and returns a new set. A set difference resembles a subtraction, where the result is a set of all elements that appears in the first set but not in the second. In mathmatics it's denoted as:
A \ B
Example:
{1 2 3} \ {3 4 5} = {1 2}
This operation is noncommutative, meaning you will get different results depending on the order of the operands. In other words:
A.SetDiff(B) != B.SetDiff(A)
func (Set[T]) Slice ¶
func (s Set[T]) Slice() []T
Slice returns a new slice of all values in the set.
func (Set[T]) SymDiff ¶
SymDiff performs a "symmetric difference" on the sets and returns a new set. A symmetric difference is the set of all elements that appear in either of the sets, but not both. In mathmatics it's commonly denoted as either:
A △ B
or
A ⊖ B
Example:
{1 2 3} ⊖ {3 4 5} = {1 2 4 5}
This operation is commutative, meaning you will get the same result no matter the order of the operands. In other words:
A.SymDiff(B) == B.SymDiff(A)
func (Set[T]) Union ¶
Union performs a "union" on the sets and returns a new set. A union is a set of all elements that appear in either set. In mathmatics it's denoted as:
A ∪ B
Example:
{1 2 3} ∪ {3 4 5} = {1 2 3 4 5}
This operation is commutative, meaning you will get the same result no matter the order of the operands. In other words:
A.Union(B) == B.Union(A)
type SetProduct ¶
type SetProduct[TA comparable, TB comparable] struct { A TA B TB }
SetProduct is the resulting type from a Cartesian product operation.
type SortOrdered ¶
type SortOrdered[T constraints.Ordered] []T
SortOrdered implements sort.Interface via the default less-than operator.
func (SortOrdered[T]) Len ¶
func (s SortOrdered[T]) Len() int
func (SortOrdered[T]) Less ¶
func (s SortOrdered[T]) Less(i, j int) bool
func (SortOrdered[T]) Swap ¶
func (s SortOrdered[T]) Swap(i, j int)
type SortedSlice ¶
type SortedSlice[T comparable] struct { // contains filtered or unexported fields }
SortedSlice is a slice of ordered values. The slice is always sorted thanks to only inserting values in a sorted order.
Example ¶
// SPDX-FileCopyrightText: 2022 Kalle Fagerberg // // SPDX-License-Identifier: MIT package main import ( "fmt" "gopkg.in/typ.v1" ) type User struct { Name string IsAdmin bool } func (u User) String() string { if u.IsAdmin { return fmt.Sprintf("%s (admin)", u.Name) } return u.Name } func (u User) AsAdmin() User { u.IsAdmin = true return u } func main() { slice := typ.NewSortedSlice([]User{}, func(a, b User) bool { return a.Name < b.Name }) johnDoe := User{Name: "John"} slice.Add(johnDoe) slice.Add(User{Name: "Jane"}) slice.Add(User{Name: "Ann"}) slice.Add(User{Name: "Wayne"}) fmt.Println(slice) fmt.Println("Contains John non-admin?", slice.Contains(johnDoe)) fmt.Println("Contains John admin?", slice.Contains(johnDoe.AsAdmin())) slice.Remove(johnDoe) fmt.Println(slice) }
Output: [Ann Jane John Wayne] Contains John non-admin? true Contains John admin? false [Ann Jane Wayne]
func NewSortedSlice ¶
func NewSortedSlice[T comparable](values []T, less func(a, b T) bool) SortedSlice[T]
NewSortedSlice returns a new sorted slice based on a slice of values and a custom less function that is used to keep values sorted. The values are sorted on insertion.
The less function is expected to return the same value for the same set of inputs for the lifetime of the sorted slice.
Note that if the less function is used when finding values to remove. If the less function cannot properly distinguish between two elements, then any of the equivalent elements may be the one being removed. The SortedSlice does not keep track of collision detection.
func (*SortedSlice[T]) Add ¶
func (s *SortedSlice[T]) Add(value T) int
func (*SortedSlice[T]) Contains ¶
func (s *SortedSlice[T]) Contains(value T) bool
func (*SortedSlice[T]) Get ¶
func (s *SortedSlice[T]) Get(index int) T
func (*SortedSlice[T]) Index ¶
func (s *SortedSlice[T]) Index(value T) int
func (*SortedSlice[T]) Len ¶
func (s *SortedSlice[T]) Len() int
func (*SortedSlice[T]) Remove ¶
func (s *SortedSlice[T]) Remove(value T) int
func (*SortedSlice[T]) RemoveAt ¶
func (s *SortedSlice[T]) RemoveAt(index int)
func (SortedSlice[T]) String ¶
func (s SortedSlice[T]) String() string
type Stack ¶
type Stack[T any] []T
Stack is a first-in-last-out collection.
Example ¶
var s Stack[string] s.Push("tripp") s.Push("trapp") s.Push("trull") fmt.Println(len(s)) // 3 fmt.Println(s.Pop()) // trull, true fmt.Println(s.Pop()) // trapp, true fmt.Println(s.Pop()) // tripp, true fmt.Println(s.Pop()) // "", false
Output: 3 trull true trapp true tripp true false
func (*Stack[T]) Peek ¶
Peek returns (but does not remove) the value on top of the stack, or false if the stack is empty.
type SyncMap ¶
type SyncMap[K comparable, V any] struct { // contains filtered or unexported fields }
SyncMap is like a Go map[K]V but is safe for concurrent use by multiple goroutines without additional locking or coordination. Loads, stores, and deletes run in amortized constant time.
The SyncMap type is specialized. Most code should use a plain Go map instead, with separate locking or coordination, for better type safety and to make it easier to maintain other invariants along with the map content.
The SyncMap type is optimized for two common use cases: (1) when the entry for a given key is only ever written once but read many times, as in caches that only grow, or (2) when multiple goroutines read, write, and overwrite entries for disjoint sets of keys. In these two cases, use of a SyncMap may significantly reduce lock contention compared to a Go map paired with a separate Mutex or RWMutex.
The zero SyncMap is empty and ready for use. A SyncMap must not be copied after first use.
This map is a fork of the official Go implementation, with the change of making it generic.
func (*SyncMap[K, V]) Delete ¶
func (m *SyncMap[K, V]) Delete(key K)
Delete deletes the value for a key.
func (*SyncMap[K, V]) Load ¶
Load returns the value stored in the map for a key, or nil if no value is present. The ok result indicates whether value was found in the map.
func (*SyncMap[K, V]) LoadAndDelete ¶
LoadAndDelete deletes the value for a key, returning the previous value if any. The loaded result reports whether the key was present.
func (*SyncMap[K, V]) LoadOrStore ¶
LoadOrStore returns the existing value for the key if present. Otherwise, it stores and returns the given value. The loaded result is true if the value was loaded, false if stored.
func (*SyncMap[K, V]) Range ¶
Range calls f sequentially for each key and value present in the map. If f returns false, range stops the iteration.
Range does not necessarily correspond to any consistent snapshot of the SyncMap's contents: no key will be visited more than once, but if the value for any key is stored or deleted concurrently, Range may reflect any mapping for that key from any point during the Range call.
Range may be O(N) with the number of elements in the map even if f returns false after a constant number of calls.