Merge 4bb127a240
into d8f796af33
This commit is contained in:
commit
491b9fb564
|
@ -254,7 +254,7 @@ func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface {
|
||||||
// directly, or whether it should be considered for sorting by surrogate keys
|
// directly, or whether it should be considered for sorting by surrogate keys
|
||||||
// (if the ConfigState allows it).
|
// (if the ConfigState allows it).
|
||||||
func canSortSimply(kind reflect.Kind) bool {
|
func canSortSimply(kind reflect.Kind) bool {
|
||||||
// This switch parallels valueSortLess, except for the default case.
|
// This switch parallels valueLessEqual, except for the default case.
|
||||||
switch kind {
|
switch kind {
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
return true
|
return true
|
||||||
|
@ -289,43 +289,55 @@ func (s *valuesSorter) Swap(i, j int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// valueSortLess returns whether the first value should sort before the second
|
// valueLessEqual returns whether the first value should sort before the second
|
||||||
// value. It is used by valueSorter.Less as part of the sort.Interface
|
// value. It is used by valueSorter.Less as part of the sort.Interface
|
||||||
// implementation.
|
// implementation.
|
||||||
func valueSortLess(a, b reflect.Value) bool {
|
func valueLessEqual(a, b reflect.Value) (less, equal bool) {
|
||||||
switch a.Kind() {
|
switch a.Kind() {
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
return !a.Bool() && b.Bool()
|
av, bv := a.Bool(), b.Bool()
|
||||||
|
return !av && bv, av == bv
|
||||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||||
return a.Int() < b.Int()
|
av, bv := a.Int(), b.Int()
|
||||||
|
return av < bv, av == bv
|
||||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||||
return a.Uint() < b.Uint()
|
av, bv := a.Uint(), b.Uint()
|
||||||
|
return av < bv, av == bv
|
||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float32, reflect.Float64:
|
||||||
return a.Float() < b.Float()
|
av, bv := a.Float(), b.Float()
|
||||||
|
return av < bv, av == bv
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
return a.String() < b.String()
|
av, bv := a.String(), b.String()
|
||||||
|
return av < bv, av == bv
|
||||||
case reflect.Uintptr:
|
case reflect.Uintptr:
|
||||||
return a.Uint() < b.Uint()
|
av, bv := a.Uint(), b.Uint()
|
||||||
|
return av < bv, av == bv
|
||||||
case reflect.Array:
|
case reflect.Array:
|
||||||
// Compare the contents of both arrays.
|
// Compare the contents of both arrays.
|
||||||
l := a.Len()
|
l := a.Len()
|
||||||
for i := 0; i < l; i++ {
|
for i := 0; i < l; i++ {
|
||||||
av := a.Index(i)
|
av := a.Index(i)
|
||||||
bv := b.Index(i)
|
bv := b.Index(i)
|
||||||
if av.Interface() == bv.Interface() {
|
|
||||||
|
less, equal := valueLessEqual(av, bv)
|
||||||
|
if equal {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return valueSortLess(av, bv)
|
|
||||||
|
return less, false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return a.String() < b.String()
|
|
||||||
|
av, bv := a.String(), b.String()
|
||||||
|
return av < bv, av == bv
|
||||||
}
|
}
|
||||||
|
|
||||||
// Less returns whether the value at index i should sort before the
|
// Less returns whether the value at index i should sort before the
|
||||||
// value at index j. It is part of the sort.Interface implementation.
|
// value at index j. It is part of the sort.Interface implementation.
|
||||||
func (s *valuesSorter) Less(i, j int) bool {
|
func (s *valuesSorter) Less(i, j int) bool {
|
||||||
if s.strings == nil {
|
if s.strings == nil {
|
||||||
return valueSortLess(s.values[i], s.values[j])
|
less, _ := valueLessEqual(s.values[i], s.values[j])
|
||||||
|
return less
|
||||||
}
|
}
|
||||||
return s.strings[i] < s.strings[j]
|
return s.strings[i] < s.strings[j]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1039,4 +1039,34 @@ func TestDumpSortedKeys(t *testing.T) {
|
||||||
t.Errorf("Sorted keys mismatch:\n %v %v", s, expected)
|
t.Errorf("Sorted keys mismatch:\n %v %v", s, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type structWithUnexportedMapWithArrayKey struct {
|
||||||
|
f map[[3]byte]int
|
||||||
|
}
|
||||||
|
s = cfg.Sdump(structWithUnexportedMapWithArrayKey{
|
||||||
|
map[[3]byte]int{
|
||||||
|
[3]byte{0x1, 0x2, 0x3}: 2,
|
||||||
|
[3]byte{0x1, 0x3, 0x2}: 3,
|
||||||
|
[3]byte{0x1, 0x2, 0x2}: 1,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
expected =
|
||||||
|
`(spew_test.structWithUnexportedMapWithArrayKey) {
|
||||||
|
f: (map[[3]uint8]int) (len=3) {
|
||||||
|
([3]uint8) (len=3 cap=3) {
|
||||||
|
00000000 01 02 02 |...|
|
||||||
|
}: (int) 1,
|
||||||
|
([3]uint8) (len=3 cap=3) {
|
||||||
|
00000000 01 02 03 |...|
|
||||||
|
}: (int) 2,
|
||||||
|
([3]uint8) (len=3 cap=3) {
|
||||||
|
00000000 01 03 02 |...|
|
||||||
|
}: (int) 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
if s != expected {
|
||||||
|
t.Errorf("Sorted keys mismatch:\n %v %v", s, expected)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue