Comparison helper macros: add an Attributes parameter

Some of relational operators in Qt are marked with QT_ASCII_CAST_WARN
(see e.g. String, QLatin1StringView).
If we want to convert these operators to the new comparison helper
macros, we need a way to preserve this attribute.
My tests show that simply adding the attribute to the helper
comparesEqual() and compareThreeWay() functions does not work, so we
need to explicitly add it to each of the generated operators.

Change-Id: I2940a70fe191326e8a2ebfb05b8da6e0f21a845c
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
bb10
Ivan Solovev 2024-02-09 12:42:58 +01:00
parent 909d881e75
commit de16185068
5 changed files with 243 additions and 66 deletions

View File

@ -1131,6 +1131,29 @@ CHECK(strong, equivalent);
Q_DECLARE_EQUALITY_COMPARABLE
*/
/*!
\internal
\macro Q_DECLARE_EQUALITY_COMPARABLE(LeftType, RightType, Attributes)
\macro Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(LeftType, RightType, Attributes)
\macro Q_DECLARE_PARTIALLY_ORDERED(LeftType, RightType, Attributes)
\macro Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(LeftType, RightType, Attributes)
\macro Q_DECLARE_WEAKLY_ORDERED(LeftType, RightType, Attributes)
\macro Q_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE(LeftType, RightType, Attributes)
\macro Q_DECLARE_STRONGLY_ORDERED(LeftType, RightType, Attributes)
\macro Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(LeftType, RightType, Attributes)
\since 6.8
\relates <QtCompare>
These macros behave like their two-argument versions, but allow
specification of C++ attributes to add before every generated relational
operator.
As an example, the \c Attributes parameter can be used in Qt to pass
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.
*/
/*!
\fn template <typename LeftInt, typename RightInt, Qt::if_integral<LeftInt> = true, Qt::if_integral<RightInt> = true> auto Qt::compareThreeWay(LeftInt lhs, RightInt rhs)
\since 6.7

View File

@ -66,6 +66,9 @@ 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
* 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.
The macros require two helper functions. For operators to be constexpr,
these must be constexpr, too. Additionally, other attributes (like
@ -88,12 +91,14 @@ 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) \
#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
Attributes \
friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(comparesEqual(lhs, rhs))) \
{ return comparesEqual(lhs, rhs); }
#define QT_DECLARE_3WAY_HELPER_STRONG(LeftType, RightType, Constexpr) \
#define QT_DECLARE_3WAY_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
Attributes \
friend Constexpr std::strong_ordering \
operator<=>(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
@ -101,7 +106,8 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
return compareThreeWay(lhs, rhs); \
}
#define QT_DECLARE_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr) \
#define QT_DECLARE_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
Attributes \
friend Constexpr std::weak_ordering \
operator<=>(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
@ -109,7 +115,8 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
return compareThreeWay(lhs, rhs); \
}
#define QT_DECLARE_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr) \
#define QT_DECLARE_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
Attributes \
friend Constexpr std::partial_ordering \
operator<=>(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
@ -117,19 +124,22 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
return compareThreeWay(lhs, rhs); \
}
#define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingType, LeftType, RightType, Constexpr) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr) \
QT_DECLARE_3WAY_HELPER_ ## OrderingType (LeftType, RightType, Constexpr)
#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)
#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) \
#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
Attributes \
friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(comparesEqual(rhs, lhs))) \
{ return comparesEqual(rhs, lhs); }
#define QT_DECLARE_REVERSED_3WAY_HELPER_STRONG(LeftType, RightType, Constexpr) \
#define QT_DECLARE_REVERSED_3WAY_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
Attributes \
friend Constexpr std::strong_ordering \
operator<=>(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
@ -140,7 +150,8 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
return r; \
}
#define QT_DECLARE_REVERSED_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr) \
#define QT_DECLARE_REVERSED_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
Attributes \
friend Constexpr std::weak_ordering \
operator<=>(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
@ -151,7 +162,8 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
return r; \
}
#define QT_DECLARE_REVERSED_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr) \
#define QT_DECLARE_REVERSED_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
Attributes \
friend Constexpr std::partial_ordering \
operator<=>(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
@ -163,15 +175,16 @@ template <typename In> constexpr auto to_Qt(In in) noexcept
}
#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
Constexpr) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr) \
QT_DECLARE_REVERSED_3WAY_HELPER_ ## OrderingString (LeftType, RightType, Constexpr)
Constexpr, Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
QT_DECLARE_REVERSED_3WAY_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, 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)
#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, Constexpr)
#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes)
#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
Constexpr, Attributes)
#endif // Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY
@ -179,78 +192,100 @@ 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) \
#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Attributes) \
Attributes \
friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(comparesEqual(lhs, rhs))) \
{ return comparesEqual(lhs, rhs); } \
Attributes \
friend Constexpr bool operator!=(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(comparesEqual(lhs, rhs))) \
{ return !comparesEqual(lhs, rhs); }
// Helpers for reversed comparison, using the existing comparesEqual() function.
#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr) \
#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
Attributes \
friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(comparesEqual(rhs, lhs))) \
{ return comparesEqual(rhs, lhs); } \
Attributes \
friend Constexpr bool operator!=(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(comparesEqual(rhs, lhs))) \
{ return !comparesEqual(rhs, lhs); }
#define QT_DECLARE_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr) \
#define QT_DECLARE_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr, \
Attributes) \
Attributes \
friend Constexpr bool operator<(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
{ return compareThreeWay(lhs, rhs) < 0; } \
Attributes \
friend Constexpr bool operator>(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
{ return compareThreeWay(lhs, rhs) > 0; } \
Attributes \
friend Constexpr bool operator<=(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
{ return compareThreeWay(lhs, rhs) <= 0; } \
Attributes \
friend Constexpr bool operator>=(LeftType const &lhs, RightType const &rhs) \
noexcept(noexcept(compareThreeWay(lhs, rhs))) \
{ return compareThreeWay(lhs, rhs) >= 0; }
#define QT_DECLARE_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr) \
QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, Constexpr)
#define QT_DECLARE_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, Constexpr, \
Attributes)
#define QT_DECLARE_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr) \
QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, Constexpr)
#define QT_DECLARE_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, Constexpr, \
Attributes)
#define QT_DECLARE_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr) \
QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, Constexpr)
#define QT_DECLARE_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, Constexpr, \
Attributes)
#define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingString, LeftType, RightType, Constexpr) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr) \
QT_DECLARE_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr)
#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)
// Helpers for reversed ordering, using the existing compareThreeWay() function.
#define QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr) \
#define QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr, \
Attributes) \
Attributes \
friend Constexpr bool operator<(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
{ return compareThreeWay(rhs, lhs) > 0; } \
Attributes \
friend Constexpr bool operator>(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
{ return compareThreeWay(rhs, lhs) < 0; } \
Attributes \
friend Constexpr bool operator<=(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
{ return compareThreeWay(rhs, lhs) >= 0; } \
Attributes \
friend Constexpr bool operator>=(RightType const &lhs, LeftType const &rhs) \
noexcept(noexcept(compareThreeWay(rhs, lhs))) \
{ return compareThreeWay(rhs, lhs) <= 0; }
#define QT_DECLARE_REVERSED_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr) \
QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, Constexpr)
#define QT_DECLARE_REVERSED_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Attributes) \
QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, \
Constexpr, Attributes)
#define QT_DECLARE_REVERSED_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr) \
QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, Constexpr)
#define QT_DECLARE_REVERSED_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Attributes) \
QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, \
Constexpr, Attributes)
#define QT_DECLARE_REVERSED_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr) \
QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, Constexpr)
#define QT_DECLARE_REVERSED_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Attributes) \
QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, \
Constexpr, Attributes)
#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
Constexpr) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr) \
QT_DECLARE_REVERSED_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr)
Constexpr, Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Attributes) \
QT_DECLARE_REVERSED_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, \
Attributes)
#endif // __cpp_lib_three_way_comparison
@ -258,84 +293,143 @@ 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 */)
QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, /* non-constexpr */, /* no attributes */)
#define QT_DECLARE_EQUALITY_COMPARABLE_2(LeftType, RightType) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */)
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */, \
/* no attributes */) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */, \
/* 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_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */, \
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)
QT_DECLARE_EQUALITY_OPERATORS_HELPER(Type, Type, constexpr, /* no attributes */)
#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_2(LeftType, RightType) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr)
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr, /* no attributes */) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr, \
/* 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)
#define Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE, __VA_ARGS__)
// Partial ordering operators
#define QT_DECLARE_PARTIALLY_ORDERED_1(Type) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, /* non-constexpr */)
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, /* non-constexpr */, \
/* no attributes */)
#define QT_DECLARE_PARTIALLY_ORDERED_2(LeftType, RightType) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */)
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */, \
/* no attributes */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
/* non-constexpr */, /* no attributes */)
#define QT_DECLARE_PARTIALLY_ORDERED_3(LeftType, RightType, Attributes) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */, \
Attributes) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
/* non-constexpr */, 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)
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, Type, Type, constexpr, /* no attributes */)
#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, constexpr) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr)
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, constexpr, \
/* no attributes */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr, \
/* 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_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr, \
Attributes)
#define Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
// Weak ordering operators
#define QT_DECLARE_WEAKLY_ORDERED_1(Type) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, /* non-constexpr */)
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, /* non-constexpr */, /* no attributes */)
#define QT_DECLARE_WEAKLY_ORDERED_2(LeftType, RightType) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */)
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
/* no attributes */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
/* no attributes */)
#define QT_DECLARE_WEAKLY_ORDERED_3(LeftType, RightType, Attributes) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
Attributes) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
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)
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, Type, Type, constexpr, /* no attributes */)
#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, constexpr) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr)
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, constexpr, \
/* no attributes */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr, \
/* 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)
#define Q_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
// Strong ordering operators
#define QT_DECLARE_STRONGLY_ORDERED_1(Type) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, /* non-constexpr */)
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, /* non-constexpr */, \
/* no attributes */)
#define QT_DECLARE_STRONGLY_ORDERED_2(LeftType, RightType) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, /* non-constexpr */)
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */, \
/* no attributes */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
/* non-constexpr */, /* no attributes */)
#define QT_DECLARE_STRONGLY_ORDERED_3(LeftType, RightType, Attributes) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */, \
Attributes) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
/* non-constexpr */, 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)
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, Type, Type, constexpr, /* no attributes */)
#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_2(LeftType, RightType) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, constexpr) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr)
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, constexpr, \
/* no attributes */) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr, \
/* 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_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr, \
Attributes)
#define Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)

View File

@ -3,7 +3,7 @@
qt_internal_add_test(tst_qcomparehelpers
SOURCES
tst_qcomparehelpers.h tst_qcomparehelpers.cpp
tst_qcomparehelpers.h tst_qcomparehelpers.cpp tst_qcomparehelpers1.cpp
wrappertypes.h
LIBRARIES
Qt::TestPrivate
@ -14,7 +14,7 @@ qt_internal_add_test(tst_qcomparehelpers
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20" AND NOT MACOS AND NOT VXWORKS)
qt_internal_add_test(tst_qcomparehelpers_cpp23
SOURCES
tst_qcomparehelpers.h tst_qcomparehelpers.cpp
tst_qcomparehelpers.h tst_qcomparehelpers.cpp tst_qcomparehelpers1.cpp
wrappertypes.h
DEFINES
tst_QCompareHelpers=tst_QCompareHelpersCpp23

View File

@ -55,8 +55,9 @@ private Q_SLOTS:
void builtinOrder();
// Add new test cases to another cpp file, because minGW already complains
// about a too large tst_qcomparehelpers.cpp.obj object file
// Add new test cases to tst_qcomparehelpers1.cpp, because minGW already
// complains about a too large tst_qcomparehelpers.cpp.obj object file
void compareWithAttributes();
};
#endif // TST_QCOMPAREHELPERS_H

View File

@ -0,0 +1,59 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include "tst_qcomparehelpers.h"
#define DECLARE_TYPE(Name, Type, RetType, Constexpr, Suffix) \
class Deprecated ## Name \
{ \
public: \
Constexpr Deprecated ## Name () {} \
\
private: \
friend Constexpr bool \
comparesEqual(const Deprecated ## Name &lhs, int rhs) noexcept; \
friend Constexpr RetType \
compareThreeWay(const Deprecated ## Name &lhs, int rhs) noexcept; \
Q_DECLARE_ ## Type ## _ORDERED ## Suffix (Deprecated ## Name, int, \
Q_DECL_DEPRECATED_X("This op is deprecated")) \
}; \
\
Constexpr bool comparesEqual(const Deprecated ## Name &lhs, int rhs) noexcept \
{ Q_UNUSED(lhs); Q_UNUSED(rhs); return true; } \
Constexpr RetType compareThreeWay(const Deprecated ## Name &lhs, int rhs) noexcept \
{ 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, , )
#undef DECLARE_TYPE
void tst_QCompareHelpers::compareWithAttributes()
{
// All these comparisons would trigger deprecation warnings.
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
#define COMPARE(ClassName) \
do { \
ClassName c; \
QCOMPARE_EQ(c, 0); \
QCOMPARE_LE(c, 0); \
QCOMPARE_GE(0, c); \
} while (false)
COMPARE(DeprecatedPartialConst);
COMPARE(DeprecatedPartial);
COMPARE(DeprecatedWeakConst);
COMPARE(DeprecatedWeak);
COMPARE(DeprecatedStrongConst);
COMPARE(DeprecatedStrong);
#undef COMPARE
QT_WARNING_POP
}