v8.run/go/exp@v0.0.26-0.20230226010534-afcdbd3f782d/fastrand/shuffle.go (about)

     1  package fastrand
     2  
     3  import (
     4  	"math/rand"
     5  )
     6  
     7  func ShuffleSlice[T any](s []T) {
     8  	if len(s) > (1<<32 - 1) {
     9  		rand.Shuffle(len(s), func(i, j int) {
    10  			s[i], s[j] = s[j], s[i]
    11  		})
    12  		// TODO: Implement own shuffle for slices with length > (1<<32 - 1)
    13  	}
    14  	// var zero T
    15  	// elemSize := unsafe.Sizeof(zero)
    16  	// data := (*reflect.SliceHeader)(unsafe.Pointer(&s)).Data
    17  	for i := len(s); i > 1; i-- {
    18  		p := Uint32n(uint32(i))
    19  		// Unsafe swap
    20  		// tmp = *(*T)(unsafe.Pointer(data + uintptr(i-1)*elemSize))
    21  		// *(*T)(unsafe.Pointer(data + uintptr(i-1)*elemSize)) = *(*T)(unsafe.Pointer(data + uintptr(p)*elemSize))
    22  		// *(*T)(unsafe.Pointer(data + uintptr(p)*elemSize)) = tmp
    23  
    24  		// Safe swap
    25  		s[i-1], s[p] = s[p], s[i-1]
    26  	}
    27  }