Rework comparison helper macros to get rid of conditional noexcept

The conditional noexcept in comparison operators is known to cause
problems in various cases.
For example, we had a problem in QBAV, where gcc and clang tried to
expand conditional noexcept before the class was complete, and, as a
result, discarded some of the QBAV constructors (see
fff6562f8c for a more detailed
explanation).
Other problem is related to the GHS compiler which tries to compile
the noexcept specification and provides a hard error instead of
SFINAE'ing out in case of failure
(see e1f45ad818 or
0ac0b412c754e53d167716f207be9d76a7fe16be as examples).

This patch reworks the macros to get rid of the conditional noexcept.
Instead, it demands that all operators are noexcept by default, and
adds another set of helper macros that can be used if it's not
possible to make the relational operators noexcept.
The new macros end with the _NON_NOEXCEPT suffix.

The patch also adds static_assert() to the generated operators to
verify that the proper macros are used. However, some platforms
(e.g. QNX and Integrity) fail to handle conditional noexcept on
lambdas, and so we have to use yet another macro to generate the
checks only on platforms that handle them properly.

This patch also applies the new approach to qtbase, adding noexcept
where possible, and falling back to the _NON_NOEXCEPT macros
otherwise.

As a drive-by: fix the macro implementation to use
QtOrderingPrivate::reversed() instead of manually reimplementing it.

I decided to pick the patch to 6.8, because it allows to fix some
questionable APIs (see QBAV story above).

Change-Id: I72f56778acb469f18b578b3418c0c41b4f6d62e7
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit d292648d0bbac50388dae035dc34782accb3807f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
bb10
Ivan Solovev 2024-07-09 14:06:36 +02:00 committed by Qt Cherry-pick Bot
parent c26e16e1d4
commit 65ef677131
19 changed files with 332 additions and 169 deletions

View File

