qIsNull: redo implementation

The reason for using type-punning through an integer was
to avoid compiler warnings about float comparisons. We have
now a better mechanism to suppress such warnings,
so there is no need to be "clever" and trigger UB because
of the union usage.

Drive-by change: add constexpr+noexcept because now there's no
longer UB.

Change-Id: I29f7514e39055658d4ef6c431daf5abfc660df16
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Giuseppe D'Angelo 2019-04-27 22:10:17 +02:00
parent 1b16f79bf2
commit fe57936d8c

View File

@ -902,38 +902,22 @@ Q_REQUIRED_RESULT Q_DECL_CONSTEXPR static inline Q_DECL_UNUSED bool qFuzzyIsNul
return qAbs(f) <= 0.00001f;
}
/*
This function tests a double for a null value. It doesn't
check whether the actual value is 0 or close to 0, but whether
it is binary 0, disregarding sign.
*/
Q_REQUIRED_RESULT static inline Q_DECL_UNUSED bool qIsNull(double d)
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG("-Wfloat-equal")
QT_WARNING_DISABLE_GCC("-Wfloat-equal")
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR static inline Q_DECL_UNUSED bool qIsNull(double d) noexcept
{
union U {
double d;
quint64 u;
};
U val;
val.d = d;
return (val.u & Q_UINT64_C(0x7fffffffffffffff)) == 0;
return d == 0.0;
}
/*
This function tests a float for a null value. It doesn't
check whether the actual value is 0 or close to 0, but whether
it is binary 0, disregarding sign.
*/
Q_REQUIRED_RESULT static inline Q_DECL_UNUSED bool qIsNull(float f)
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR static inline Q_DECL_UNUSED bool qIsNull(float f) noexcept
{
union U {
float f;
quint32 u;
};
U val;
val.f = f;
return (val.u & 0x7fffffff) == 0;
return f == 0.0f;
}
QT_WARNING_POP
/*
Compilers which follow outdated template instantiation rules
require a class to have a comparison operator to exist when