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  }