Comparison helper macros: support variable number of attributes

Comparison macros already had the possibility to specify attributes.
These attributes were added in front of each of the generated
comparison operators.
The original usecase was to allow QT_ASCII_CAST_WARN macro before
each of the generated operators, which was needed e.g. for QString vs
QByteArray comparison [0].
However, further work on applying the macros within QtCore revealed
that the same macro parameter can be used if the operators need to
be template functions [1]. This usecase was, however, limited to
templates with a single type and no constraints.

In order to support templates with more than one type, as well as
complex template constraints, we need to convert the comparison
helper macros into variadic macros, and make Attributes a variable
parameter.

This allows us to specify more complex templates, as well as
template constraints as attributes.

Due to the implementation of QT_OVERLOADED_MACRO(), which supports
maximum of 9 arguments, we can support up to 7 comma-separated
arguments for the attributes (because two marco arguments are used
for the left and right hand side types of the comparison). We need
to explicitly define all nine overloads of the macro, though.
And because of MSVC incorrectly expanding __VA_ARGS__ as one(!)
argument, we need to use QT_VA_ARGS_EXPAND in these definitions.

[0]: 42b6fdfb523f47ba711138bb299d97823e7c64d2
[1]: 890c270b9b27de5075bda668dbe8117649673b05

Task-number: QTBUG-127095
Change-Id: I90f3c53f7135562989eabefa29e05d47264ca089
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Ivan Solovev 2024-07-11 16:47:52 +02:00
parent 334a92ecb8
commit 4f2e95a089
3 changed files with 374 additions and 143 deletions

View File

