implement reflect.Swapper
Signed-off-by: mathetake <takeshi@tetrate.io>
Этот коммит содержится в:
родитель
ff833ef998
коммит
1dec9dcbc4
3 изменённых файлов: 341 добавлений и 1 удалений
|
@ -1,5 +1,40 @@
|
||||||
package reflect
|
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) {
|
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
|
Загрузка…
Создание таблицы
Сослаться в новой задаче