package xx import ( "runtime" "strings" "unsafe" "git.brut.systems/judah/xx/mem" ) // 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 mem.Sizeof[TSrc]() < mem.Sizeof[TDst]() { panic("copy: size of src must be >= dst") } mem.Copy(unsafe.Pointer(dst), unsafe.Pointer(src), mem.Sizeof[TDst]()) return dst } // Clone returns a newly allocated shallow copy of the given value. func Clone[T any](value *T) *T { return Copy(new(T), value) } // BoolUint converts a boolean to an integer. func BoolUint(b bool) uint { return uint(*(*uint8)(unsafe.Pointer(&b))) } // CallerLocation returns the source location of the function CallerLocation is called in. func CallerLocation() (file string, line int) { _, file, line, _ = runtime.Caller(2) // @todo: I'm sure there's a better way to do this // Special-case when CallerLocation is called from main if strings.Contains(file, "runtime") && strings.Contains(file, "proc.go") { _, file, line, _ = runtime.Caller(1) } return } // HashLocation returns a hash of file and line, most likely returned from [CallerLocation]. func HashLocation(file string, line int) uint64 { const ( FNV64_PRIME uint64 = 0x100000001B3 FNV64_BIAS uint64 = 0xCBF29CE484222325 ) h := FNV64_BIAS for _, c := range file { h = (h ^ uint64(c)) * FNV64_PRIME } h = (h ^ uint64(line)) * FNV64_PRIME return h }