mirror of
https://github.com/tursom/GoCollections.git
synced 2025-03-13 17:00:18 +08:00
51 lines
1010 B
Go
51 lines
1010 B
Go
package unsafe
|
|
|
|
import (
|
|
"reflect"
|
|
"unsafe"
|
|
|
|
"github.com/tursom/GoCollections/lang"
|
|
)
|
|
|
|
type slice struct {
|
|
array unsafe.Pointer
|
|
len int
|
|
cap int
|
|
}
|
|
|
|
func ForceCast[T any](v unsafe.Pointer) *T {
|
|
if v == nil {
|
|
return nil
|
|
} else {
|
|
return (*T)(v)
|
|
}
|
|
}
|
|
|
|
func Sizeof[T any]() uintptr {
|
|
return unsafe.Sizeof(lang.Nil[T]())
|
|
}
|
|
|
|
// AsBytes cast any slice as []byte with same pinter, real len and real cap
|
|
func AsBytes[T any](arr []T) []byte {
|
|
sarr := *ForceCast[slice](unsafe.Pointer(&arr))
|
|
typeAlign := reflect.TypeOf(lang.Nil[T]()).Align()
|
|
asBytes := unsafe.Pointer(&slice{
|
|
array: sarr.array,
|
|
len: sarr.len * typeAlign,
|
|
cap: sarr.cap * typeAlign,
|
|
})
|
|
|
|
return *ForceCast[[]byte](asBytes)
|
|
}
|
|
|
|
// AsString cast bytes as string
|
|
func AsString(bytes []byte) string {
|
|
return *ForceCast[string](unsafe.Pointer(&bytes))
|
|
}
|
|
|
|
func IndexOf[T any](s []T, v *T) int {
|
|
begin := *(*uintptr)(unsafe.Pointer(&s))
|
|
addr := uintptr(unsafe.Pointer(v))
|
|
return int((addr - begin) / reflect.TypeOf(*v).Size())
|
|
}
|