implement reflect.Swapper
Signed-off-by: mathetake <takeshi@tetrate.io>
Этот коммит содержится в:
родитель
ff833ef998
коммит
1dec9dcbc4
3 изменённых файлов: 341 добавлений и 1 удалений
|
@ -1,5 +1,40 @@
|
|||
package reflect
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// Some of code here has been copied from the Go sources:
|
||||
// https://github.com/golang/go/blob/go1.15.2/src/reflect/swapper.go
|
||||
// It has the following copyright note:
|
||||
//
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
func Swapper(slice interface{}) func(i, j int) {
|
||||
panic("unimplemented: reflect.Swapper")
|
||||
v := ValueOf(slice)
|
||||
if v.Kind() != Slice {
|
||||
panic(&ValueError{Method: "Swapper"})
|
||||
}
|
||||
|
||||
// Just return Nop func if nothing to swap.
|
||||
if v.Len() < 2 {
|
||||
return func(i, j int) {}
|
||||
}
|
||||
|
||||
typ := v.Type().Elem()
|
||||
size := typ.Size()
|
||||
|
||||
header := (*SliceHeader)(v.value)
|
||||
tmp := unsafe.Pointer(&make([]byte, size)[0])
|
||||
|
||||
return func(i, j int) {
|
||||
if uint(i) >= uint(header.Len) || uint(j) >= uint(header.Len) {
|
||||
panic("reflect: slice index out of range")
|
||||
}
|
||||
val1 := unsafe.Pointer(header.Data + uintptr(i)*size)
|
||||
val2 := unsafe.Pointer(header.Data + uintptr(j)*size)
|
||||
memcpy(tmp, val1, size)
|
||||
memcpy(val1, val2, size)
|
||||
memcpy(val2, tmp, size)
|
||||
}
|
||||
}
|
||||
|
|
183
testdata/sort.go
предоставленный
Обычный файл
183
testdata/sort.go
предоставленный
Обычный файл
|
@ -0,0 +1,183 @@
|
|||
package main
|
||||
|
||||
import "sort"
|
||||
|
||||
// sort.Slice implicitly uses reflect.Swapper
|
||||
|
||||
func strings() {
|
||||
data := []string{"aaaa", "cccc", "bbb", "fff", "ggg"}
|
||||
sort.Slice(data, func(i, j int) bool {
|
||||
return data[i] > data[j]
|
||||
})
|
||||
println("strings")
|
||||
for _, d := range data {
|
||||
println(d)
|
||||
}
|
||||
}
|
||||
|
||||
func int64s() {
|
||||
sd := []int64{1, 6, 3, 2, 1923, 123, -123, -29, 3, 0, 1}
|
||||
sort.Slice(sd, func(i, j int) bool {
|
||||
return sd[i] > sd[j]
|
||||
})
|
||||
println("int64s")
|
||||
for _, d := range sd {
|
||||
println(d)
|
||||
}
|
||||
|
||||
ud := []uint64{1, 6, 3, 2, 1923, 123, 29, 3, 0, 1}
|
||||
sort.Slice(ud, func(i, j int) bool {
|
||||
return ud[i] > ud[j]
|
||||
})
|
||||
println("uint64s")
|
||||
for _, d := range ud {
|
||||
println(d)
|
||||
}
|
||||
}
|
||||
|
||||
func int32s() {
|
||||
sd := []int32{1, 6, 3, 2, 1923, 123, -123, -29, 3, 0, 1}
|
||||
sort.Slice(sd, func(i, j int) bool {
|
||||
return sd[i] > sd[j]
|
||||
})
|
||||
println("int32s")
|
||||
for _, d := range sd {
|
||||
println(d)
|
||||
}
|
||||
|
||||
ud := []uint32{1, 6, 3, 2, 1923, 123, 29, 3, 0, 1}
|
||||
sort.Slice(ud, func(i, j int) bool {
|
||||
return ud[i] > ud[j]
|
||||
})
|
||||
println("uint32s")
|
||||
for _, d := range ud {
|
||||
println(d)
|
||||
}
|
||||
}
|
||||
|
||||
func int16s() {
|
||||
sd := []int16{1, 6, 3, 2, 1923, 123, -123, -29, 3, 0, 1}
|
||||
sort.Slice(sd, func(i, j int) bool {
|
||||
return sd[i] > sd[j]
|
||||
})
|
||||
println("int16s")
|
||||
for _, d := range sd {
|
||||
println(d)
|
||||
}
|
||||
|
||||
ud := []uint16{1, 6, 3, 2, 1923, 123, 29, 3, 0, 1}
|
||||
sort.Slice(ud, func(i, j int) bool {
|
||||
return ud[i] > ud[j]
|
||||
})
|
||||
println("uint16s")
|
||||
for _, d := range ud {
|
||||
println(d)
|
||||
}
|
||||
}
|
||||
|
||||
func int8s() {
|
||||
sd := []int8{1, 6, 3, 2, 123, -123, -29, 3, 0, 1}
|
||||
sort.Slice(sd, func(i, j int) bool {
|
||||
return sd[i] > sd[j]
|
||||
})
|
||||
println("int8s")
|
||||
for _, d := range sd {
|
||||
println(d)
|
||||
}
|
||||
|
||||
ud := []uint8{1, 6, 3, 2, 123, 29, 3, 0, 1}
|
||||
sort.Slice(ud, func(i, j int) bool {
|
||||
return ud[i] > ud[j]
|
||||
})
|
||||
println("uint8s")
|
||||
for _, d := range ud {
|
||||
println(d)
|
||||
}
|
||||
}
|
||||
|
||||
func ints() {
|
||||
sd := []int{1, 6, 3, 2, 123, -123, -29, 3, 0, 1}
|
||||
sort.Slice(sd, func(i, j int) bool {
|
||||
return sd[i] > sd[j]
|
||||
})
|
||||
println("ints")
|
||||
for _, d := range sd {
|
||||
println(d)
|
||||
}
|
||||
|
||||
ud := []uint{1, 6, 3, 2, 123, 29, 3, 0, 1}
|
||||
sort.Slice(ud, func(i, j int) bool {
|
||||
return ud[i] > ud[j]
|
||||
})
|
||||
println("uints")
|
||||
for _, d := range ud {
|
||||
println(d)
|
||||
}
|
||||
}
|
||||
|
||||
func structs() {
|
||||
type s struct {
|
||||
name string
|
||||
a uint64
|
||||
b uint32
|
||||
c uint16
|
||||
d int
|
||||
e *struct {
|
||||
aa uint16
|
||||
bb int
|
||||
}
|
||||
}
|
||||
|
||||
data := []s{
|
||||
{
|
||||
name: "struct 1",
|
||||
d: 100,
|
||||
e: &struct {
|
||||
aa uint16
|
||||
bb int
|
||||
}{aa: 123, bb: -10},
|
||||
},
|
||||
{
|
||||
name: "struct 2",
|
||||
d: 1,
|
||||
e: &struct {
|
||||
aa uint16
|
||||
bb int
|
||||
}{aa: 15, bb: 10},
|
||||
},
|
||||
{
|
||||
name: "struct 3",
|
||||
d: 10,
|
||||
e: &struct {
|
||||
aa uint16
|
||||
bb int
|
||||
}{aa: 31, bb: -1030},
|
||||
},
|
||||
{
|
||||
name: "struct 4",
|
||||
e: &struct {
|
||||
aa uint16
|
||||
bb int
|
||||
}{},
|
||||
},
|
||||
}
|
||||
sort.Slice(data, func(i, j int) bool {
|
||||
di := data[i]
|
||||
dj := data[j]
|
||||
return di.d*di.e.bb > dj.d*dj.e.bb
|
||||
})
|
||||
println("structs")
|
||||
for _, d := range data {
|
||||
println(d.name)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
strings()
|
||||
int64s()
|
||||
int32s()
|
||||
int16s()
|
||||
int8s()
|
||||
ints()
|
||||
structs()
|
||||
}
|
122
testdata/sort.txt
предоставленный
Обычный файл
122
testdata/sort.txt
предоставленный
Обычный файл
|
@ -0,0 +1,122 @@
|
|||
strings
|
||||
ggg
|
||||
fff
|
||||
cccc
|
||||
bbb
|
||||
aaaa
|
||||
int64s
|
||||
1923
|
||||
123
|
||||
6
|
||||
3
|
||||
3
|
||||
2
|
||||
1
|
||||
1
|
||||
0
|
||||
-29
|
||||
-123
|
||||
uint64s
|
||||
1923
|
||||
123
|
||||
29
|
||||
6
|
||||
3
|
||||
3
|
||||
2
|
||||
1
|
||||
1
|
||||
0
|
||||
int32s
|
||||
1923
|
||||
123
|
||||
6
|
||||
3
|
||||
3
|
||||
2
|
||||
1
|
||||
1
|
||||
0
|
||||
-29
|
||||
-123
|
||||
uint32s
|
||||
1923
|
||||
123
|
||||
29
|
||||
6
|
||||
3
|
||||
3
|
||||
2
|
||||
1
|
||||
1
|
||||
0
|
||||
int16s
|
||||
1923
|
||||
123
|
||||
6
|
||||
3
|
||||
3
|
||||
2
|
||||
1
|
||||
1
|
||||
0
|
||||
-29
|
||||
-123
|
||||
uint16s
|
||||
1923
|
||||
123
|
||||
29
|
||||
6
|
||||
3
|
||||
3
|
||||
2
|
||||
1
|
||||
1
|
||||
0
|
||||
int8s
|
||||
123
|
||||
6
|
||||
3
|
||||
3
|
||||
2
|
||||
1
|
||||
1
|
||||
0
|
||||
-29
|
||||
-123
|
||||
uint8s
|
||||
123
|
||||
29
|
||||
6
|
||||
3
|
||||
3
|
||||
2
|
||||
1
|
||||
1
|
||||
0
|
||||
ints
|
||||
123
|
||||
6
|
||||
3
|
||||
3
|
||||
2
|
||||
1
|
||||
1
|
||||
0
|
||||
-29
|
||||
-123
|
||||
uints
|
||||
123
|
||||
29
|
||||
6
|
||||
3
|
||||
3
|
||||
2
|
||||
1
|
||||
1
|
||||
0
|
||||
structs
|
||||
struct 2
|
||||
struct 4
|
||||
struct 1
|
||||
struct 3
|
Загрузка…
Создание таблицы
Сослаться в новой задаче