mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-09 21:43:40 +00:00
reflect: Add Value.IsZero() method
Add Value.IsZero() with tests, largely copied from the Go source code. The tests were altered to remove the parts calling `Zero()` as that is still unimplemented in tinygo, and to remove a test that tries to catch a panic which is not supported on wasi. A new case for `UnsafePointer` in `Value.IsNil()` was required for unsafe.Pointer tests to pass. Link: https://cs.opensource.google/go/go/+/refs/tags/go1.19.3:src/reflect/value.go;l=1568 Link: https://cs.opensource.google/go/go/+/refs/tags/go1.19.3:src/reflect/all_test.go;l=1322 Co-authored-by: Cam Hutchison <camh@xdna.net>
This commit is contained in:
+42
-1
@@ -1,6 +1,7 @@
|
||||
package reflect
|
||||
|
||||
import (
|
||||
"math"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@@ -91,6 +92,46 @@ func (v Value) Type() Type {
|
||||
return v.typecode
|
||||
}
|
||||
|
||||
// IsZero reports whether v is the zero value for its type.
|
||||
// It panics if the argument is invalid.
|
||||
func (v Value) IsZero() bool {
|
||||
switch v.Kind() {
|
||||
case Bool:
|
||||
return !v.Bool()
|
||||
case Int, Int8, Int16, Int32, Int64:
|
||||
return v.Int() == 0
|
||||
case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
|
||||
return v.Uint() == 0
|
||||
case Float32, Float64:
|
||||
return math.Float64bits(v.Float()) == 0
|
||||
case Complex64, Complex128:
|
||||
c := v.Complex()
|
||||
return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
|
||||
case Array:
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
if !v.Index(i).IsZero() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case Chan, Func, Interface, Map, Pointer, Slice, UnsafePointer:
|
||||
return v.IsNil()
|
||||
case String:
|
||||
return v.Len() == 0
|
||||
case Struct:
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
if !v.Field(i).IsZero() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
default:
|
||||
// This should never happens, but will act as a safeguard for
|
||||
// later, as a default value doesn't makes sense here.
|
||||
panic(&ValueError{"reflect.Value.IsZero", v.Kind()})
|
||||
}
|
||||
}
|
||||
|
||||
// Internal function only, do not use.
|
||||
//
|
||||
// RawType returns the raw, underlying type code. It is used in the runtime
|
||||
@@ -107,7 +148,7 @@ func (v Value) Kind() Kind {
|
||||
// is not a channel, map, pointer, function, slice, or interface.
|
||||
func (v Value) IsNil() bool {
|
||||
switch v.Kind() {
|
||||
case Chan, Map, Ptr:
|
||||
case Chan, Map, Ptr, UnsafePointer:
|
||||
return v.pointer() == nil
|
||||
case Func:
|
||||
if v.value == nil {
|
||||
|
||||
Reference in New Issue
Block a user