package xx import ( "unsafe" ) // New returns a newly allocated value with an initial value. func New[T any](expr T) *T { p := new(T) *p = expr return p } // Bitcast performs a bit conversion between two types of the same size. // // Bitcast panics if the sizes of the types differ. func Bitcast[TOut any, TIn any](value TIn) TOut { if SizeOf[TOut]() != SizeOf[TIn]() { panic("bitcast: sizes of types must match") } return *((*TOut)(unsafe.Pointer(&value))) } // Copy copies src number of bytes into dst. // Returns dst. // // Copy panics if src is smaller than dst. func Copy[TDst any, TSrc any](dst *TDst, src *TSrc) *TDst { if SizeOf[TSrc]() < SizeOf[TDst]() { panic("copy: size of src must be >= dst") } MemCopy(unsafe.Pointer(dst), unsafe.Pointer(src), SizeOf[TDst]()) return dst } // MemCopy copies size number of bytes from src into dst. // Returns dst. func MemCopy(dst, src unsafe.Pointer, size uintptr) unsafe.Pointer { copy(unsafe.Slice((*byte)(dst), size), unsafe.Slice((*byte)(src), size)) return dst } // SizeOf returns the size in bytes of the given type. // // Not to be confused with [unsafe.Sizeof] which returns the size of an expression. func SizeOf[T any]() uintptr { var zero T return unsafe.Sizeof(zero) }