github.com/tursom/GoCollections@v0.3.10/unsafe/unsafe.go (about) 1 package unsafe 2 3 import ( 4 "reflect" 5 "unsafe" 6 ) 7 8 type slice struct { 9 array unsafe.Pointer 10 len int 11 cap int 12 } 13 14 type iface struct { 15 tab *struct{} 16 data unsafe.Pointer 17 } 18 19 func Nil[T any]() T { 20 var n T 21 return n 22 } 23 24 func ForceCast[T any](v unsafe.Pointer) *T { 25 if v == nil { 26 return nil 27 } else { 28 return (*T)(v) 29 } 30 } 31 32 func Sizeof[T any]() uintptr { 33 return unsafe.Sizeof(Nil[T]()) 34 } 35 36 // AsBytes cast any slice as []byte with same pinter, real len and real cap 37 func AsBytes[T any](arr []T) []byte { 38 sarr := *ForceCast[slice](unsafe.Pointer(&arr)) 39 typeAlign := reflect.TypeOf(Nil[T]()).Align() 40 asBytes := unsafe.Pointer(&slice{ 41 array: sarr.array, 42 len: sarr.len * typeAlign, 43 cap: sarr.cap * typeAlign, 44 }) 45 46 return *ForceCast[[]byte](asBytes) 47 } 48 49 func AsBytes1[T any](value *T) []byte { 50 typeAlign := reflect.TypeOf(value).Align() 51 asBytes := unsafe.Pointer(&slice{ 52 array: unsafe.Pointer(value), 53 len: typeAlign, 54 cap: typeAlign, 55 }) 56 57 return *ForceCast[[]byte](asBytes) 58 } 59 60 func AsBytes2(value any) []byte { 61 typeAlign := reflect.TypeOf(value).Align() 62 asBytes := unsafe.Pointer(&slice{ 63 array: InterfacePointer(value), 64 len: typeAlign, 65 cap: typeAlign, 66 }) 67 68 return *ForceCast[[]byte](asBytes) 69 } 70 71 func InterfacePointer(i any) unsafe.Pointer { 72 return ForceCast[iface](unsafe.Pointer(&i)).data 73 } 74 75 func InterfaceForceCast[T any](i any) *T { 76 return ForceCast[T](ForceCast[iface](unsafe.Pointer(&i)).data) 77 } 78 79 // AsString cast bytes as string 80 func AsString(bytes []byte) string { 81 return *ForceCast[string](unsafe.Pointer(&bytes)) 82 } 83 84 func IndexOf[T any](s []T, v *T) int { 85 begin := *(*uintptr)(unsafe.Pointer(&s)) 86 addr := uintptr(unsafe.Pointer(v)) 87 return int((addr - begin) / reflect.TypeOf(*v).Size()) 88 }