package coll import "fmt" const ( DefaultSize = 4 ) type Vector[T any] []T func New[T any]() Vector[T] { return WithCap[T](DefaultSize) } func WithCap[T any](capacity int) Vector[T] { return make(Vector[T], 0, capacity) } func From[T any](v []T) Vector[T] { return Vector[T](v) } func (v Vector[T]) Push(t T) Vector[T] { if len(v) == cap(v) { v = v.upsize() } v = v[:len(v)+1] v[len(v)-1] = t return v } func (v Vector[T]) Append(t ...T) Vector[T] { if cap(v)-len(v) < len(t) { v = v.upsizeSpecific(len(t)) } startLen := len(v) v = v[:len(v)+len(t)] var tIndex int for index := startLen; index < cap(v); index++ { v[index] = t[tIndex] tIndex++ } return v } func (v Vector[T]) Remove(index int) Vector[T] { return From(append(v[:index], v[index+1:]...)) } // Faster remove function that can be used on vectors where ordering doesn't matter func (v Vector[T]) RemoveUnordered(index int) Vector[T] { v[index] = v[len(v)-1] return v[:len(v)-1] } func (v Vector[T]) upsize() Vector[T] { return v.upsizeSpecific(cap(v)) } func (v Vector[T]) upsizeSpecific(extraSize int) Vector[T] { resized := make([]T, len(v), cap(v)+extraSize) copy(resized, v) return resized } func (v Vector[T]) panicIndex(index int) { min := -1 if len(v) != 0 { min = 0 } panic(fmt.Sprintf("index %d out of range [%d;%d)", index, min, len(v))) } // GetSoft tries to get the requested index, or returns a default value if // it's out of range func (v Vector[T]) GetSoft(index int) T { var result T if index < 0 || index >= len(v) { return result } return v[index] } func (v Vector[T]) Get(index int) T { if index < 0 || index >= len(v) { v.panicIndex(index) } return v[index] } func (v Vector[T]) Set(index int, value T) Vector[T] { if index < 0 || index >= len(v) { v.panicIndex(index) } v[index] = value return v } func (v Vector[T]) Pop() (T, Vector[T]) { t := v[len(v)-1] return t, v[:len(v)-1] } func (v Vector[T]) Sub(start, end int) Vector[T] { if start >= len(v) { v.panicIndex(start) } if end >= len(v) { v.panicIndex(end) } if start < 0 { return From(v[:end]) } if end < 0 { return From(v[start:]) } return From(v[start:end]) } func (v Vector[T]) Filter(f func(T) bool) Vector[T] { return Filter(v, f) } func (v Vector[T]) Any(f func(T) bool) bool { return Any(v, f) } func (v Vector[T]) Take(howMany int) Vector[T] { return Take(v, howMany) } func (v Vector[T]) Clone() Vector[T] { clone := make([]T, len(v)) copy(clone, v) v = clone return v }