Skip to content

Commit edbe05d

Browse files
committed
Short live QtPrivate::fuzzyCompare()!
Extract Method QtPrivate::fuzzyCompare() from the qFuzzyCompare() implementations that correctly validate the preconditions of the public qFuzzyCompare() (QMarginsF, QSizeF, QPointF), so we can more easily apply the same technique to other in-tree callers. In the process, replace comparison to literal 0.0 with calls to qIsNull() so we're a) insulated from -Wfloat-compare and b) have a customization point to extend to types other than float and double. Amends: - 473d069 (QMarginsF) - fa0d77e (QPointF) - 3ca9877 (QSizeF) Pick-to: 6.10 6.8 6.5 Task-number: QTBUG-142020 Change-Id: Ib7ec06822f8006771a1c3a96145e98d574a29fbe Reviewed-by: Ivan Solovev <[email protected]>
1 parent 3aba084 commit edbe05d

File tree

4 files changed

+29
-19
lines changed

4 files changed

+29
-19
lines changed

src/corelib/global/qnumeric.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,27 @@ QT_WARNING_DISABLE_FLOAT_COMPARE
627627

628628
QT_WARNING_POP
629629

630+
namespace QtPrivate {
631+
/*
632+
A version of qFuzzyCompare that works for all values (qFuzzyCompare()
633+
requires that neither argument is numerically 0).
634+
635+
It's private because we need a fix for the many qFuzzyCompare() uses that
636+
ignore the precondition, even for older branches.
637+
638+
See QTBUG-142020 for discussion of a longer-term solution.
639+
*/
640+
template <typename T, typename S>
641+
[[nodiscard]] constexpr bool fuzzyCompare(const T &lhs, const S &rhs) noexcept
642+
{
643+
static_assert(noexcept(qIsNull(lhs) && qIsNull(rhs) && qFuzzyIsNull(lhs - rhs) && qFuzzyCompare(lhs, rhs)),
644+
"The operations qIsNull(), qFuzzyIsNull() and qFuzzyCompare() must be noexcept"
645+
"for both argument types!");
646+
return qIsNull(lhs) || qIsNull(rhs) ? qFuzzyIsNull(lhs - rhs) : qFuzzyCompare(lhs, rhs);
647+
}
648+
} // namespace QtPrivate
649+
650+
630651
inline int qIntCast(double f) { return int(f); }
631652
inline int qIntCast(float f) { return int(f); }
632653

src/corelib/tools/qmargins.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -333,20 +333,13 @@ class QMarginsF
333333
qreal m_right;
334334
qreal m_bottom;
335335

336-
QT_WARNING_PUSH
337-
QT_WARNING_DISABLE_FLOAT_COMPARE
338336
friend constexpr bool qFuzzyCompare(const QMarginsF &lhs, const QMarginsF &rhs) noexcept
339337
{
340-
return ((!lhs.m_left || !rhs.m_left) ? qFuzzyIsNull(lhs.m_left - rhs.m_left)
341-
: qFuzzyCompare(lhs.m_left, rhs.m_left))
342-
&& ((!lhs.m_top || !rhs.m_top) ? qFuzzyIsNull(lhs.m_top - rhs.m_top)
343-
: qFuzzyCompare(lhs.m_top, rhs.m_top))
344-
&& ((!lhs.m_right || !rhs.m_right) ? qFuzzyIsNull(lhs.m_right - rhs.m_right)
345-
: qFuzzyCompare(lhs.m_right, rhs.m_right))
346-
&& ((!lhs.m_bottom || !rhs.m_bottom) ? qFuzzyIsNull(lhs.m_bottom - rhs.m_bottom)
347-
: qFuzzyCompare(lhs.m_bottom, rhs.m_bottom));
338+
return QtPrivate::fuzzyCompare(lhs.m_left, rhs.m_left)
339+
&& QtPrivate::fuzzyCompare(lhs.m_top, rhs.m_top)
340+
&& QtPrivate::fuzzyCompare(lhs.m_right, rhs.m_right)
341+
&& QtPrivate::fuzzyCompare(lhs.m_bottom, rhs.m_bottom);
348342
}
349-
QT_WARNING_POP
350343
friend constexpr bool qFuzzyIsNull(const QMarginsF &m) noexcept
351344
{
352345
return qFuzzyIsNull(m.m_left) && qFuzzyIsNull(m.m_top)

src/corelib/tools/qpoint.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -259,14 +259,11 @@ class QPointF
259259
}
260260

261261
private:
262-
QT_WARNING_PUSH
263-
QT_WARNING_DISABLE_FLOAT_COMPARE
264262
friend constexpr bool qFuzzyCompare(const QPointF &p1, const QPointF &p2) noexcept
265263
{
266-
return ((!p1.xp || !p2.xp) ? qFuzzyIsNull(p1.xp - p2.xp) : qFuzzyCompare(p1.xp, p2.xp))
267-
&& ((!p1.yp || !p2.yp) ? qFuzzyIsNull(p1.yp - p2.yp) : qFuzzyCompare(p1.yp, p2.yp));
264+
return QtPrivate::fuzzyCompare(p1.xp, p2.xp)
265+
&& QtPrivate::fuzzyCompare(p1.yp, p2.yp);
268266
}
269-
QT_WARNING_POP
270267
friend constexpr bool qFuzzyIsNull(const QPointF &point) noexcept
271268
{
272269
return qFuzzyIsNull(point.xp) && qFuzzyIsNull(point.yp);

src/corelib/tools/qsize.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,9 @@ class Q_CORE_EXPORT QSizeF
258258
QT_WARNING_DISABLE_FLOAT_COMPARE
259259
friend constexpr bool qFuzzyCompare(const QSizeF &s1, const QSizeF &s2) noexcept
260260
{
261-
// Cannot use qFuzzyCompare(), because it will give incorrect results
262261
// if one of the arguments is 0.0.
263-
return ((!s1.wd || !s2.wd) ? qFuzzyIsNull(s1.wd - s2.wd) : qFuzzyCompare(s1.wd, s2.wd))
264-
&& ((!s1.ht || !s2.ht) ? qFuzzyIsNull(s1.ht - s2.ht) : qFuzzyCompare(s1.ht, s2.ht));
262+
return QtPrivate::fuzzyCompare(s1.wd, s2.wd)
263+
&& QtPrivate::fuzzyCompare(s1.ht, s2.ht);
265264
}
266265
QT_WARNING_POP
267266
friend constexpr bool qFuzzyIsNull(const QSizeF &size) noexcept

0 commit comments

Comments
 (0)