@ -912,6 +912,13 @@ CHECK(strong, equivalent);
// inline implementation which uses comparesEqual()
}
\endcode
//! [noexcept-requirement-desc]
These macros generate \c {noexcept} relational operators, and so they check
that the helper functions are \c {noexcept}.
Use the \c {_NON_NOEXCEPT} versions of the macros if the relational
operators of your class cannot be \c {noexcept}.
//! [noexcept-requirement-desc]
*/
/*!
@ -1068,6 +1075,8 @@ CHECK(strong, equivalent);
}
\endcode
\include qcompare.cpp noexcept-requirement-desc
\sa Q_DECLARE_EQUALITY_COMPARABLE, Q_DECLARE_WEAKLY_ORDERED,
Q_DECLARE_STRONGLY_ORDERED
*/
@ -1097,6 +1106,8 @@ CHECK(strong, equivalent);
operators. This means that the helper \c {comparesEqual()} and
\c {compareThreeWay()} functions must also be \c constexpr.
\include qcompare.cpp noexcept-requirement-desc
See \l {Q_DECLARE_PARTIALLY_ORDERED} for usage examples.
\sa Q_DECLARE_PARTIALLY_ORDERED, Q_DECLARE_STRONGLY_ORDERED,
@ -1128,6 +1139,8 @@ CHECK(strong, equivalent);
operators. This means that the helper \c {comparesEqual()} and
\c {compareThreeWay()} functions must also be \c constexpr.
\include qcompare.cpp noexcept-requirement-desc
See \l {Q_DECLARE_PARTIALLY_ORDERED} for usage examples.
\sa Q_DECLARE_PARTIALLY_ORDERED, Q_DECLARE_WEAKLY_ORDERED,
@ -1155,6 +1168,30 @@ CHECK(strong, equivalent);
the \c QT_ASCII_CAST_WARN marco (whose expansion can mark the function as
deprecated) when implementing comparison of encoding-aware string types
with C-style strings or byte arrays.
\include qcompare.cpp noexcept-requirement-desc
*/
/*!
\internal
\macro Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(Type)
\macro Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(LeftType, RightType)
\macro Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(LeftType, RightType, Attributes)
\macro Q_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT(Type)
\macro Q_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT(LeftType, RightType)
\macro Q_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT(LeftType, RightType, Attributes)
\macro Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(Type)
\macro Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(LeftType, RightType)
\macro Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(LeftType, RightType, Attributes)
\macro Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(Type)
\macro Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(LeftType, RightType)
\macro Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(LeftType, RightType, Attributes)
\since 6.8
\relates <QtCompare>
These macros behave like their versions without the \c {_NON_NOEXCEPT}
suffix, but should be used when the relational operators cannot be
\c {noexcept}.
*/
/*!

View File

@ -67,6 +67,13 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
* RightType - the type of the right operand of the comparison
* Constexpr - must be either constexpr or empty. Defines whether the
operator is constexpr or not
* Noexcept - a noexcept specifier. By default the relational operators are
expected to be noexcept. However, there are some cases when
this cannot be achieved (e.g. QDir). The public macros will
pass noexcept(true) or noexcept(false) in this parameter,
because conditional noexcept is known to cause some issues.
However, internally we might want to pass a predicate here
for some specific classes (e.g. QList, etc).
* Attributes - an optional list of attributes. For example, pass
\c QT_ASCII_CAST_WARN when defining comparisons between
C-style string and an encoding-aware string type.
@ -85,6 +92,24 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
unintended implicit conversions.
*/
/*
Some systems (e.g. QNX and Integrity (GHS compiler)) have bugs in
handling conditional noexcept in lambdas.
This macro is needed to overcome such bugs and provide a noexcept check only
on platforms that behave normally.
It does nothing on the systems that have problems.
*/
#if !defined(Q_OS_QNX) && !defined(Q_CC_GHS)
# define QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, Func) \
constexpr auto f = []() Noexcept {}; \
static_assert(!noexcept(f()) || noexcept(Func(lhs, rhs)), \
"Use *_NON_NOEXCEPT version of the macro, " \
"or make the helper function noexcept")
#else
# define QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, Func) /* no check */
#endif
// Seems that qdoc uses C++20 even when Qt is compiled in C++17 mode.
// Or at least it defines __cpp_lib_three_way_comparison.
// Let qdoc see only the C++17 operators for now, because that's what our docs
@ -92,100 +117,100 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
#if defined(__cpp_lib_three_way_comparison) && !defined(Q_QDOC)
// C++20 - provide operator==() for equality, and operator<=>() for ordering
#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
Attributes \
friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(comparesEqual(lhs, rhs))) \
{ return comparesEqual(lhs, rhs); }
friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) Noexcept \
{ \
QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, comparesEqual); \
return comparesEqual(lhs, rhs); \
}
#define QT_DECLARE_3WAY_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_3WAY_HELPER_STRONG(LeftType, RightType, Constexpr, Noexcept, Attributes) \
Attributes \
friend Constexpr std::strong_ordering \
operator<=>(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
operator<=>(LeftType const &lhs, RightType const &rhs) Noexcept \
{ \
QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, compareThreeWay); \
return compareThreeWay(lhs, rhs); \
}
#define QT_DECLARE_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr, Noexcept, Attributes) \
Attributes \
friend Constexpr std::weak_ordering \
operator<=>(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
operator<=>(LeftType const &lhs, RightType const &rhs) Noexcept \
{ \
QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, compareThreeWay); \
return compareThreeWay(lhs, rhs); \
}
#define QT_DECLARE_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr, Noexcept, Attributes) \
Attributes \
friend Constexpr std::partial_ordering \
operator<=>(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
operator<=>(LeftType const &lhs, RightType const &rhs) Noexcept \
{ \
QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, compareThreeWay); \
return compareThreeWay(lhs, rhs); \
}
#define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingType, LeftType, RightType, Constexpr, \
Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
QT_DECLARE_3WAY_HELPER_ ## OrderingType (LeftType, RightType, Constexpr, Attributes)
Noexcept, Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Noexcept, Attributes) \
QT_DECLARE_3WAY_HELPER_ ## OrderingType (LeftType, RightType, Constexpr, Noexcept, Attributes)
#ifdef Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY
// define reversed versions of the operators manually, because buggy MSVC versions do not do it
#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
Attributes \
friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(comparesEqual(rhs, lhs))) \
friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) Noexcept \
{ return comparesEqual(rhs, lhs); }
#define QT_DECLARE_REVERSED_3WAY_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_REVERSED_3WAY_HELPER_STRONG(LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
Attributes \
friend Constexpr std::strong_ordering \
operator<=>(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
operator<=>(RightType const &lhs, LeftType const &rhs) Noexcept \
{ \
const auto r = compareThreeWay(rhs, lhs); \
if (is_gt(r)) return std::strong_ordering::less; \
if (is_lt(r)) return std::strong_ordering::greater; \
return r; \
return QtOrderingPrivate::reversed(r); \
}
#define QT_DECLARE_REVERSED_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_REVERSED_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
Attributes \
friend Constexpr std::weak_ordering \
operator<=>(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
operator<=>(RightType const &lhs, LeftType const &rhs) Noexcept \
{ \
const auto r = compareThreeWay(rhs, lhs); \
if (is_gt(r)) return std::weak_ordering::less; \
if (is_lt(r)) return std::weak_ordering::greater; \
return r; \
return QtOrderingPrivate::reversed(r); \
}
#define QT_DECLARE_REVERSED_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_REVERSED_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
Attributes \
friend Constexpr std::partial_ordering \
operator<=>(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
operator<=>(RightType const &lhs, LeftType const &rhs) Noexcept \
{ \
const auto r = compareThreeWay(rhs, lhs); \
if (is_gt(r)) return std::partial_ordering::less; \
if (is_lt(r)) return std::partial_ordering::greater; \
return r; \
return QtOrderingPrivate::reversed(r); \
}
#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
Constexpr, Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
QT_DECLARE_REVERSED_3WAY_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, Attributes)
Constexpr, Noexcept, Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
QT_DECLARE_REVERSED_3WAY_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, \
Noexcept, Attributes)
#else
// dummy macros for C++17 compatibility, reversed operators are generated by the compiler
#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes)
#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, \
Noexcept, Attributes)
#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
Constexpr, Attributes)
Constexpr, Noexcept, Attributes)
#endif // Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY
@ -193,100 +218,101 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
// C++17 - provide operator==() and operator!=() for equality,
// and all 4 comparison operators for ordering
#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
Attributes \
friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(comparesEqual(lhs, rhs))) \
{ return comparesEqual(lhs, rhs); } \
friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) Noexcept \
{ \
QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, comparesEqual); \
return comparesEqual(lhs, rhs); \
} \
Attributes \
friend Constexpr bool operator!=(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(comparesEqual(lhs, rhs))) \
friend Constexpr bool operator!=(LeftType const &lhs, RightType const &rhs) Noexcept \
{ return !comparesEqual(lhs, rhs); }
// Helpers for reversed comparison, using the existing comparesEqual() function.
#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
Attributes \
friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(comparesEqual(rhs, lhs))) \
friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) Noexcept \
{ return comparesEqual(rhs, lhs); } \
Attributes \
friend Constexpr bool operator!=(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(comparesEqual(rhs, lhs))) \
friend Constexpr bool operator!=(RightType const &lhs, LeftType const &rhs) Noexcept \
{ return !comparesEqual(rhs, lhs); }
#define QT_DECLARE_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr, \
Attributes) \
Noexcept, Attributes) \
Attributes \
friend Constexpr bool operator<(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
{ return is_lt(compareThreeWay(lhs, rhs)); } \
friend Constexpr bool operator<(LeftType const &lhs, RightType const &rhs) Noexcept \
{ \
QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, compareThreeWay); \
return is_lt(compareThreeWay(lhs, rhs)); \
} \
Attributes \
friend Constexpr bool operator>(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
{ return is_gt(compareThreeWay(lhs, rhs)); } \
friend Constexpr bool operator>(LeftType const &lhs, RightType const &rhs) Noexcept \
{ return is_gt(compareThreeWay(lhs, rhs)); } \
Attributes \
friend Constexpr bool operator<=(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
{ return is_lteq(compareThreeWay(lhs, rhs)); } \
friend Constexpr bool operator<=(LeftType const &lhs, RightType const &rhs) Noexcept \
{ return is_lteq(compareThreeWay(lhs, rhs)); } \
Attributes \
friend Constexpr bool operator>=(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
friend Constexpr bool operator>=(LeftType const &lhs, RightType const &rhs) Noexcept \
{ return is_gteq(compareThreeWay(lhs, rhs)); }
#define QT_DECLARE_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Noexcept, Attributes) \
QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, Constexpr, \
Attributes)
Noexcept, Attributes)
#define QT_DECLARE_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Noexcept, Attributes) \
QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, Constexpr, \
Attributes)
Noexcept, Attributes)
#define QT_DECLARE_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Noexcept, Attributes) \
QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, Constexpr, \
Attributes)
Noexcept, Attributes)
#define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingString, LeftType, RightType, Constexpr, \
Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
QT_DECLARE_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, Attributes)
Noexcept, Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Noexcept, Attributes) \
QT_DECLARE_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, Noexcept, \
Attributes)
// Helpers for reversed ordering, using the existing compareThreeWay() function.
#define QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr, \
Attributes) \
Noexcept, Attributes) \
Attributes \
friend Constexpr bool operator<(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
{ return is_gt(compareThreeWay(rhs, lhs)); } \
friend Constexpr bool operator<(RightType const &lhs, LeftType const &rhs) Noexcept \
{ return is_gt(compareThreeWay(rhs, lhs)); } \
Attributes \
friend Constexpr bool operator>(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
{ return is_lt(compareThreeWay(rhs, lhs)); } \
friend Constexpr bool operator>(RightType const &lhs, LeftType const &rhs) Noexcept \
{ return is_lt(compareThreeWay(rhs, lhs)); } \
Attributes \
friend Constexpr bool operator<=(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
{ return is_gteq(compareThreeWay(rhs, lhs)); } \
friend Constexpr bool operator<=(RightType const &lhs, LeftType const &rhs) Noexcept \
{ return is_gteq(compareThreeWay(rhs, lhs)); } \
Attributes \
friend Constexpr bool operator>=(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
friend Constexpr bool operator>=(RightType const &lhs, LeftType const &rhs) Noexcept \
{ return is_lteq(compareThreeWay(rhs, lhs)); }
#define QT_DECLARE_REVERSED_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_REVERSED_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Noexcept, \
Attributes) \
QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, \
Constexpr, Attributes)
Constexpr, Noexcept, Attributes)
#define QT_DECLARE_REVERSED_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_REVERSED_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Noexcept, \
Attributes) \
QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, \
Constexpr, Attributes)
Constexpr, Noexcept, Attributes)
#define QT_DECLARE_REVERSED_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
#define QT_DECLARE_REVERSED_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Noexcept, \
Attributes) \
QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, \
Constexpr, Attributes)
Constexpr, Noexcept, Attributes)
#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
Constexpr, Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
Constexpr, Noexcept, Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Noexcept, \
Attributes) \
QT_DECLARE_REVERSED_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, \
Attributes)
Noexcept, Attributes)
#endif // __cpp_lib_three_way_comparison
@ -294,147 +320,240 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
// Equality operators
#define QT_DECLARE_EQUALITY_COMPARABLE_1(Type) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, /* non-constexpr */, /* no attributes */)
QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, /* non-constexpr */, noexcept(true), \
/* no attributes */)
#define QT_DECLARE_EQUALITY_COMPARABLE_2(LeftType, RightType) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */, \
/* no attributes */) \
noexcept(true), /* no attributes */) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */, \
/* no attributes */)
noexcept(true), /* no attributes */)
#define QT_DECLARE_EQUALITY_COMPARABLE_3(LeftType, RightType, Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */, Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */, \
noexcept(true), Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */, \
Attributes)
noexcept(true), Attributes)
#define Q_DECLARE_EQUALITY_COMPARABLE(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE, __VA_ARGS__)
#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_1(Type) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, constexpr, /* no attributes */)
QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, constexpr, noexcept(true), \
/* no attributes */)
#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_2(LeftType, RightType) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr, /* no attributes */) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr, noexcept(true), \
/* no attributes */) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr, \
/* no attributes */)
noexcept(true), /* no attributes */)
#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr, Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr, Attributes)
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr, noexcept(true), \
Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr, noexcept(true), \
Attributes)
#define Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE, __VA_ARGS__)
#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_1(Type) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, /* non-constexpr */, noexcept(false), \
/* no attributes */)
#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_2(LeftType, RightType) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */, \
noexcept(false), /* no attributes */) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */, \
noexcept(false), /* no attributes */)
#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(LeftType, RightType, Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */, \
noexcept(false), Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */, \
noexcept(false), Attributes)
#define Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT, __VA_ARGS__)
// Partial ordering operators
#define QT_DECLARE_PARTIALLY_ORDERED_1(Type) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, /* non-constexpr */, \
/* no attributes */)
noexcept(true), /* no attributes */)
#define QT_DECLARE_PARTIALLY_ORDERED_2(LeftType, RightType) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */, \
/* no attributes */) \
noexcept(true), /* no attributes */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
/* non-constexpr */, /* no attributes */)
/* non-constexpr */, noexcept(true), \
/* no attributes */)
#define QT_DECLARE_PARTIALLY_ORDERED_3(LeftType, RightType, Attributes) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */, \
Attributes) \
noexcept(true), Attributes) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
/* non-constexpr */, Attributes)
/* non-constexpr */, noexcept(true), Attributes)
#define Q_DECLARE_PARTIALLY_ORDERED(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED, __VA_ARGS__)
#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_1(Type) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, constexpr, /* no attributes */)
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, constexpr, noexcept(true), \
/* no attributes */)
#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, constexpr, \
/* no attributes */) \
noexcept(true), /* no attributes */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr, \
/* no attributes */)
noexcept(true), /* no attributes */)
#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, constexpr, Attributes) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, constexpr, noexcept(true), \
Attributes) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr, \
Attributes)
noexcept(true), Attributes)
#define Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_1(Type) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, /* non-constexpr */, \
noexcept(false), /* no attributes */)
#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_2(LeftType, RightType) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */, \
noexcept(false), /* no attributes */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
/* non-constexpr */, noexcept(false), \
/* no attributes */)
#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, Attributes) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */, \
noexcept(false), Attributes) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
/* non-constexpr */, noexcept(false), Attributes)
#define Q_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT, __VA_ARGS__)
// Weak ordering operators
#define QT_DECLARE_WEAKLY_ORDERED_1(Type) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, /* non-constexpr */, /* no attributes */)
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, /* non-constexpr */, noexcept(true), \
/* no attributes */)
#define QT_DECLARE_WEAKLY_ORDERED_2(LeftType, RightType) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
/* no attributes */) \
noexcept(true), /* no attributes */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
/* no attributes */)
noexcept(true), /* no attributes */)
#define QT_DECLARE_WEAKLY_ORDERED_3(LeftType, RightType, Attributes) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
Attributes) \
noexcept(true), Attributes) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
Attributes)
noexcept(true), Attributes)
#define Q_DECLARE_WEAKLY_ORDERED(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED, __VA_ARGS__)
#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_1(Type) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, constexpr, /* no attributes */)
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, constexpr, noexcept(true), \
/* no attributes */)
#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, constexpr, \
/* no attributes */) \
noexcept(true), /* no attributes */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr, \
/* no attributes */)
noexcept(true), /* no attributes */)
#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, constexpr, Attributes) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr, \
Attributes)
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, constexpr, noexcept(true), \
Attributes) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr, \
noexcept(true), Attributes)
#define Q_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_1(Type) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, /* non-constexpr */, noexcept(false), \
/* no attributes */)
#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_2(LeftType, RightType) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
noexcept(false), /* no attributes */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
noexcept(false), /* no attributes */)
#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, Attributes) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
noexcept(false), Attributes) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
noexcept(false), Attributes)
#define Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT, __VA_ARGS__)
// Strong ordering operators
#define QT_DECLARE_STRONGLY_ORDERED_1(Type) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, /* non-constexpr */, \
/* no attributes */)
noexcept(true), /* no attributes */)
#define QT_DECLARE_STRONGLY_ORDERED_2(LeftType, RightType) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */, \
/* no attributes */) \
noexcept(true), /* no attributes */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
/* non-constexpr */, /* no attributes */)
/* non-constexpr */, noexcept(true), \
/* no attributes */)
#define QT_DECLARE_STRONGLY_ORDERED_3(LeftType, RightType, Attributes) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */, \
Attributes) \
noexcept(true), Attributes) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
/* non-constexpr */, Attributes)
/* non-constexpr */, noexcept(true), Attributes)
#define Q_DECLARE_STRONGLY_ORDERED(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED, __VA_ARGS__)
#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_1(Type) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, constexpr, /* no attributes */)
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, constexpr, noexcept(true), \
/* no attributes */)
#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, constexpr, \
/* no attributes */) \
noexcept(true), /* no attributes */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr, \
/* no attributes */)
noexcept(true), /* no attributes */)
#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, constexpr, Attributes) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, constexpr, noexcept(true), \
Attributes) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr, \
Attributes)
noexcept(true), Attributes)
#define Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_1(Type) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, /* non-constexpr */, \
noexcept(false), /* no attributes */)
#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_2(LeftType, RightType) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */, \
noexcept(false), /* no attributes */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
/* non-constexpr */, noexcept(false), \
/* no attributes */)
#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, Attributes) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */, \
noexcept(false), Attributes) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
/* non-constexpr */, noexcept(false), Attributes)
#define Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT, __VA_ARGS__)
namespace QtPrivate {
template <typename T>

View File

@ -242,7 +242,7 @@ protected:
private:
friend Q_CORE_EXPORT bool comparesEqual(const QDir &lhs, const QDir &rhs);
Q_DECLARE_EQUALITY_COMPARABLE(QDir)
Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QDir)
friend class QDirIterator;
friend class QDirListing;
friend class QDirListingPrivate;

