summaryrefslogtreecommitdiffstats
path: root/src/corelib/global
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@theqtcompany.com>2015-08-10 13:22:38 +0200
committerErik Verbruggen <erik.verbruggen@theqtcompany.com>2015-11-19 10:56:41 +0000
commit72c68f5f220d691b475b42374b40039b99620876 (patch)
treea0ec5f34acec23c7a6740e18dd341ae8cf7588fd /src/corelib/global
parentc7934f2489e2eb9a539206bab35f335b1943c5bd (diff)
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<double>. 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 <lars.knoll@theqtcompany.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/global')
-rw-r--r--src/corelib/global/qnumeric_p.h84
1 files changed, 14 insertions, 70 deletions
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<double>::has_infinity,
+ "platform has no definition for infinity for type double");
+ return std::numeric_limits<double>::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<double>::has_signaling_NaN,
+ "platform has no definition for signaling NaN for type double");
+ return std::numeric_limits<double>::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<double>::has_quiet_NaN,
+ "platform has no definition for quiet NaN for type double");
+ return std::numeric_limits<double>::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);