From 8784ea16a6bc66ac481d5cbf2dd1ece2d57a836b Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Thu, 21 Nov 2024 13:10:27 +0100 Subject: [PATCH] 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. Pick-to: 6.9 6.8 Change-Id: If2ab48ef910e97f241f5922d4108a271bc532f3a Reviewed-by: Thiago Macieira --- src/corelib/global/qcompare.h | 7 ++++--- src/corelib/global/qcomparehelpers.h | 27 ++++++++++++++++----------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/corelib/global/qcompare.h b/src/corelib/global/qcompare.h index 6d704283875..7b937a9e716 100644 --- a/src/corelib/global/qcompare.h +++ b/src/corelib/global/qcompare.h @@ -647,14 +647,15 @@ auto qCompareThreeWay(const LeftType &lhs, const RightType &rhs); template - || QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay, + std::disjunction_v< + QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay, + QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay>, bool> = true> auto qCompareThreeWay(const LT &lhs, const RT &rhs) noexcept(QtOrderingPrivate::CompareThreeWayTester::compareThreeWayNoexcept()) { using Qt::compareThreeWay; - if constexpr (QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay) { + if constexpr (QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay_v) { return compareThreeWay(lhs, rhs); } else { const auto retval = compareThreeWay(rhs, lhs); diff --git a/src/corelib/global/qcomparehelpers.h b/src/corelib/global/qcomparehelpers.h index ede96a83cf6..9b4fc435134 100644 --- a/src/corelib/global/qcomparehelpers.h +++ b/src/corelib/global/qcomparehelpers.h @@ -1201,19 +1201,22 @@ using WrappedType = std::conditional_t, Qt::totally_ordered // Check if compareThreeWay is implemented for the (LT, RT) argument // pair. template -constexpr inline bool hasCompareThreeWay = false; +struct HasCompareThreeWay : std::false_type {}; template -constexpr inline bool hasCompareThreeWay< +struct HasCompareThreeWay< LT, RT, std::void_t(), std::declval()))> - > = true; + > : std::true_type {}; template -constexpr inline bool hasCompareThreeWay< +struct HasCompareThreeWay< LT*, RT*, std::void_t>(), std::declval>()))> - > = true; + > : std::true_type {}; + +template +constexpr inline bool hasCompareThreeWay_v = HasCompareThreeWay::value; // Check if the operation is noexcept. We have two different overloads, // depending on the available compareThreeWay() implementation. @@ -1221,12 +1224,13 @@ constexpr inline bool hasCompareThreeWay< // context. template , bool> = true> + std::enable_if_t, bool> = true> constexpr bool compareThreeWayNoexcept() noexcept { return noexcept(compareThreeWay(std::declval(), std::declval())); } template && hasCompareThreeWay, + std::enable_if_t>, + HasCompareThreeWay>, bool> = true> constexpr bool compareThreeWayNoexcept() noexcept { return noexcept(compareThreeWay(std::declval(), std::declval())); } @@ -1319,7 +1323,7 @@ auto lexicographicalCompareThreeWay(InputIt1 first1, InputIt1 last1, namespace Test = QtOrderingPrivate::CompareThreeWayTester; // Need this because the user might provide only // compareThreeWay(LT, RT), but not the reversed version. - if constexpr (Test::hasCompareThreeWay) + if constexpr (Test::hasCompareThreeWay_v) return compareThreeWay(WrapLT(lhs), WrapRT(rhs)); else return QtOrderingPrivate::reversed(compareThreeWay(WrapRT(rhs), WrapLT(lhs))); @@ -1333,9 +1337,10 @@ namespace Qt { template using if_has_qt_compare_three_way = - std::enable_if_t - || QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay, - bool>; + std::enable_if_t< + std::disjunction_v, + QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay>, + bool>; } // namespace Qt