Refactor hasCompareThreeWay check

Use structs derived from std::false_type and std::true_type instead
of boolean constants. This allows us to make use of std::conjunction_v
and std::disjunciton_v in the conditions, thus making use of
short-circuit evaluation and saving unnecessary template
instantiations.

Still keep the constexpr bool *_v constant for the cases when we need
a signle check only.

Amends 678e9f614bc5a05d2ff16cf916397998e7cdfca1.

Change-Id: If2ab48ef910e97f241f5922d4108a271bc532f3a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 8784ea16a6bc66ac481d5cbf2dd1ece2d57a836b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit b2bb9ef0f187a3c3d22c7f7714c038d07f87bb1b)
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
bb10
Ivan Solovev 2024-12-20 13:11:13 +01:00
parent 1467bdb4ea
commit 48cc0f9612
2 changed files with 13 additions and 8 deletions

View File

@ -641,14 +641,15 @@ auto qCompareThreeWay(const LeftType &lhs, const RightType &rhs);
template <typename LT, typename RT,
std::enable_if_t<
QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay<LT, RT>
|| QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay<RT, LT>,
std::disjunction_v<
QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay<LT, RT>,
QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay<RT, LT>>,
bool> = true>
auto qCompareThreeWay(const LT &lhs, const RT &rhs)
noexcept(QtOrderingPrivate::CompareThreeWayTester::compareThreeWayNoexcept<LT, RT>())
{
using Qt::compareThreeWay;
if constexpr (QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay<LT, RT>) {
if constexpr (QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay_v<LT, RT>) {
return compareThreeWay(lhs, rhs);
} else {
const auto retval = compareThreeWay(rhs, lhs);

View File

@ -873,12 +873,15 @@ using Qt::compareThreeWay;
// Check if compareThreeWay is implemented for the (LT, RT) argument
// pair.
template <typename LT, typename RT, typename = void>
constexpr inline bool hasCompareThreeWay = false;
struct HasCompareThreeWay : std::false_type {};
template <typename LT, typename RT>
constexpr inline bool hasCompareThreeWay<
struct HasCompareThreeWay<
LT, RT, std::void_t<decltype(compareThreeWay(std::declval<LT>(), std::declval<RT>()))>
> = true;
> : std::true_type {};
template <typename LT, typename RT>
constexpr inline bool hasCompareThreeWay_v = HasCompareThreeWay<LT, RT>::value;
// Check if the operation is noexcept. We have two different overloads,
// depending on the available compareThreeWay() implementation.
@ -886,12 +889,13 @@ constexpr inline bool hasCompareThreeWay<
// context.
template <typename LT, typename RT,
std::enable_if_t<hasCompareThreeWay<LT, RT>, bool> = true>
std::enable_if_t<hasCompareThreeWay_v<LT, RT>, bool> = true>
constexpr bool compareThreeWayNoexcept() noexcept
{ return noexcept(compareThreeWay(std::declval<LT>(), std::declval<RT>())); }
template <typename LT, typename RT,
std::enable_if_t<!hasCompareThreeWay<LT, RT> && hasCompareThreeWay<RT, LT>,
std::enable_if_t<std::conjunction_v<std::negation<HasCompareThreeWay<LT, RT>>,
HasCompareThreeWay<RT, LT>>,
bool> = true>
constexpr bool compareThreeWayNoexcept() noexcept
{ return noexcept(compareThreeWay(std::declval<RT>(), std::declval<LT>())); }