internal/lib/reflect: Value.IsZero

This commit is contained in:
visualfc
2024-11-14 10:35:01 +08:00
parent 792716eefc
commit 5fb8503fd2

View File

@@ -22,6 +22,7 @@ package reflect
import ( import (
"errors" "errors"
"math"
"unsafe" "unsafe"
"github.com/goplus/llgo/c/bitcast" "github.com/goplus/llgo/c/bitcast"
@@ -843,66 +844,63 @@ func (v Value) IsValid() bool {
// IsZero reports whether v is the zero value for its type. // IsZero reports whether v is the zero value for its type.
// It panics if the argument is invalid. // It panics if the argument is invalid.
func (v Value) IsZero() bool { func (v Value) IsZero() bool {
/* switch v.kind() {
switch v.kind() { case Bool:
case Bool: return !v.Bool()
return !v.Bool() case Int, Int8, Int16, Int32, Int64:
case Int, Int8, Int16, Int32, Int64: return v.Int() == 0
return v.Int() == 0 case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr: return v.Uint() == 0
return v.Uint() == 0 case Float32, Float64:
case Float32, Float64: return math.Float64bits(v.Float()) == 0
return math.Float64bits(v.Float()) == 0 case Complex64, Complex128:
case Complex64, Complex128: c := v.Complex()
c := v.Complex() return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0 case Array:
case Array: // If the type is comparable, then compare directly with zero.
// If the type is comparable, then compare directly with zero. if v.typ().Equal != nil && v.typ().Size() <= maxZero {
if v.typ().Equal != nil && v.typ().Size() <= maxZero { if v.flag&flagIndir == 0 {
if v.flag&flagIndir == 0 { return v.ptr == nil
return v.ptr == nil
}
// v.ptr doesn't escape, as Equal functions are compiler generated
// and never escape. The escape analysis doesn't know, as it is a
// function pointer call.
return v.typ().Equal(noescape(v.ptr), unsafe.Pointer(&zeroVal[0]))
} }
// v.ptr doesn't escape, as Equal functions are compiler generated
n := v.Len() // and never escape. The escape analysis doesn't know, as it is a
for i := 0; i < n; i++ { // function pointer call.
if !v.Index(i).IsZero() { return v.typ().Equal(noescape(v.ptr), unsafe.Pointer(&zeroVal[0]))
return false
}
}
return true
case Chan, Func, Interface, Map, Pointer, Slice, UnsafePointer:
return v.IsNil()
case String:
return v.Len() == 0
case Struct:
// If the type is comparable, then compare directly with zero.
if v.typ().Equal != nil && v.typ().Size() <= maxZero {
if v.flag&flagIndir == 0 {
return v.ptr == nil
}
// See noescape justification above.
return v.typ().Equal(noescape(v.ptr), unsafe.Pointer(&zeroVal[0]))
}
n := v.NumField()
for i := 0; i < n; i++ {
if !v.Field(i).IsZero() {
return false
}
}
return true
default:
// This should never happen, but will act as a safeguard for later,
// as a default value doesn't makes sense here.
panic(&ValueError{"reflect.Value.IsZero", v.Kind()})
} }
*/
panic("todo: reflect.Value.IsZero") n := v.Len()
for i := 0; i < n; 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:
// If the type is comparable, then compare directly with zero.
if v.typ().Equal != nil && v.typ().Size() <= maxZero {
if v.flag&flagIndir == 0 {
return v.ptr == nil
}
// See noescape justification above.
return v.typ().Equal(noescape(v.ptr), unsafe.Pointer(&zeroVal[0]))
}
n := v.NumField()
for i := 0; i < n; i++ {
if !v.Field(i).IsZero() {
return false
}
}
return true
default:
// This should never happen, but will act as a safeguard for later,
// as a default value doesn't makes sense here.
panic(&ValueError{"reflect.Value.IsZero", v.Kind()})
}
} }
// SetZero sets v to be the zero value of v's type. // SetZero sets v to be the zero value of v's type.
@@ -1793,6 +1791,9 @@ func Zero(typ Type) Value {
// must match declarations in runtime/map.go. // must match declarations in runtime/map.go.
const maxZero = runtime.MaxZero const maxZero = runtime.MaxZero
//go:linkname zeroVal runtime.ZeroVal
var zeroVal [maxZero]byte
// New returns a Value representing a pointer to a new zero value // New returns a Value representing a pointer to a new zero value
// for the specified type. That is, the returned Value's Type is PointerTo(typ). // for the specified type. That is, the returned Value's Type is PointerTo(typ).
func New(typ Type) Value { func New(typ Type) Value {