func SortBYOB(x, buffer []int32) {
	if len(x) > len(buffer) {
		panic("Buffer too small")
	}
	if len(x) < 2 {
		return
	}
	from := x
	to := buffer[:len(x)]
	var key uint8
	for keyOffset := uint(0); keyOffset < bitSize; keyOffset += radix {
		sorted := true
		var prev int32 = math.MinInt32
		var offset [256]int  
		for _, elem := range from {
			key = uint8(elem >> keyOffset)
			offset[key]++
			if sorted {  
				sorted = elem >= prev
				prev = elem
			}
		}
		if sorted {  
			if (keyOffset/radix)%2 == 1 {
				copy(to, from)
			}
			return
		}
		watermark := 0
		if keyOffset == bitSize-radix {
			for i := 128; i < len(offset); i++ {
				count := offset[i]
				offset[i] = watermark
				watermark += count
			}
			for i := 0; i < 128; i++ {
				count := offset[i]
				offset[i] = watermark
				watermark += count
			}
		} else {
			for i, count := range offset {
				offset[i] = watermark
				watermark += count
			}
		}
		for _, elem := range from {
			key = uint8(elem >> keyOffset)  
			to[offset[key]] = elem          
			offset[key]++
		}
		from, to = to, from
	}
}
SortBYOB sorts a []int32 using a Radix sort, using supplied buffer space. Panics if
len(x) does not equal len(buffer). Uses radix sort even on small slices.
package zint32
import (
	"math"
	"sort"
)
const (
	MinSize      = 128
	radix   uint = 8
	bitSize uint = 32
)
func Sort(x []int32) {
	if len(x) < MinSize {
		sort.Slice(x, func(i, j int) bool { return x[i] < x[j] })
	} else {
		buffer := make([]int32, len(x))
		SortBYOB(x, buffer)
	}
}
func SortCopy(x []int32) []int32 {
	y := make([]int32, len(x))
	copy(y, x)
	Sort(y)
	return y
}