From de16185068a08e0cab8bf588c574899a19392410 Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Fri, 9 Feb 2024 12:42:58 +0100 Subject: [PATCH] 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 --- src/corelib/global/qcompare.cpp | 23 ++ src/corelib/global/qcomparehelpers.h | 218 +++++++++++++----- .../global/qcomparehelpers/CMakeLists.txt | 4 +- .../qcomparehelpers/tst_qcomparehelpers.h | 5 +- .../qcomparehelpers/tst_qcomparehelpers1.cpp | 59 +++++ 5 files changed, 243 insertions(+), 66 deletions(-) create mode 100644 tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp diff --git a/src/corelib/global/qcompare.cpp b/src/corelib/global/qcompare.cpp index 1c6fec0bfd..a4b732891d 100644 --- a/src/corelib/global/qcompare.cpp +++ b/src/corelib/global/qcompare.cpp @@ -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 + + 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 = true, Qt::if_integral = true> auto Qt::compareThreeWay(LeftInt lhs, RightInt rhs) \since 6.7 diff --git a/src/corelib/global/qcomparehelpers.h b/src/corelib/global/qcomparehelpers.h index 0394703e17..0e43ac296b 100644 --- a/src/corelib/global/qcomparehelpers.h +++ b/src/corelib/global/qcomparehelpers.h @@ -66,6 +66,9 @@ template 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 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 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 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 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 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 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 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 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 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__) diff --git a/tests/auto/corelib/global/qcomparehelpers/CMakeLists.txt b/tests/auto/corelib/global/qcomparehelpers/CMakeLists.txt index da71d713d4..21967cdc07 100644 --- a/tests/auto/corelib/global/qcomparehelpers/CMakeLists.txt +++ b/tests/auto/corelib/global/qcomparehelpers/CMakeLists.txt @@ -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 diff --git a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.h b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.h index 82f527609f..16398b0978 100644 --- a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.h +++ b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers.h @@ -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 diff --git a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp new file mode 100644 index 0000000000..a3b8200a63 --- /dev/null +++ b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp @@ -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 +}