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  }