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 <thiago.macieira@intel.com>
This commit is contained in:
parent
b6f3695a80
commit
8784ea16a6
@ -647,14 +647,15 @@ auto qCompareThreeWay(const LeftType &lhs, const RightType &rhs);
|
|||||||
|
|
||||||
template <typename LT, typename RT,
|
template <typename LT, typename RT,
|
||||||
std::enable_if_t<
|
std::enable_if_t<
|
||||||
QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay<LT, RT>
|
std::disjunction_v<
|
||||||
|| QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay<RT, LT>,
|
QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay<LT, RT>,
|
||||||
|
QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay<RT, LT>>,
|
||||||
bool> = true>
|
bool> = true>
|
||||||
auto qCompareThreeWay(const LT &lhs, const RT &rhs)
|
auto qCompareThreeWay(const LT &lhs, const RT &rhs)
|
||||||
noexcept(QtOrderingPrivate::CompareThreeWayTester::compareThreeWayNoexcept<LT, RT>())
|
noexcept(QtOrderingPrivate::CompareThreeWayTester::compareThreeWayNoexcept<LT, RT>())
|
||||||
{
|
{
|
||||||
using Qt::compareThreeWay;
|
using Qt::compareThreeWay;
|
||||||
if constexpr (QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay<LT, RT>) {
|
if constexpr (QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay_v<LT, RT>) {
|
||||||
return compareThreeWay(lhs, rhs);
|
return compareThreeWay(lhs, rhs);
|
||||||
} else {
|
} else {
|
||||||
const auto retval = compareThreeWay(rhs, lhs);
|
const auto retval = compareThreeWay(rhs, lhs);
|
||||||
|
@ -1201,19 +1201,22 @@ using WrappedType = std::conditional_t<std::is_pointer_v<T>, Qt::totally_ordered
|
|||||||
// Check if compareThreeWay is implemented for the (LT, RT) argument
|
// Check if compareThreeWay is implemented for the (LT, RT) argument
|
||||||
// pair.
|
// pair.
|
||||||
template <typename LT, typename RT, typename = void>
|
template <typename LT, typename RT, typename = void>
|
||||||
constexpr inline bool hasCompareThreeWay = false;
|
struct HasCompareThreeWay : std::false_type {};
|
||||||
|
|
||||||
template <typename LT, typename RT>
|
template <typename LT, typename RT>
|
||||||
constexpr inline bool hasCompareThreeWay<
|
struct HasCompareThreeWay<
|
||||||
LT, RT, std::void_t<decltype(compareThreeWay(std::declval<LT>(), std::declval<RT>()))>
|
LT, RT, std::void_t<decltype(compareThreeWay(std::declval<LT>(), std::declval<RT>()))>
|
||||||
> = true;
|
> : std::true_type {};
|
||||||
|
|
||||||
template <typename LT, typename RT>
|
template <typename LT, typename RT>
|
||||||
constexpr inline bool hasCompareThreeWay<
|
struct HasCompareThreeWay<
|
||||||
LT*, RT*,
|
LT*, RT*,
|
||||||
std::void_t<decltype(compareThreeWay(std::declval<WrappedType<LT>>(),
|
std::void_t<decltype(compareThreeWay(std::declval<WrappedType<LT>>(),
|
||||||
std::declval<WrappedType<RT>>()))>
|
std::declval<WrappedType<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,
|
// Check if the operation is noexcept. We have two different overloads,
|
||||||
// depending on the available compareThreeWay() implementation.
|
// depending on the available compareThreeWay() implementation.
|
||||||
@ -1221,12 +1224,13 @@ constexpr inline bool hasCompareThreeWay<
|
|||||||
// context.
|
// context.
|
||||||
|
|
||||||
template <typename LT, typename RT,
|
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
|
constexpr bool compareThreeWayNoexcept() noexcept
|
||||||
{ return noexcept(compareThreeWay(std::declval<LT>(), std::declval<RT>())); }
|
{ return noexcept(compareThreeWay(std::declval<LT>(), std::declval<RT>())); }
|
||||||
|
|
||||||
template <typename LT, typename 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>
|
bool> = true>
|
||||||
constexpr bool compareThreeWayNoexcept() noexcept
|
constexpr bool compareThreeWayNoexcept() noexcept
|
||||||
{ return noexcept(compareThreeWay(std::declval<RT>(), std::declval<LT>())); }
|
{ return noexcept(compareThreeWay(std::declval<RT>(), std::declval<LT>())); }
|
||||||
@ -1319,7 +1323,7 @@ auto lexicographicalCompareThreeWay(InputIt1 first1, InputIt1 last1,
|
|||||||
namespace Test = QtOrderingPrivate::CompareThreeWayTester;
|
namespace Test = QtOrderingPrivate::CompareThreeWayTester;
|
||||||
// Need this because the user might provide only
|
// Need this because the user might provide only
|
||||||
// compareThreeWay(LT, RT), but not the reversed version.
|
// compareThreeWay(LT, RT), but not the reversed version.
|
||||||
if constexpr (Test::hasCompareThreeWay<WrapLT, WrapRT>)
|
if constexpr (Test::hasCompareThreeWay_v<WrapLT, WrapRT>)
|
||||||
return compareThreeWay(WrapLT(lhs), WrapRT(rhs));
|
return compareThreeWay(WrapLT(lhs), WrapRT(rhs));
|
||||||
else
|
else
|
||||||
return QtOrderingPrivate::reversed(compareThreeWay(WrapRT(rhs), WrapLT(lhs)));
|
return QtOrderingPrivate::reversed(compareThreeWay(WrapRT(rhs), WrapLT(lhs)));
|
||||||
@ -1333,9 +1337,10 @@ namespace Qt {
|
|||||||
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
using if_has_qt_compare_three_way =
|
using if_has_qt_compare_three_way =
|
||||||
std::enable_if_t<QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay<T, U>
|
std::enable_if_t<
|
||||||
|| QtOrderingPrivate::CompareThreeWayTester::hasCompareThreeWay<U, T>,
|
std::disjunction_v<QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay<T, U>,
|
||||||
bool>;
|
QtOrderingPrivate::CompareThreeWayTester::HasCompareThreeWay<U, T>>,
|
||||||
|
bool>;
|
||||||
|
|
||||||
} // namespace Qt
|
} // namespace Qt
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user