NotNil(fi, t)
}
+func setField[S, V any](in S, offset uintptr, value V) (out S) {
+ *(*V)(unsafe.Add(unsafe.Pointer(&in), offset)) = value
+ return in
+}
+
func TestIsZero(t *testing.T) {
for i, tt := range []struct {
x any
{float32(1.2), false},
{float64(0), true},
{float64(1.2), false},
- {math.Copysign(0, -1), false},
+ {math.Copysign(0, -1), true},
{complex64(0), true},
{complex64(1.2), false},
{complex128(0), true},
{complex128(1.2), false},
- {complex(math.Copysign(0, -1), 0), false},
- {complex(0, math.Copysign(0, -1)), false},
- {complex(math.Copysign(0, -1), math.Copysign(0, -1)), false},
+ {complex(math.Copysign(0, -1), 0), true},
+ {complex(0, math.Copysign(0, -1)), true},
+ {complex(math.Copysign(0, -1), math.Copysign(0, -1)), true},
{uintptr(0), true},
{uintptr(128), false},
// Array
{struct{ s []int }{[]int{1}}, false}, // incomparable struct
{struct{ Value }{}, true},
{struct{ Value }{ValueOf(0)}, false},
+ {struct{ _, a, _ uintptr }{}, true}, // comparable struct with blank fields
+ {setField(struct{ _, a, _ uintptr }{}, 0*unsafe.Sizeof(uintptr(0)), 1), true},
+ {setField(struct{ _, a, _ uintptr }{}, 1*unsafe.Sizeof(uintptr(0)), 1), false},
+ {setField(struct{ _, a, _ uintptr }{}, 2*unsafe.Sizeof(uintptr(0)), 1), true},
+ {struct{ _, a, _ func() }{}, true}, // incomparable struct with blank fields
+ {setField(struct{ _, a, _ func() }{}, 0*unsafe.Sizeof((func())(nil)), func() {}), true},
+ {setField(struct{ _, a, _ func() }{}, 1*unsafe.Sizeof((func())(nil)), func() {}), false},
+ {setField(struct{ _, a, _ func() }{}, 2*unsafe.Sizeof((func())(nil)), func() {}), true},
// UnsafePointer
{(unsafe.Pointer)(nil), true},
{(unsafe.Pointer)(new(int)), false},
case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
return v.Uint() == 0
case Float32, Float64:
- return math.Float64bits(v.Float()) == 0
+ return v.Float() == 0
case Complex64, Complex128:
- c := v.Complex()
- return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
+ return v.Complex() == 0
case Array:
// If the type is comparable, then compare directly with zero.
if v.typ().Equal != nil && v.typ().Size() <= maxZero {
n := v.NumField()
for i := 0; i < n; i++ {
- if !v.Field(i).IsZero() {
+ if !v.Field(i).IsZero() && v.Type().Field(i).Name != "_" {
return false
}
}