func (s *GenericVectorTypeSlice) Get(i int) GenericType {
	if i < 0 || s.start+i >= s.stop {
		panic("Index out of bounds")
	}
	return s.vector.Get(s.start + i)
}
Get returns the element at position i.
package generic_types
import (
	"encoding/binary"
	"fmt"
	"hash/crc32"
	"math"
	"unsafe"
)
const shiftSize = 5
const nodeSize = 32
const shiftBitMask = 0x1F
type commonNode interface{}
var emptyCommonNode commonNode = []commonNode{}
func uintMin(a, b uint) uint {
	if a < b {
		return a
	}
	return b
}
func newPath(shift uint, node commonNode) commonNode {
	if shift == 0 {
		return node
	}
	return newPath(shift-shiftSize, commonNode([]commonNode{node}))
}
func assertSliceOk(start, stop, len int) {
	if start < 0 {
		panic(fmt.Sprintf("Invalid slice index %d (index must be non-negative)", start))
	}
	if start > stop {
		panic(fmt.Sprintf("Invalid slice index: %d > %d", start, stop))
	}
	if stop > len {
		panic(fmt.Sprintf("Slice bounds out of range, start=%d, stop=%d, len=%d", start, stop, len))
	}
}
const upperMapLoadFactor float64 = 8.0
const lowerMapLoadFactor float64 = 2.0
const initialMapLoadFactor float64 = (upperMapLoadFactor + lowerMapLoadFactor) / 2
func hash(x []byte) uint32 {
	return crc32.ChecksumIEEE(x)
}
func nilinterhash(p unsafe.Pointer, h uintptr) uintptr
func interfaceHash(x interface{}) uint32 {
	return uint32(nilinterhash(unsafe.Pointer(&x), 0))
}
func byteHash(x byte) uint32 {
	return hash([]byte{x})
}
func uint8Hash(x uint8) uint32 {
	return byteHash(byte(x))
}
func int8Hash(x int8) uint32 {
	return uint8Hash(uint8(x))
}
func uint16Hash(x uint16) uint32 {
	bX := make([]byte, 2)
	binary.LittleEndian.PutUint16(bX, x)
	return hash(bX)
}
func int16Hash(x int16) uint32 {
	return uint16Hash(uint16(x))
}
func uint32Hash(x uint32) uint32 {
	bX := make([]byte, 4)
	binary.LittleEndian.PutUint32(bX, x)
	return hash(bX)
}
func int32Hash(x int32) uint32 {
	return uint32Hash(uint32(x))
}
func uint64Hash(x uint64) uint32 {
	bX := make([]byte, 8)
	binary.LittleEndian.PutUint64(bX, x)
	return hash(bX)
}
func int64Hash(x int64) uint32 {
	return uint64Hash(uint64(x))
}
func intHash(x int) uint32 {
	return int64Hash(int64(x))
}
func uintHash(x uint) uint32 {
	return uint64Hash(uint64(x))
}
func boolHash(x bool) uint32 {
	if x {
		return 1
	}
	return 0
}
func runeHash(x rune) uint32 {
	return int32Hash(int32(x))
}
func stringHash(x string) uint32 {
	return hash([]byte(x))
}
func float64Hash(x float64) uint32 {
	return uint64Hash(math.Float64bits(x))
}
func float32Hash(x float32) uint32 {
	return uint32Hash(math.Float32bits(x))
}
type GenericVectorType struct {
	tail  []GenericType
	root  commonNode
	len   uint
	shift uint
}
var emptyGenericVectorTypeTail = make([]GenericType, 0)
var emptyGenericVectorType *GenericVectorType = &GenericVectorType{root: emptyCommonNode, shift: shiftSize, tail: emptyGenericVectorTypeTail}
func NewGenericVectorType(items ...GenericType) *GenericVectorType {
	return emptyGenericVectorType.Append(items...)
}
func (v *GenericVectorType) Get(i int) GenericType {
	if i < 0 || uint(i) >= v.len {
		panic("Index out of bounds")
	}
	return v.sliceFor(uint(i))[i&shiftBitMask]
}
func (v *GenericVectorType) sliceFor(i uint) []GenericType {
	if i >= v.tailOffset() {
		return v.tail
	}
	node := v.root
	for level := v.shift; level > 0; level -= shiftSize {
		node = node.([]commonNode)[(i>>level)&shiftBitMask]
	}
	return node.([]GenericType)
}
func (v *GenericVectorType) tailOffset() uint {
	if v.len < nodeSize {
		return 0
	}
	return ((v.len - 1) >> shiftSize) << shiftSize
}
func (v *GenericVectorType) Set(i int, item GenericType) *GenericVectorType {
	if i < 0 || uint(i) >= v.len {
		panic("Index out of bounds")
	}
	if uint(i) >= v.tailOffset() {
		newTail := make([]GenericType, len(v.tail))
		copy(newTail, v.tail)
		newTail[i&shiftBitMask] = item
		return &GenericVectorType{root: v.root, tail: newTail, len: v.len, shift: v.shift}
	}
	return &GenericVectorType{root: v.doAssoc(v.shift, v.root, uint(i), item), tail: v.tail, len: v.len, shift: v.shift}
}
func (v *GenericVectorType) doAssoc(level uint, node commonNode, i uint, item GenericType) commonNode {
	if level == 0 {
		ret := make([]GenericType, nodeSize)
		copy(ret, node.([]GenericType))
		ret[i&shiftBitMask] = item
		return ret
	}
	ret := make([]commonNode, nodeSize)
	copy(ret, node.([]commonNode))
	subidx := (i >> level) & shiftBitMask
	ret[subidx] = v.doAssoc(level-shiftSize, ret[subidx], i, item)
	return ret
}
func (v *GenericVectorType) pushTail(level uint, parent commonNode, tailNode []GenericType) commonNode {
	subIdx := ((v.len - 1) >> level) & shiftBitMask
	parentNode := parent.([]commonNode)
	ret := make([]commonNode, subIdx+1)
	copy(ret, parentNode)
	var nodeToInsert commonNode
	if level == shiftSize {
		nodeToInsert = tailNode
	} else if subIdx < uint(len(parentNode)) {
		nodeToInsert = v.pushTail(level-shiftSize, parentNode[subIdx], tailNode)
	} else {
		nodeToInsert = newPath(level-shiftSize, tailNode)
	}
	ret[subIdx] = nodeToInsert
	return ret
}
func (v *GenericVectorType) Append(item ...GenericType) *GenericVectorType {
	result := v
	itemLen := uint(len(item))
	for insertOffset := uint(0); insertOffset < itemLen; {
		tailLen := result.len - result.tailOffset()
		tailFree := nodeSize - tailLen
		if tailFree == 0 {
			result = result.pushLeafNode(result.tail)
			result.tail = emptyGenericVectorType.tail
			tailFree = nodeSize
			tailLen = 0
		}
		batchLen := uintMin(itemLen-insertOffset, tailFree)
		newTail := make([]GenericType, 0, tailLen+batchLen)
		newTail = append(newTail, result.tail...)
		newTail = append(newTail, item[insertOffset:insertOffset+batchLen]...)
		result = &GenericVectorType{root: result.root, tail: newTail, len: result.len + batchLen, shift: result.shift}
		insertOffset += batchLen
	}
	return result
}
func (v *GenericVectorType) pushLeafNode(node []GenericType) *GenericVectorType {
	var newRoot commonNode
	newShift := v.shift
	if (v.len >> shiftSize) > (1 << v.shift) {
		newNode := newPath(v.shift, node)
		newRoot = commonNode([]commonNode{v.root, newNode})
		newShift = v.shift + shiftSize
	} else {
		newRoot = v.pushTail(v.shift, v.root, node)
	}
	return &GenericVectorType{root: newRoot, tail: v.tail, len: v.len, shift: newShift}
}
func (v *GenericVectorType) Slice(start, stop int) *GenericVectorTypeSlice {
	assertSliceOk(start, stop, v.Len())
	return &GenericVectorTypeSlice{vector: v, start: start, stop: stop}
}
func (v *GenericVectorType) Len() int {
	return int(v.len)
}
func (v *GenericVectorType) Range(f func(GenericType) bool) {
	var currentNode []GenericType
	for i := uint(0); i < v.len; i++ {
		if i&shiftBitMask == 0 {
			currentNode = v.sliceFor(i)
		}
		if !f(currentNode[i&shiftBitMask]) {
			return
		}
	}
}
func (v *GenericVectorType) ToNativeSlice() []GenericType {
	result := make([]GenericType, 0, v.len)
	for i := uint(0); i < v.len; i += nodeSize {
		result = append(result, v.sliceFor(i)...)
	}
	return result
}
type GenericVectorTypeSlice struct {
	vector      *GenericVectorType
	start, stop int
}
func NewGenericVectorTypeSlice(items ...GenericType) *GenericVectorTypeSlice {
	return &GenericVectorTypeSlice{vector: emptyGenericVectorType.Append(items...), start: 0, stop: len(items)}
}
func (s *GenericVectorTypeSlice) Len() int {
	return s.stop - s.start
}