gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/slice/unsafe/unsafe.go (about) 1 package unsafe 2 3 import ( 4 "unsafe" 5 ) 6 7 type Slice struct { 8 Ptr unsafe.Pointer 9 Len int 10 Cap int 11 } 12 13 func Struct[E any](s []E) Slice { 14 return *(*Slice)(unsafe.Pointer(&s)) 15 } 16 17 func StructP[E any](sp *[]E) *Slice { 18 return (*Slice)(unsafe.Pointer(sp)) 19 } 20 21 func StructTo[E any](s Slice) (es []E) { 22 *(*Slice)(unsafe.Pointer(&es)) = s 23 return 24 } 25 26 func Build[E any](ptr unsafe.Pointer, len, cap int) (s []E) { 27 *(*Slice)(unsafe.Pointer(&s)) = Slice{Ptr: ptr, Len: len, Cap: cap} 28 return 29 } 30 31 func Convert[EI, EO any](s []EI, len, cap int) (os []EO) { 32 *(*Slice)(unsafe.Pointer(&os)) = Slice{Ptr: (*Slice)(unsafe.Pointer(&s)).Ptr, Len: len, Cap: cap} 33 return 34 } 35 36 func String(bs []byte) string { 37 return *(*string)(unsafe.Pointer(&bs)) 38 } 39 40 func Pointer[E any](s []E) unsafe.Pointer { 41 return (*Slice)(unsafe.Pointer(&s)).Ptr 42 } 43 44 func In[E any](p *E, s []E) bool { 45 if len(s) == 0 { 46 return false 47 } 48 up := uintptr(unsafe.Pointer(p)) 49 return up >= uintptr(unsafe.Pointer(&s[0])) && 50 up <= uintptr(unsafe.Pointer(&s[len(s)-1])) 51 } 52 53 func Merge[E any](ss ...[]E) []E { 54 if len(ss) == 0 { 55 return nil 56 } 57 var e E 58 es := unsafe.Sizeof(e) 59 p := (*Slice)(unsafe.Pointer(&ss[0])).Ptr 60 sp := uintptr(p) 61 cp := sp + uintptr(cap(ss[0]))*es 62 lp := sp + uintptr(len(ss[0]))*es 63 64 min, maxC, maxL := sp, cp, lp 65 for _, s := range ss[1:] { 66 up := (*Slice)(unsafe.Pointer(&s)).Ptr 67 if sp = uintptr(up); sp > maxC { 68 return nil 69 } else if sp < min { 70 min = sp 71 p = up 72 } 73 if cp = sp + uintptr(cap(s))*es; cp < min { 74 return nil 75 } else if cp > maxC { 76 maxC = cp 77 } 78 if lp = sp + uintptr(len(s))*es; lp > maxL { 79 maxL = lp 80 } 81 } 82 return Build[E](p, int((maxL-min)/es), int((maxC-min)/es)) 83 }