@ -1149,14 +1149,14 @@ CHECK(strong, equivalent);
/*!
\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)
\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>
@ -1169,6 +1169,35 @@ CHECK(strong, equivalent);
deprecated) when implementing comparison of encoding-aware string types
with C-style strings or byte arrays.
Starting from Qt 6.9, \c Attributes becomes a variable argument, meaning
that you can now specify more complex templates and constraints using
these macros.
For example, equality-comparison of a custom type with any integral type
can be implemented in the following way:
\code
class MyClass {
public:
...
private:
template <typename T, std::enable_if_t<std::is_integral_v<T>, bool> = true>
friend constexpr bool comparesEqual(const MyClass &lhs, T rhs) noexcept
{ ... }
Q_DECLARE_EQUALITY_COMPARABLE(MyClass, T,
template <typename T,
std::enable_if_t<std::is_integral_v<T>,
bool> = true>)
};
\endcode
\note Bear in mind that a macro treats each comma (unless within
parentheses) as starting a new argument; for example, the invocation above
has five arguments. Due to implementation details, the macros cannot have
more than nine arguments. If the constraint is too complicated, use an alias
template to give it a self-explanatory name, and use this alias as an
argument of the macro.
\include qcompare.cpp noexcept-requirement-desc
*/
@ -1176,22 +1205,24 @@ CHECK(strong, equivalent);
\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_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_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_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)
\macro Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(LeftType, RightType, Attributes...)
\since 6.8
\relates <QtCompare>
These macros behave like their versions without the \c {_NON_NOEXCEPT}
suffix, but should be used when the relational operators cannot be
\c {noexcept}.
Starting from Qt 6.9, \c Attributes becomes a variable argument.
*/
/*!

View File

@ -124,9 +124,11 @@ orderingFlagsFor(T t) noexcept
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.
* 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.
This is a variable argument, and can now include up to 7
comma-separated parameters.
The macros require two helper functions. For operators to be constexpr,
these must be constexpr, too. Additionally, other attributes (like
@ -171,16 +173,16 @@ orderingFlagsFor(T t) noexcept
// C++20 - provide operator==() for equality, and operator<=>() for ordering
#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
Attributes \
Noexcept, ...) \
__VA_ARGS__ \
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, Noexcept, Attributes) \
Attributes \
#define QT_DECLARE_3WAY_HELPER_STRONG(LeftType, RightType, Constexpr, Noexcept, ...) \
__VA_ARGS__ \
friend Constexpr std::strong_ordering \
operator<=>(LeftType const &lhs, RightType const &rhs) Noexcept \
{ \
@ -188,8 +190,8 @@ orderingFlagsFor(T t) noexcept
return compareThreeWay(lhs, rhs); \
}
#define QT_DECLARE_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr, Noexcept, Attributes) \
Attributes \
#define QT_DECLARE_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr, Noexcept, ...) \
__VA_ARGS__ \
friend Constexpr std::weak_ordering \
operator<=>(LeftType const &lhs, RightType const &rhs) Noexcept \
{ \
@ -197,8 +199,8 @@ orderingFlagsFor(T t) noexcept
return compareThreeWay(lhs, rhs); \
}
#define QT_DECLARE_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr, Noexcept, Attributes) \
Attributes \
#define QT_DECLARE_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr, Noexcept, ...) \
__VA_ARGS__ \
friend Constexpr std::partial_ordering \
operator<=>(LeftType const &lhs, RightType const &rhs) Noexcept \
{ \
@ -207,22 +209,23 @@ orderingFlagsFor(T t) noexcept
}
#define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingType, LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Noexcept, Attributes) \
QT_DECLARE_3WAY_HELPER_ ## OrderingType (LeftType, RightType, Constexpr, Noexcept, Attributes)
Noexcept, ...) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Noexcept, __VA_ARGS__) \
QT_DECLARE_3WAY_HELPER_ ## OrderingType (LeftType, RightType, Constexpr, Noexcept, \
__VA_ARGS__)
#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, \
Noexcept, Attributes) \
Attributes \
Noexcept, ...) \
__VA_ARGS__ \
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, \
Noexcept, Attributes) \
Attributes \
Noexcept, ...) \
__VA_ARGS__ \
friend Constexpr std::strong_ordering \
operator<=>(RightType const &lhs, LeftType const &rhs) Noexcept \
{ \
@ -231,8 +234,8 @@ orderingFlagsFor(T t) noexcept
}
#define QT_DECLARE_REVERSED_3WAY_HELPER_WEAK(LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
Attributes \
Noexcept, ...) \
__VA_ARGS__ \
friend Constexpr std::weak_ordering \
operator<=>(RightType const &lhs, LeftType const &rhs) Noexcept \
{ \
@ -241,8 +244,8 @@ orderingFlagsFor(T t) noexcept
}
#define QT_DECLARE_REVERSED_3WAY_HELPER_PARTIAL(LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
Attributes \
Noexcept, ...) \
__VA_ARGS__ \
friend Constexpr std::partial_ordering \
operator<=>(RightType const &lhs, LeftType const &rhs) Noexcept \
{ \
@ -251,19 +254,19 @@ orderingFlagsFor(T t) noexcept
}
#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
Constexpr, Noexcept, Attributes) \
Constexpr, Noexcept, ...) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
Noexcept, __VA_ARGS__) \
QT_DECLARE_REVERSED_3WAY_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, \
Noexcept, Attributes)
Noexcept, __VA_ARGS__)
#else
// dummy macros for C++17 compatibility, reversed operators are generated by the compiler
#define QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, \
Noexcept, Attributes)
Noexcept, ...)
#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
Constexpr, Noexcept, Attributes)
Constexpr, Noexcept, ...)
#endif // Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY
@ -272,100 +275,97 @@ orderingFlagsFor(T t) noexcept
// and all 4 comparison operators for ordering
#define QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
Attributes \
Noexcept, ...) \
__VA_ARGS__ \
friend Constexpr bool operator==(LeftType const &lhs, RightType const &rhs) Noexcept \
{ \
QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, comparesEqual); \
return comparesEqual(lhs, rhs); \
} \
Attributes \
__VA_ARGS__ \
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, \
Noexcept, Attributes) \
Attributes \
Noexcept, ...) \
__VA_ARGS__ \
friend Constexpr bool operator==(RightType const &lhs, LeftType const &rhs) Noexcept \
{ return comparesEqual(rhs, lhs); } \
Attributes \
__VA_ARGS__ \
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, \
Noexcept, Attributes) \
Attributes \
Noexcept, ...) \
__VA_ARGS__ \
friend Constexpr bool operator<(LeftType const &lhs, RightType const &rhs) Noexcept \
{ \
QT_COMPARISON_NOEXCEPT_CHECK(Noexcept, compareThreeWay); \
return is_lt(compareThreeWay(lhs, rhs)); \
} \
Attributes \
__VA_ARGS__ \
friend Constexpr bool operator>(LeftType const &lhs, RightType const &rhs) Noexcept \
{ return is_gt(compareThreeWay(lhs, rhs)); } \
Attributes \
__VA_ARGS__ \
friend Constexpr bool operator<=(LeftType const &lhs, RightType const &rhs) Noexcept \
{ return is_lteq(compareThreeWay(lhs, rhs)); } \
Attributes \
__VA_ARGS__ \
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, Noexcept, Attributes) \
#define QT_DECLARE_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Noexcept, ...) \
QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, Constexpr, \
Noexcept, Attributes)
Noexcept, __VA_ARGS__)
#define QT_DECLARE_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Noexcept, Attributes) \
#define QT_DECLARE_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Noexcept, ...) \
QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, Constexpr, \
Noexcept, Attributes)
Noexcept, __VA_ARGS__)
#define QT_DECLARE_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Noexcept, Attributes) \
#define QT_DECLARE_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Noexcept, ...) \
QT_DECLARE_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, Constexpr, \
Noexcept, Attributes)
Noexcept, __VA_ARGS__)
#define QT_DECLARE_ORDERING_OPERATORS_HELPER(OrderingString, LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Noexcept, Attributes) \
Noexcept, ...) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, Constexpr, Noexcept, __VA_ARGS__) \
QT_DECLARE_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, Noexcept, \
Attributes)
__VA_ARGS__)
// Helpers for reversed ordering, using the existing compareThreeWay() function.
#define QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(OrderingType, LeftType, RightType, Constexpr, \
Noexcept, Attributes) \
Attributes \
Noexcept, ...) \
__VA_ARGS__ \
friend Constexpr bool operator<(RightType const &lhs, LeftType const &rhs) Noexcept \
{ return is_gt(compareThreeWay(rhs, lhs)); } \
Attributes \
__VA_ARGS__ \
friend Constexpr bool operator>(RightType const &lhs, LeftType const &rhs) Noexcept \
{ return is_lt(compareThreeWay(rhs, lhs)); } \
Attributes \
__VA_ARGS__ \
friend Constexpr bool operator<=(RightType const &lhs, LeftType const &rhs) Noexcept \
{ return is_gteq(compareThreeWay(rhs, lhs)); } \
Attributes \
__VA_ARGS__ \
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, Noexcept, \
Attributes) \
#define QT_DECLARE_REVERSED_ORDERING_HELPER_PARTIAL(LeftType, RightType, Constexpr, Noexcept, ...) \
QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::partial_ordering, LeftType, RightType, \
Constexpr, Noexcept, Attributes)
Constexpr, Noexcept, __VA_ARGS__)
#define QT_DECLARE_REVERSED_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Noexcept, \
Attributes) \
#define QT_DECLARE_REVERSED_ORDERING_HELPER_WEAK(LeftType, RightType, Constexpr, Noexcept, ...) \
QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::weak_ordering, LeftType, RightType, \
Constexpr, Noexcept, Attributes)
Constexpr, Noexcept, __VA_ARGS__)
#define QT_DECLARE_REVERSED_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Noexcept, \
Attributes) \
#define QT_DECLARE_REVERSED_ORDERING_HELPER_STRONG(LeftType, RightType, Constexpr, Noexcept, ...) \
QT_DECLARE_REVERSED_ORDERING_HELPER_TEMPLATE(Qt::strong_ordering, LeftType, RightType, \
Constexpr, Noexcept, Attributes)
Constexpr, Noexcept, __VA_ARGS__)
#define QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(OrderingString, LeftType, RightType, \
Constexpr, Noexcept, Attributes) \
Constexpr, Noexcept, ...) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, Constexpr, Noexcept, \
Attributes) \
__VA_ARGS__) \
QT_DECLARE_REVERSED_ORDERING_HELPER_ ## OrderingString (LeftType, RightType, Constexpr, \
Noexcept, Attributes)
Noexcept, __VA_ARGS__)
#endif // __cpp_lib_three_way_comparison
@ -382,11 +382,24 @@ orderingFlagsFor(T t) noexcept
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */, \
noexcept(true), /* no attributes */)
#define QT_DECLARE_EQUALITY_COMPARABLE_3(LeftType, RightType, Attributes) \
#define QT_DECLARE_EQUALITY_COMPARABLE_3(LeftType, RightType, ...) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */, \
noexcept(true), Attributes) \
noexcept(true), __VA_ARGS__) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */, \
noexcept(true), Attributes)
noexcept(true), __VA_ARGS__)
#define QT_DECLARE_EQUALITY_COMPARABLE_4(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
#define QT_DECLARE_EQUALITY_COMPARABLE_5(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
#define QT_DECLARE_EQUALITY_COMPARABLE_6(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
#define QT_DECLARE_EQUALITY_COMPARABLE_7(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
#define QT_DECLARE_EQUALITY_COMPARABLE_8(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
#define QT_DECLARE_EQUALITY_COMPARABLE_9(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_3(__VA_ARGS__))
#define Q_DECLARE_EQUALITY_COMPARABLE(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE, __VA_ARGS__)
@ -401,11 +414,24 @@ orderingFlagsFor(T t) noexcept
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr, \
noexcept(true), /* no attributes */)
#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(LeftType, RightType, ...) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, constexpr, noexcept(true), \
Attributes) \
__VA_ARGS__) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, constexpr, noexcept(true), \
Attributes)
__VA_ARGS__)
#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_4(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_5(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_6(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_7(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_8(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_9(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE_3(__VA_ARGS__))
#define Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE, __VA_ARGS__)
@ -420,11 +446,24 @@ orderingFlagsFor(T t) noexcept
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) \
#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(LeftType, RightType, ...) \
QT_DECLARE_EQUALITY_OPERATORS_HELPER(LeftType, RightType, /* non-constexpr */, \
noexcept(false), Attributes) \
noexcept(false), __VA_ARGS__) \
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(LeftType, RightType, /* non-constexpr */, \
noexcept(false), Attributes)
noexcept(false), __VA_ARGS__)
#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_4(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_5(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_6(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_7(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_8(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_9(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT_3(__VA_ARGS__))
#define Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT, __VA_ARGS__)
@ -441,11 +480,24 @@ orderingFlagsFor(T t) noexcept
/* non-constexpr */, noexcept(true), \
/* no attributes */)
#define QT_DECLARE_PARTIALLY_ORDERED_3(LeftType, RightType, Attributes) \
#define QT_DECLARE_PARTIALLY_ORDERED_3(LeftType, RightType, ...) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */, \
noexcept(true), Attributes) \
noexcept(true), __VA_ARGS__) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
/* non-constexpr */, noexcept(true), Attributes)
/* non-constexpr */, noexcept(true), __VA_ARGS__)
#define QT_DECLARE_PARTIALLY_ORDERED_4(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
#define QT_DECLARE_PARTIALLY_ORDERED_5(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
#define QT_DECLARE_PARTIALLY_ORDERED_6(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
#define QT_DECLARE_PARTIALLY_ORDERED_7(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
#define QT_DECLARE_PARTIALLY_ORDERED_8(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
#define QT_DECLARE_PARTIALLY_ORDERED_9(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_3(__VA_ARGS__))
#define Q_DECLARE_PARTIALLY_ORDERED(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED, __VA_ARGS__)
@ -460,11 +512,24 @@ orderingFlagsFor(T t) noexcept
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr, \
noexcept(true), /* no attributes */)
#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, ...) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, constexpr, noexcept(true), \
Attributes) \
__VA_ARGS__) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, constexpr, \
noexcept(true), Attributes)
noexcept(true), __VA_ARGS__)
#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_4(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_5(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_6(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_7(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_8(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_9(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define Q_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
@ -480,11 +545,24 @@ orderingFlagsFor(T t) noexcept
/* non-constexpr */, noexcept(false), \
/* no attributes */)
#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, Attributes) \
#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, ...) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(PARTIAL, LeftType, RightType, /* non-constexpr */, \
noexcept(false), Attributes) \
noexcept(false), __VA_ARGS__) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(PARTIAL, LeftType, RightType, \
/* non-constexpr */, noexcept(false), Attributes)
/* non-constexpr */, noexcept(false), __VA_ARGS__)
#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_4(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_5(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_6(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_7(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_8(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_9(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define Q_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_PARTIALLY_ORDERED_NON_NOEXCEPT, __VA_ARGS__)
@ -500,11 +578,24 @@ orderingFlagsFor(T t) noexcept
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
noexcept(true), /* no attributes */)
#define QT_DECLARE_WEAKLY_ORDERED_3(LeftType, RightType, Attributes) \
#define QT_DECLARE_WEAKLY_ORDERED_3(LeftType, RightType, ...) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
noexcept(true), Attributes) \
noexcept(true), __VA_ARGS__) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
noexcept(true), Attributes)
noexcept(true), __VA_ARGS__)
#define QT_DECLARE_WEAKLY_ORDERED_4(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
#define QT_DECLARE_WEAKLY_ORDERED_5(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
#define QT_DECLARE_WEAKLY_ORDERED_6(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
#define QT_DECLARE_WEAKLY_ORDERED_7(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
#define QT_DECLARE_WEAKLY_ORDERED_8(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
#define QT_DECLARE_WEAKLY_ORDERED_9(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_3(__VA_ARGS__))
#define Q_DECLARE_WEAKLY_ORDERED(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED, __VA_ARGS__)
@ -519,11 +610,24 @@ orderingFlagsFor(T t) noexcept
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr, \
noexcept(true), /* no attributes */)
#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, ...) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, constexpr, noexcept(true), \
Attributes) \
__VA_ARGS__) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, constexpr, \
noexcept(true), Attributes)
noexcept(true), __VA_ARGS__)
#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_4(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_5(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_6(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_7(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_8(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_9(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define Q_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
@ -538,11 +642,24 @@ orderingFlagsFor(T t) noexcept
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) \
#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, ...) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
noexcept(false), Attributes) \
noexcept(false), __VA_ARGS__) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(WEAK, LeftType, RightType, /* non-constexpr */, \
noexcept(false), Attributes)
noexcept(false), __VA_ARGS__)
#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_4(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_5(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_6(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_7(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_8(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_9(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT, __VA_ARGS__)
@ -559,11 +676,24 @@ orderingFlagsFor(T t) noexcept
/* non-constexpr */, noexcept(true), \
/* no attributes */)
#define QT_DECLARE_STRONGLY_ORDERED_3(LeftType, RightType, Attributes) \
#define QT_DECLARE_STRONGLY_ORDERED_3(LeftType, RightType, ...) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */, \
noexcept(true), Attributes) \
noexcept(true), __VA_ARGS__) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
/* non-constexpr */, noexcept(true), Attributes)
/* non-constexpr */, noexcept(true), __VA_ARGS__)
#define QT_DECLARE_STRONGLY_ORDERED_4(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
#define QT_DECLARE_STRONGLY_ORDERED_5(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
#define QT_DECLARE_STRONGLY_ORDERED_6(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
#define QT_DECLARE_STRONGLY_ORDERED_7(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
#define QT_DECLARE_STRONGLY_ORDERED_8(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
#define QT_DECLARE_STRONGLY_ORDERED_9(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_3(__VA_ARGS__))
#define Q_DECLARE_STRONGLY_ORDERED(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED, __VA_ARGS__)
@ -578,11 +708,24 @@ orderingFlagsFor(T t) noexcept
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr, \
noexcept(true), /* no attributes */)
#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, Attributes) \
#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(LeftType, RightType, ...) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, constexpr, noexcept(true), \
Attributes) \
__VA_ARGS__) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, constexpr, \
noexcept(true), Attributes)
noexcept(true), __VA_ARGS__)
#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_4(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_5(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_6(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_7(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_8(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_9(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE_3(__VA_ARGS__))
#define Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE, __VA_ARGS__)
@ -598,11 +741,24 @@ orderingFlagsFor(T t) noexcept
/* non-constexpr */, noexcept(false), \
/* no attributes */)
#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, Attributes) \
#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(LeftType, RightType, ...) \
QT_DECLARE_ORDERING_OPERATORS_HELPER(STRONG, LeftType, RightType, /* non-constexpr */, \
noexcept(false), Attributes) \
noexcept(false), __VA_ARGS__) \
QT_DECLARE_ORDERING_OPERATORS_REVERSED_HELPER(STRONG, LeftType, RightType, \
/* non-constexpr */, noexcept(false), Attributes)
/* non-constexpr */, noexcept(false), __VA_ARGS__)
#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_4(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_5(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_6(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_7(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_8(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_9(...) \
QT_VA_ARGS_EXPAND(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT_3(__VA_ARGS__))
#define Q_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT(...) \
QT_OVERLOADED_MACRO(QT_DECLARE_STRONGLY_ORDERED_NON_NOEXCEPT, __VA_ARGS__)

View File

@ -3,39 +3,72 @@
#include "tst_qcomparehelpers.h"
#define DECLARE_TYPE(Name, Type, RetType, Constexpr, Noex, Suffix) \
#define DECLARE_TYPE(Name, Type, RetType, Constexpr, Noex, Suffix, ...) \
class Templated ## Name \
{ \
public: \
Constexpr Templated ## Name () {} \
\
private: \
template <typename X> \
__VA_ARGS__ \
friend Constexpr bool \
comparesEqual(const Templated ## Name &lhs, X rhs) noexcept(Noex); \
template <typename X> \
comparesEqual(const Templated ## Name &lhs, X rhs) noexcept(Noex) \
{ Q_UNUSED(lhs); Q_UNUSED(rhs); return true; } \
__VA_ARGS__ \
friend Constexpr RetType \
compareThreeWay(const Templated ## Name &lhs, X rhs) noexcept(Noex); \
Q_DECLARE_ ## Type ## _ORDERED ## Suffix (Templated ## Name, X, template <typename X>) \
compareThreeWay(const Templated ## Name &lhs, X rhs) noexcept(Noex) \
{ Q_UNUSED(lhs); Q_UNUSED(rhs); return RetType::equivalent; } \
Q_DECLARE_ ## Type ## _ORDERED ## Suffix (Templated ## Name, X, __VA_ARGS__) \
}; \
\
template <typename X> \
Constexpr bool comparesEqual(const Templated ## Name &lhs, X rhs) noexcept(Noex) \
{ Q_UNUSED(lhs); Q_UNUSED(rhs); return true; } \
template <typename X> \
Constexpr RetType compareThreeWay(const Templated ## Name &lhs, X rhs) noexcept(Noex) \
{ Q_UNUSED(lhs); Q_UNUSED(rhs); return RetType::equivalent; }
/* END */
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)
#define DECLARE_TYPES_FOR_N_ATTRS(N, ...) \
DECLARE_TYPE(PartialConst ## N, PARTIALLY, Qt::partial_ordering, constexpr, \
true, _LITERAL_TYPE, __VA_ARGS__) \
DECLARE_TYPE(Partial ## N, PARTIALLY, Qt::partial_ordering, , true, , __VA_ARGS__) \
DECLARE_TYPE(PartialNonNoex ## N, PARTIALLY, Qt::partial_ordering, , false, \
_NON_NOEXCEPT, __VA_ARGS__) \
DECLARE_TYPE(WeakConst ## N, WEAKLY, Qt::weak_ordering, constexpr, true, \
_LITERAL_TYPE, __VA_ARGS__) \
DECLARE_TYPE(Weak ## N, WEAKLY, Qt::weak_ordering, , true, , __VA_ARGS__) \
DECLARE_TYPE(WeakNonNoex ## N, WEAKLY, Qt::weak_ordering, , false, \
_NON_NOEXCEPT, __VA_ARGS__) \
DECLARE_TYPE(StrongConst ## N, STRONGLY, Qt::strong_ordering, constexpr, true, \
_LITERAL_TYPE, __VA_ARGS__) \
DECLARE_TYPE(Strong ## N, STRONGLY, Qt::strong_ordering, , true, , __VA_ARGS__) \
DECLARE_TYPE(StrongNonNoex ## N, STRONGLY, Qt::strong_ordering, , false, \
_NON_NOEXCEPT, __VA_ARGS__) \
/* END */
template <typename T>
using if_int = std::enable_if_t<std::is_same_v<T, int>, bool>;
// The code below tries to craft some artificial template constraints that
// would fit into 1-7 macro arguments.
DECLARE_TYPES_FOR_N_ATTRS(1, template <typename X>)
DECLARE_TYPES_FOR_N_ATTRS(2, template <typename X, if_int<X> = true>)
DECLARE_TYPES_FOR_N_ATTRS(3, template <typename X, std::enable_if_t<std::is_integral_v<X>,
bool> = true>)
DECLARE_TYPES_FOR_N_ATTRS(4, template <typename X, std::enable_if_t<std::is_same_v<X, int>,
bool> = true>)
DECLARE_TYPES_FOR_N_ATTRS(5, template <typename X,
std::enable_if_t<std::disjunction_v<
std::is_same<X, int>,
std::is_floating_point<X>>,
bool> = true>)
DECLARE_TYPES_FOR_N_ATTRS(6, template <typename X,
std::enable_if_t<std::disjunction_v<
std::is_same<X, int>,
std::is_same<X, short>>,
bool> = true>)
DECLARE_TYPES_FOR_N_ATTRS(7, template <typename X,
std::enable_if_t<std::disjunction_v<
std::is_same<X, int>,
std::is_same<X, short>,
std::is_floating_point<X>>,
bool> = true>)
#undef DECLARE_TYPES_FOR_N_ATTRS
#undef DECLARE_TYPE
void tst_QCompareHelpers::compareWithAttributes()
@ -48,16 +81,27 @@ void tst_QCompareHelpers::compareWithAttributes()
QCOMPARE_GE(0, c); \
} while (false)
COMPARE(TemplatedPartialConst);
COMPARE(TemplatedPartial);
COMPARE(TemplatedPartialNonNoex);
COMPARE(TemplatedWeakConst);
COMPARE(TemplatedWeak);
COMPARE(TemplatedWeakNonNoex);
COMPARE(TemplatedStrongConst);
COMPARE(TemplatedStrong);
COMPARE(TemplatedStrongNonNoex);
#define COMPARE_SET(N) \
COMPARE(TemplatedPartialConst ## N); \
COMPARE(TemplatedPartial ## N); \
COMPARE(TemplatedPartialNonNoex ## N); \
COMPARE(TemplatedWeakConst ## N); \
COMPARE(TemplatedWeak ## N); \
COMPARE(TemplatedWeakNonNoex ## N); \
COMPARE(TemplatedStrongConst ## N); \
COMPARE(TemplatedStrong ## N); \
COMPARE(TemplatedStrongNonNoex ## N); \
/* END */
COMPARE_SET(1)
COMPARE_SET(2)
COMPARE_SET(3)
COMPARE_SET(4)
COMPARE_SET(5)
COMPARE_SET(6)
COMPARE_SET(7)
#undef COMPARE_SET
#undef COMPARE
}