diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2023-05-02 12:33:26 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2023-11-28 20:30:19 +0000 |
commit | fe12650e9d85ea0ed4a73f85cdbef0ddf3b67ae3 (patch) | |
tree | 465c96111fc234c422b7d37fa34797e00c081163 /src/testlib | |
parent | e616f8decb998f68753300c8282b48d05bd6fd01 (diff) |
Implement compare helper macros
These macros should unwrap into a proper set of equality and ordering
operators, depending on the C++ standard being used.
For C++17, all 6 operators (==, !=, <, >, <=, >=) are overloaded, while
for C++20 only the overloads for opeartor==() and operator<=>() are
provided.
The macros are documented as internal for now.
The macros rely on two helper functions:
bool comparesEqual(LeftType lhs, RightType rhs);
ReturnType compareThreeWay(LeftType lhs, RightType rhs);
The comparesEqual() helper function is used to implement operator==()
and operator!=().
The compareThreeWay() helper function is used to implement the four
relational operators in C++17, or operator<=>() in C++20.
ReturnType must be one of Qt::{partial,weak,strong}_ordering.
When possible, the functions should also be declared constexpr and
noexcept.
It's the user's responsibility to provide the functions before
using the macros.
Implement a test case which applies the new macros to the dummy
classes, and uses the new helper function to verify the comparison
results.
The MSVC compiler before version 19.36 has a bug, where it fails
to correctly generate reverse opeerators in C++20 mode. Introduce
a new Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY definition for such
compiler versions, and use it to manually generate reversed
operators when needed.
Task-number: QTBUG-104113
Change-Id: Idc19d55df011fd616ff654f35a964e831b8ab93b
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Diffstat (limited to 'src/testlib')
-rw-r--r-- | src/testlib/qcomparisontesthelper_p.h | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/src/testlib/qcomparisontesthelper_p.h b/src/testlib/qcomparisontesthelper_p.h index 432b6f5bd3..00e00925db 100644 --- a/src/testlib/qcomparisontesthelper_p.h +++ b/src/testlib/qcomparisontesthelper_p.h @@ -127,6 +127,7 @@ void testAllComparisonOperatorsCompile() Func(std::as_const(Left), std::as_const(Right), Op, Expected); \ /* END */ + /*! \internal Basic testing of equality operators. @@ -166,8 +167,9 @@ void testEqualityOperators(LeftType lhs, RightType rhs, bool expectedEqual) (==, !=, <, >, <=, >=) for the \a lhs operand of type \c {LeftType} and the \a rhs operand of type \c {RightType}. - The \c OrderingType must be one of Qt::partial_ordering, - Qt::weak_ordering, or Qt::strong_ordering. + When compiled in C++17 mode, the \c OrderingType must be one of + Qt::partial_ordering, Qt::strong_ordering, or Qt::weak_ordering. + In C++20 mode, also the \c {std::*_ordering} types can be used. The \a expectedOrdering parameter provides the expected relation between \a lhs and \a rhs. @@ -189,9 +191,18 @@ void testAllComparisonOperators(LeftType lhs, RightType rhs, OrderingType expect constexpr bool isQOrderingType = std::is_same_v<OrderingType, Qt::partial_ordering> || std::is_same_v<OrderingType, Qt::weak_ordering> || std::is_same_v<OrderingType, Qt::strong_ordering>; - static_assert(isQOrderingType, +#ifdef __cpp_lib_three_way_comparison + constexpr bool isStdOrderingType = std::is_same_v<OrderingType, std::partial_ordering> + || std::is_same_v<OrderingType, std::weak_ordering> + || std::is_same_v<OrderingType, std::strong_ordering>; +#else + constexpr bool isStdOrderingType = false; +#endif + + static_assert(isQOrderingType || isStdOrderingType, "Please provide, as the expectedOrdering parameter, a value " - "of one of the Qt::{partial,weak,strong_ordering types."); + "of one of the Qt::{partial,weak,strong}_ordering or " + "std::{partial,weak,strong}_ordering types."); // We have all sorts of operator==() between Q*Ordering and std::*_ordering // types, so we can just compare to Qt::partial_ordering. |