View File

@ -176,7 +176,7 @@ protected:
private:
friend Q_CORE_EXPORT bool comparesEqual(const QFileInfo &lhs, const QFileInfo &rhs);
Q_DECLARE_EQUALITY_COMPARABLE(QFileInfo)
Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QFileInfo)
QFileInfoPrivate* d_func();
inline const QFileInfoPrivate* d_func() const
{

View File

@ -68,7 +68,7 @@ public:
private:
friend Q_CORE_EXPORT bool comparesEqual(const QProcessEnvironment &lhs,
const QProcessEnvironment &rhs);
Q_DECLARE_EQUALITY_COMPARABLE(QProcessEnvironment)
Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QProcessEnvironment)
friend class QProcessPrivate;
friend class QProcessEnvironmentPrivate;
QSharedDataPointer<QProcessEnvironmentPrivate> d;

View File

@ -404,7 +404,7 @@ QStorageInfo QStorageInfo::root()
volume than the QStorageInfo object \a rhs; otherwise returns \c false.
*/
bool comparesEqual(const QStorageInfo &lhs, const QStorageInfo &rhs)
bool comparesEqual(const QStorageInfo &lhs, const QStorageInfo &rhs) noexcept
{
if (lhs.d == rhs.d)
return true;

View File

@ -59,7 +59,8 @@ public:
private:
explicit QStorageInfo(QStorageInfoPrivate &dd);
friend class QStorageInfoPrivate;
friend Q_CORE_EXPORT bool comparesEqual(const QStorageInfo &lhs, const QStorageInfo &rhs);
friend Q_CORE_EXPORT bool
comparesEqual(const QStorageInfo &lhs, const QStorageInfo &rhs) noexcept;
Q_DECLARE_EQUALITY_COMPARABLE(QStorageInfo)
friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QStorageInfo &);

View File

@ -274,7 +274,7 @@ private:
friend Q_CORE_EXPORT bool comparesEqual(const QUrl &lhs, const QUrl &rhs);
friend Q_CORE_EXPORT Qt::weak_ordering
compareThreeWay(const QUrl &lhs, const QUrl &rhs);
Q_DECLARE_WEAKLY_ORDERED(QUrl)
Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(QUrl)
QUrlPrivate *d;
friend class QUrlQuery;

View File

@ -71,7 +71,7 @@ public:
private:
friend Q_CORE_EXPORT bool comparesEqual(const QUrlQuery &lhs, const QUrlQuery &rhs);
Q_DECLARE_EQUALITY_COMPARABLE(QUrlQuery)
Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QUrlQuery)
friend class QUrl;
friend Q_CORE_EXPORT size_t qHash(const QUrlQuery &key, size_t seed) noexcept;
QSharedDataPointer<QUrlQueryPrivate> d;

View File

@ -110,13 +110,13 @@ struct QJniArrayIterator
private:
friend constexpr bool comparesEqual(const QJniArrayIterator &lhs,
const QJniArrayIterator &rhs)
const QJniArrayIterator &rhs) noexcept
{
Q_ASSERT(lhs.m_array == rhs.m_array);
return lhs.m_index == rhs.m_index;
}
friend constexpr Qt::strong_ordering compareThreeWay(const QJniArrayIterator &lhs,
const QJniArrayIterator &rhs)
const QJniArrayIterator &rhs) noexcept
{
Q_ASSERT(lhs.m_array == rhs.m_array);
return Qt::compareThreeWay(lhs.m_index, rhs.m_index);

View File

@ -96,7 +96,7 @@ private:
friend bool comparesEqual(const QPointer &lhs, const QPointer<X> &rhs) noexcept
{ return lhs.data() == rhs.data(); }
QT_DECLARE_EQUALITY_OPERATORS_HELPER(QPointer, QPointer<X>, /* non-constexpr */,
template <typename X>)
noexcept(true), template <typename X>)
template <typename X>
friend bool comparesEqual(const QPointer &lhs, X *rhs) noexcept

