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 (seebb10fff6562f8cfor 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 (seee1f45ad818or 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>
parent
c26e16e1d4
commit
65ef677131
|
|
@ -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}.
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 &);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 &);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue