github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/reflect/swapper.go (about) 1 package reflect 2 3 import "unsafe" 4 5 // Some of code here has been copied from the Go sources: 6 // https://github.com/golang/go/blob/go1.15.2/src/reflect/swapper.go 7 // It has the following copyright note: 8 // 9 // Copyright 2016 The Go Authors. All rights reserved. 10 // Use of this source code is governed by a BSD-style 11 // license that can be found in the LICENSE file. 12 13 func Swapper(slice interface{}) func(i, j int) { 14 v := ValueOf(slice) 15 if v.Kind() != Slice { 16 panic(&ValueError{Method: "Swapper"}) 17 } 18 19 // Just return Nop func if nothing to swap. 20 if v.Len() < 2 { 21 return func(i, j int) {} 22 } 23 24 typ := v.typecode.Elem() 25 size := typ.Size() 26 27 header := (*sliceHeader)(v.value) 28 tmp := unsafe.Pointer(&make([]byte, size)[0]) 29 30 return func(i, j int) { 31 if uint(i) >= uint(header.len) || uint(j) >= uint(header.len) { 32 panic("reflect: slice index out of range") 33 } 34 val1 := unsafe.Add(header.data, uintptr(i)*size) 35 val2 := unsafe.Add(header.data, uintptr(j)*size) 36 memcpy(tmp, val1, size) 37 memcpy(val1, val2, size) 38 memcpy(val2, tmp, size) 39 } 40 }