View File

@ -618,7 +618,7 @@ private:
friend bool comparesEqual(const QVariant &a, const QVariant &b)
{ return a.equals(b); }
Q_DECLARE_EQUALITY_COMPARABLE(QVariant)
Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QVariant)
#ifndef QT_NO_DEBUG_STREAM
template <typename T>

View File

@ -636,7 +636,7 @@ private:
{ return lhs.equals(rhs); }
friend Q_CORE_EXPORT Qt::weak_ordering
compareThreeWay(const QDateTime &lhs, const QDateTime &rhs);
Q_DECLARE_WEAKLY_ORDERED(QDateTime)
Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(QDateTime)
#ifndef QT_NO_DATASTREAM
friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &);

View File

@ -201,9 +201,9 @@ class QVersionNumber
friend class QVersionNumber;
explicit constexpr It(const QVersionNumber *vn, qsizetype idx) noexcept : v(vn), i(idx) {}
friend constexpr bool comparesEqual(const It &lhs, const It &rhs)
friend constexpr bool comparesEqual(const It &lhs, const It &rhs) noexcept
{ Q_ASSERT(lhs.v == rhs.v); return lhs.i == rhs.i; }
friend constexpr Qt::strong_ordering compareThreeWay(const It &lhs, const It &rhs)
friend constexpr Qt::strong_ordering compareThreeWay(const It &lhs, const It &rhs) noexcept
{ Q_ASSERT(lhs.v == rhs.v); return Qt::compareThreeWay(lhs.i, rhs.i); }
Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(It)

