github.com/gotranspile/cxgo@v0.3.7/runtime/libc/sort.go (about) 1 package libc 2 3 import ( 4 "sort" 5 "unsafe" 6 ) 7 8 type ptrSort struct { 9 base unsafe.Pointer 10 tmp []byte 11 num int 12 size int 13 cmp func(a, b unsafe.Pointer) int32 14 } 15 16 func (p *ptrSort) Len() int { 17 return p.num 18 } 19 20 func (p *ptrSort) elem(i int) unsafe.Pointer { 21 if i < 0 || i >= p.num { 22 panic("index out of bounds") 23 } 24 return unsafe.Pointer(uintptr(p.base) + uintptr(i*p.size)) 25 } 26 27 func (p *ptrSort) elems(i int) []byte { 28 return unsafe.Slice((*byte)(p.elem(i)), p.size) 29 } 30 31 func (p *ptrSort) Less(i, j int) bool { 32 a, b := p.elem(i), p.elem(j) 33 return p.cmp(a, b) < 0 34 } 35 36 func (p *ptrSort) Swap(i, j int) { 37 a, b := p.elems(i), p.elems(j) 38 copy(p.tmp, a) 39 copy(a, b) 40 copy(b, p.tmp) 41 } 42 43 func Sort(base unsafe.Pointer, num, size uint32, compar func(a, b unsafe.Pointer) int32) { 44 sort.Sort(&ptrSort{ 45 tmp: make([]byte, size), 46 base: base, num: int(num), size: int(size), cmp: compar, 47 }) 48 } 49 50 func Search(key, base unsafe.Pointer, num, size uint32, compar func(a, b unsafe.Pointer) int32) unsafe.Pointer { 51 i := sort.Search(int(num), func(i int) bool { 52 cur := unsafe.Pointer(uintptr(base) + uintptr(i)*uintptr(size)) 53 return compar(key, cur) < 0 54 }) 55 i-- 56 if i < 0 { 57 return nil 58 } 59 cur := unsafe.Pointer(uintptr(base) + uintptr(i)*uintptr(size)) 60 if compar(key, cur) == 0 { 61 return cur 62 } 63 return nil 64 }