From d4bdd836bc75fb22f5df01f0e04b3fc1d1064066 Mon Sep 17 00:00:00 2001 From: Damian Gryski Date: Fri, 24 Mar 2023 12:19:33 -0700 Subject: [PATCH] reflect: implement and test Value.Comparable --- src/reflect/all_test.go | 4 ++++ src/reflect/type.go | 2 ++ src/reflect/value.go | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go index 6da3117c..07ead61b 100644 --- a/src/reflect/all_test.go +++ b/src/reflect/all_test.go @@ -8105,6 +8105,8 @@ func TestValue_Len(t *testing.T) { } } +*/ + func TestValue_Comparable(t *testing.T) { var a int var s []int @@ -8286,6 +8288,8 @@ func TestValue_Comparable(t *testing.T) { } } +/* + type ValueEqualTest struct { v, u any eq bool diff --git a/src/reflect/type.go b/src/reflect/type.go index ca07a326..76fe3aa4 100644 --- a/src/reflect/type.go +++ b/src/reflect/type.go @@ -958,6 +958,8 @@ func (t *rawType) Implements(u Type) bool { // Comparable returns whether values of this type can be compared to each other. func (t *rawType) Comparable() bool { switch t.Kind() { + case Invalid: + return false case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr: return true case Float32, Float64, Complex64, Complex128: diff --git a/src/reflect/value.go b/src/reflect/value.go index f0b4c390..43c0c7e6 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -217,6 +217,40 @@ func (v Value) CanAddr() bool { return v.flags&(valueFlagIndirect) == valueFlagIndirect } +func (v Value) Comparable() bool { + k := v.Kind() + switch k { + case Invalid: + return false + + case Array: + switch v.Type().Elem().Kind() { + case Interface, Array, Struct: + for i := 0; i < v.Type().Len(); i++ { + if !v.Index(i).Comparable() { + return false + } + } + return true + } + return v.Type().Comparable() + + case Interface: + return v.Elem().Comparable() + + case Struct: + for i := 0; i < v.NumField(); i++ { + if !v.Field(i).Comparable() { + return false + } + } + return true + + default: + return v.Type().Comparable() + } +} + func (v Value) Addr() Value { if !v.CanAddr() { panic("reflect.Value.Addr of unaddressable value")