View File

@ -174,7 +174,7 @@ public:
zr = zr * ref.z;
return QColorVector(xr, yr, zr);
}
friend inline bool comparesEqual(const QColorVector &lhs, const QColorVector &rhs);
friend inline bool comparesEqual(const QColorVector &lhs, const QColorVector &rhs) noexcept;
Q_DECLARE_EQUALITY_COMPARABLE(QColorVector);
private:
@ -191,7 +191,7 @@ private:
}
};
inline bool comparesEqual(const QColorVector &v1, const QColorVector &v2)
inline bool comparesEqual(const QColorVector &v1, const QColorVector &v2) noexcept
{
return (std::abs(v1.x - v2.x) < (1.0f / 2048.0f))
&& (std::abs(v1.y - v2.y) < (1.0f / 2048.0f))
@ -342,11 +342,11 @@ public:
{ 0.165665f, 0.675339f, 0.0299835f },
{ 0.125092f, 0.0456238f, 0.797134f } };
}
friend inline bool comparesEqual(const QColorMatrix &lhs, const QColorMatrix &rhs);
friend inline bool comparesEqual(const QColorMatrix &lhs, const QColorMatrix &rhs) noexcept;
Q_DECLARE_EQUALITY_COMPARABLE(QColorMatrix);
};
inline bool comparesEqual(const QColorMatrix &m1, const QColorMatrix &m2)
inline bool comparesEqual(const QColorMatrix &m1, const QColorMatrix &m2) noexcept
{
return (m1.r == m2.r) && (m1.g == m2.g) && (m1.b == m2.b);
}

