From 65ef677131d2c3812201d438c277fee7b68189aa Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Tue, 9 Jul 2024 14:06:36 +0200 Subject: [PATCH] Rework comparison helper macros to get rid of conditional noexcept The conditional noexcept in comparison operators is known to cause problems in various cases. For example, we had a problem in QBAV, where gcc and clang tried to expand conditional noexcept before the class was complete, and, as a result, discarded some of the QBAV constructors (see fff6562f8c074d75bda8b80f844dc63c6f2e64d5 for a more detailed explanation). Other problem is related to the GHS compiler which tries to compile the noexcept specification and provides a hard error instead of SFINAE'ing out in case of failure (see e1f45ad8187947e243c8247c5cbac2d884d68d55 or 0ac0b412c754e53d167716f207be9d76a7fe16be as examples). This patch reworks the macros to get rid of the conditional noexcept. Instead, it demands that all operators are noexcept by default, and adds another set of helper macros that can be used if it's not possible to make the relational operators noexcept. The new macros end with the _NON_NOEXCEPT suffix. The patch also adds static_assert() to the generated operators to verify that the proper macros are used. However, some platforms (e.g. QNX and Integrity) fail to handle conditional noexcept on lambdas, and so we have to use yet another macro to generate the checks only on platforms that handle them properly. This patch also applies the new approach to qtbase, adding noexcept where possible, and falling back to the _NON_NOEXCEPT macros otherwise. As a drive-by: fix the macro implementation to use QtOrderingPrivate::reversed() instead of manually reimplementing it. I decided to pick the patch to 6.8, because it allows to fix some questionable APIs (see QBAV story above). Change-Id: I72f56778acb469f18b578b3418c0c41b4f6d62e7 Reviewed-by: Thiago Macieira (cherry picked from commit d292648d0bbac50388dae035dc34782accb3807f) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/global/qcompare.cpp | 37 ++ src/corelib/global/qcomparehelpers.h | 391 ++++++++++++------ src/corelib/io/qdir.h | 2 +- src/corelib/io/qfileinfo.h | 2 +- src/corelib/io/qprocess.h | 2 +- src/corelib/io/qstorageinfo.cpp | 2 +- src/corelib/io/qstorageinfo.h | 3 +- src/corelib/io/qurl.h | 2 +- src/corelib/io/qurlquery.h | 2 +- src/corelib/kernel/qjniarray.h | 4 +- src/corelib/kernel/qpointer.h | 2 +- src/corelib/kernel/qvariant.h | 2 +- src/corelib/time/qdatetime.h | 2 +- src/corelib/tools/qversionnumber.h | 4 +- src/gui/painting/qcolormatrix_p.h | 8 +- src/gui/painting/qcolortrc_p.h | 2 +- .../corelib/global/qcompare/tst_qcompare.cpp | 2 +- .../qcomparehelpers/tst_qcomparehelpers1.cpp | 28 +- .../global/qcomparehelpers/wrappertypes.h | 4 +- 19 files changed, 332 insertions(+), 169 deletions(-) diff --git a/src/corelib/global/qcompare.cpp b/src/corelib/global/qcompare.cpp index 4df6146b10..393ea4dbcc 100644 --- a/src/corelib/global/qcompare.cpp +++ b/src/corelib/global/qcompare.cpp @@ -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 + + These macros behave like their versions without the \c {_NON_NOEXCEPT} + suffix, but should be used when the relational operators cannot be + \c {noexcept}. */ /*! diff --git a/src/corelib/global/qcomparehelpers.h b/src/corelib/global/qcomparehelpers.h index 2da7fbd825..3ff49286e9 100644 --- a/src/corelib/global/qcomparehelpers.h +++ b/src/corelib/global/qcomparehelpers.h @@ -67,6 +67,13 @@ 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 + * 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 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 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 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 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 diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h index 9430149e1c..2e44a7bffd 100644 --- a/src/corelib/io/qdir.h +++ b/src/corelib/io/qdir.h @@ -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; diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h index 72c8519446..7336a4e9e7 100644 --- a/src/corelib/io/qfileinfo.h +++ b/src/corelib/io/qfileinfo.h @@ -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 { diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h index 34724a6794..b369452039 100644 --- a/src/corelib/io/qprocess.h +++ b/src/corelib/io/qprocess.h @@ -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 d; diff --git a/src/corelib/io/qstorageinfo.cpp b/src/corelib/io/qstorageinfo.cpp index b7a17febaf..6c4f33a52d 100644 --- a/src/corelib/io/qstorageinfo.cpp +++ b/src/corelib/io/qstorageinfo.cpp @@ -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; diff --git a/src/corelib/io/qstorageinfo.h b/src/corelib/io/qstorageinfo.h index 3784fe8e47..2d7c60ec91 100644 --- a/src/corelib/io/qstorageinfo.h +++ b/src/corelib/io/qstorageinfo.h @@ -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 &); diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h index d6779cf485..e9b97cb9ba 100644 --- a/src/corelib/io/qurl.h +++ b/src/corelib/io/qurl.h @@ -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; diff --git a/src/corelib/io/qurlquery.h b/src/corelib/io/qurlquery.h index 061107606e..5a99b86d0e 100644 --- a/src/corelib/io/qurlquery.h +++ b/src/corelib/io/qurlquery.h @@ -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 d; diff --git a/src/corelib/kernel/qjniarray.h b/src/corelib/kernel/qjniarray.h index c4403311cb..a88e8b3b5b 100644 --- a/src/corelib/kernel/qjniarray.h +++ b/src/corelib/kernel/qjniarray.h @@ -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); diff --git a/src/corelib/kernel/qpointer.h b/src/corelib/kernel/qpointer.h index 8875eef5c3..9659fcf937 100644 --- a/src/corelib/kernel/qpointer.h +++ b/src/corelib/kernel/qpointer.h @@ -96,7 +96,7 @@ private: friend bool comparesEqual(const QPointer &lhs, const QPointer &rhs) noexcept { return lhs.data() == rhs.data(); } QT_DECLARE_EQUALITY_OPERATORS_HELPER(QPointer, QPointer, /* non-constexpr */, - template ) + noexcept(true), template ) template friend bool comparesEqual(const QPointer &lhs, X *rhs) noexcept diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index 306e5b3a38..5c388aebbd 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -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 diff --git a/src/corelib/time/qdatetime.h b/src/corelib/time/qdatetime.h index 77247dcd07..04b1954fc7 100644 --- a/src/corelib/time/qdatetime.h +++ b/src/corelib/time/qdatetime.h @@ -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 &); diff --git a/src/corelib/tools/qversionnumber.h b/src/corelib/tools/qversionnumber.h index c5ae1df1ef..b6cfcf7deb 100644 --- a/src/corelib/tools/qversionnumber.h +++ b/src/corelib/tools/qversionnumber.h @@ -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) diff --git a/src/gui/painting/qcolormatrix_p.h b/src/gui/painting/qcolormatrix_p.h index 0c85222a9a..b08d6fbd05 100644 --- a/src/gui/painting/qcolormatrix_p.h +++ b/src/gui/painting/qcolormatrix_p.h @@ -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); } diff --git a/src/gui/painting/qcolortrc_p.h b/src/gui/painting/qcolortrc_p.h index dbca91c7f6..4dc2fe8b78 100644 --- a/src/gui/painting/qcolortrc_p.h +++ b/src/gui/painting/qcolortrc_p.h @@ -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; diff --git a/tests/auto/corelib/global/qcompare/tst_qcompare.cpp b/tests/auto/corelib/global/qcompare/tst_qcompare.cpp index 556c8212b3..bb31c01e23 100644 --- a/tests/auto/corelib/global/qcompare/tst_qcompare.cpp +++ b/tests/auto/corelib/global/qcompare/tst_qcompare.cpp @@ -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; }; diff --git a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp index 33967f314c..b8e2ab97c1 100644 --- a/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp +++ b/tests/auto/corelib/global/qcomparehelpers/tst_qcomparehelpers1.cpp @@ -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 \ friend Constexpr bool \ - comparesEqual(const Templated ## Name &lhs, X rhs) noexcept; \ + comparesEqual(const Templated ## Name &lhs, X rhs) noexcept(Noex); \ template \ 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 ) \ }; \ \ template \ -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 \ -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 } diff --git a/tests/auto/corelib/global/qcomparehelpers/wrappertypes.h b/tests/auto/corelib/global/qcomparehelpers/wrappertypes.h index 1dd221a8b0..81bd7373d6 100644 --- a/tests/auto/corelib/global/qcomparehelpers/wrappertypes.h +++ b/tests/auto/corelib/global/qcomparehelpers/wrappertypes.h @@ -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 friend bool comparesEqual(const StringWrapper &lhs, const StringWrapper &rhs) noexcept { return StringWrapper::equalsHelper(lhs.m_val, rhs.m_val); } @@ -108,7 +108,7 @@ private: { return StringWrapper::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; };