From 72c68f5f220d691b475b42374b40039b99620876 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 10 Aug 2015 13:22:38 +0200 Subject: Reimplement qt_inf/qt_snan/qt_qnan using std::numeric_limits. Qt already assumes a working IEEE-754 implementation, so we can rely on a working std::numeric_limits. This patch also gets rid of three cases of type-punning with unions (which is undefined behavior in C++). Change-Id: Ic3747f49d55e372960abf2091c1d5752c1eccdff Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- src/corelib/global/qnumeric_p.h | 84 +++++++---------------------------------- 1 file changed, 14 insertions(+), 70 deletions(-) (limited to 'src/corelib/global/qnumeric_p.h') diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index b56cdef939..650c32d44b 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -107,85 +107,29 @@ static inline bool isfinite(float f) { return std::isfinite(f); } #endif } -#if !defined(Q_CC_MIPS) - -static const union { unsigned char c[8]; double d; } qt_be_inf_bytes = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } }; -static const union { unsigned char c[8]; double d; } qt_le_inf_bytes = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } }; -static inline double qt_inf() -{ - return (QSysInfo::ByteOrder == QSysInfo::BigEndian - ? qt_be_inf_bytes.d - : qt_le_inf_bytes.d); -} - -// Signaling NAN -static const union { unsigned char c[8]; double d; } qt_be_snan_bytes = { { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 } }; -static const union { unsigned char c[8]; double d; } qt_le_snan_bytes = { { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f } }; -static inline double qt_snan() +Q_DECL_CONSTEXPR static inline double qt_inf() Q_DECL_NOEXCEPT { - return (QSysInfo::ByteOrder == QSysInfo::BigEndian - ? qt_be_snan_bytes.d - : qt_le_snan_bytes.d); + Q_STATIC_ASSERT_X(std::numeric_limits::has_infinity, + "platform has no definition for infinity for type double"); + return std::numeric_limits::infinity(); } -// Quiet NAN -static const union { unsigned char c[8]; double d; } qt_be_qnan_bytes = { { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 } }; -static const union { unsigned char c[8]; double d; } qt_le_qnan_bytes = { { 0, 0, 0, 0, 0, 0, 0xf8, 0xff } }; -static inline double qt_qnan() +// Signaling NaN +Q_DECL_CONSTEXPR static inline double qt_snan() Q_DECL_NOEXCEPT { - return (QSysInfo::ByteOrder == QSysInfo::BigEndian - ? qt_be_qnan_bytes.d - : qt_le_qnan_bytes.d); + Q_STATIC_ASSERT_X(std::numeric_limits::has_signaling_NaN, + "platform has no definition for signaling NaN for type double"); + return std::numeric_limits::signaling_NaN(); } -#else // Q_CC_MIPS - -static const unsigned char qt_be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }; -static const unsigned char qt_le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; -static inline double qt_inf() +// Quiet NaN +Q_DECL_CONSTEXPR static inline double qt_qnan() Q_DECL_NOEXCEPT { - const unsigned char *bytes; - bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian - ? qt_be_inf_bytes - : qt_le_inf_bytes); - - union { unsigned char c[8]; double d; } returnValue; - memcpy(returnValue.c, bytes, sizeof(returnValue.c)); - return returnValue.d; + Q_STATIC_ASSERT_X(std::numeric_limits::has_quiet_NaN, + "platform has no definition for quiet NaN for type double"); + return std::numeric_limits::quiet_NaN(); } -// Signaling NAN -static const unsigned char qt_be_snan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }; -static const unsigned char qt_le_snan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }; -static inline double qt_snan() -{ - const unsigned char *bytes; - bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian - ? qt_be_snan_bytes - : qt_le_snan_bytes); - - union { unsigned char c[8]; double d; } returnValue; - memcpy(returnValue.c, bytes, sizeof(returnValue.c)); - return returnValue.d; -} - -// Quiet NAN -static const unsigned char qt_be_qnan_bytes[] = { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 }; -static const unsigned char qt_le_qnan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0xff }; -static inline double qt_qnan() -{ - const unsigned char *bytes; - bytes = (QSysInfo::ByteOrder == QSysInfo::BigEndian - ? qt_be_qnan_bytes - : qt_le_qnan_bytes); - - union { unsigned char c[8]; double d; } returnValue; - memcpy(returnValue.c, bytes, sizeof(returnValue.c)); - return returnValue.d; -} - -#endif // Q_CC_MIPS - static inline bool qt_is_inf(double d) { return qnumeric_std_wrapper::isinf(d); -- cgit v1.2.3