View File

@ -115,7 +115,7 @@ public:
Type m_type;
friend inline bool comparesEqual(const QColorTrc &lhs, const QColorTrc &rhs);
Q_DECLARE_EQUALITY_COMPARABLE(QColorTrc);
Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QColorTrc);
QColorTransferFunction m_fun;
QColorTransferTable m_table;

View File

@ -755,7 +755,7 @@ private:
{ return comparesEqual(lhs, StringWrapper(QString::number(rhs))); }
friend Qt::weak_ordering compareThreeWay(const StringWrapper &lhs, int rhs)
{ return compareHelper(lhs.m_val, QString::number(rhs)); }
Q_DECLARE_WEAKLY_ORDERED(StringWrapper, int)
Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(StringWrapper, int)
QString m_val;
};

View File

@ -3,7 +3,7 @@
#include "tst_qcomparehelpers.h"
#define DECLARE_TYPE(Name, Type, RetType, Constexpr, Suffix) \
#define DECLARE_TYPE(Name, Type, RetType, Constexpr, Noex, Suffix) \
class Templated ## Name \
{ \
public: \
@ -12,26 +12,29 @@ public: \
private: \
template <typename X> \
friend Constexpr bool \
comparesEqual(const Templated ## Name &lhs, X rhs) noexcept; \
comparesEqual(const Templated ## Name &lhs, X rhs) noexcept(Noex); \
template <typename X> \
friend Constexpr RetType \
compareThreeWay(const Templated ## Name &lhs, X rhs) noexcept; \
compareThreeWay(const Templated ## Name &lhs, X rhs) noexcept(Noex); \
Q_DECLARE_ ## Type ## _ORDERED ## Suffix (Templated ## Name, X, template <typename X>) \
}; \
\
template <typename X> \
Constexpr bool comparesEqual(const Templated ## Name &lhs, X rhs) noexcept \
Constexpr bool comparesEqual(const Templated ## Name &lhs, X rhs) noexcept(Noex) \
{ Q_UNUSED(lhs); Q_UNUSED(rhs); return true; } \
template <typename X> \
Constexpr RetType compareThreeWay(const Templated ## Name &lhs, X rhs) noexcept \
Constexpr RetType compareThreeWay(const Templated ## Name &lhs, X rhs) noexcept(Noex) \
{ Q_UNUSED(lhs); Q_UNUSED(rhs); return RetType::equivalent; }
DECLARE_TYPE(PartialConst, PARTIALLY, Qt::partial_ordering, constexpr, _LITERAL_TYPE)
DECLARE_TYPE(Partial, PARTIALLY, Qt::partial_ordering, , )
DECLARE_TYPE(WeakConst, WEAKLY, Qt::weak_ordering, constexpr, _LITERAL_TYPE)
DECLARE_TYPE(Weak, WEAKLY, Qt::weak_ordering, , )
DECLARE_TYPE(StrongConst, STRONGLY, Qt::strong_ordering, constexpr, _LITERAL_TYPE)
DECLARE_TYPE(Strong, STRONGLY, Qt::strong_ordering, , )
DECLARE_TYPE(PartialConst, PARTIALLY, Qt::partial_ordering, constexpr, true, _LITERAL_TYPE)
DECLARE_TYPE(Partial, PARTIALLY, Qt::partial_ordering, , true, )
DECLARE_TYPE(PartialNonNoex, PARTIALLY, Qt::partial_ordering, , false, _NON_NOEXCEPT)
DECLARE_TYPE(WeakConst, WEAKLY, Qt::weak_ordering, constexpr, true, _LITERAL_TYPE)
DECLARE_TYPE(Weak, WEAKLY, Qt::weak_ordering, , true, )
DECLARE_TYPE(WeakNonNoex, WEAKLY, Qt::weak_ordering, , false, _NON_NOEXCEPT)
DECLARE_TYPE(StrongConst, STRONGLY, Qt::strong_ordering, constexpr, true, _LITERAL_TYPE)
DECLARE_TYPE(Strong, STRONGLY, Qt::strong_ordering, , true, )
DECLARE_TYPE(StrongNonNoex, STRONGLY, Qt::strong_ordering, , false, _NON_NOEXCEPT)
#undef DECLARE_TYPE
@ -47,10 +50,13 @@ void tst_QCompareHelpers::compareWithAttributes()
COMPARE(TemplatedPartialConst);
COMPARE(TemplatedPartial);
COMPARE(TemplatedPartialNonNoex);
COMPARE(TemplatedWeakConst);
COMPARE(TemplatedWeak);
COMPARE(TemplatedWeakNonNoex);
COMPARE(TemplatedStrongConst);
COMPARE(TemplatedStrong);
COMPARE(TemplatedStrongNonNoex);
#undef COMPARE
}

View File

@ -92,7 +92,7 @@ private:
}
// Some of the helper functions are intentionally NOT marked as noexcept
// to test the conditional noexcept in the macros.
// to test various helper macros
template <typename T>
friend bool comparesEqual(const StringWrapper<T> &lhs, const StringWrapper<T> &rhs) noexcept
{ return StringWrapper<T>::equalsHelper(lhs.m_val, rhs.m_val); }
@ -108,7 +108,7 @@ private:
{ return StringWrapper<T>::compareHelper(lhs.m_val, rhs); }
Q_DECLARE_WEAKLY_ORDERED(StringWrapper)
Q_DECLARE_WEAKLY_ORDERED(StringWrapper, QAnyStringView)
Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(StringWrapper, QAnyStringView)
String m_val;
};