refactor(typetraits): simplifies concept selection and removes the concept of bitwise operations

This commit is contained in:
2022-05-21 22:39:22 +08:00
parent ee46d84897
commit 97910be70c
14 changed files with 93 additions and 263 deletions

View File

@ -40,53 +40,35 @@ struct TCommonComparisonCategory
template <typename T, typename OrderingType>
concept CThreeWayComparesAs = CSameAs<typename TCommonComparisonCategory<T, OrderingType>::Type, OrderingType>;
template <typename T, typename OrderingType = partial_ordering>
concept CThreeWayComparable = CWeaklyEqualityComparableWith<T, T> && CPartiallyOrderedWith<T, T> &&
requires(const TRemoveReference<T>::Type& A, const TRemoveReference<T>::Type& B)
{
{ A <=> B } -> CThreeWayComparesAs<OrderingType>;
};
template <typename T, typename U, typename OrderingType = partial_ordering>
concept CThreeWayComparableWith = CWeaklyEqualityComparableWith<T, U> && CPartiallyOrderedWith<T, U> &&
CThreeWayComparable<T, OrderingType> && CThreeWayComparable<U, OrderingType> &&
CCommonReferenceWith<const typename TRemoveReference<T>::Type&, const typename TRemoveReference<U>::Type&> &&
CThreeWayComparable<typename TCommonReference<const typename TRemoveReference<T>::Type&, const typename TRemoveReference<U>::Type&>::Type, OrderingType> &&
requires(const TRemoveReference<T>::Type& A, const TRemoveReference<U>::Type& B)
{
{ A <=> B } -> CThreeWayComparesAs<OrderingType>;
{ B <=> A } -> CThreeWayComparesAs<OrderingType>;
};
template <typename T, typename U = T, typename OrderingType = partial_ordering>
concept CThreeWayComparable = CWeaklyEqualityComparable<T, U> && CPartiallyOrdered<T, U>
&& CCommonReference<const typename TRemoveReference<T>::Type&, const typename TRemoveReference<U>::Type&>
&& requires(const typename TRemoveReference<T>::Type& A, const typename TRemoveReference<U>::Type& B,
const typename TRemoveReference<typename TCommonReference<const typename TRemoveReference<T>::Type&, const typename TRemoveReference<U>::Type&>::Type>::Type& C)
{
{ A <=> A } -> CThreeWayComparesAs<OrderingType>;
{ B <=> B } -> CThreeWayComparesAs<OrderingType>;
{ A <=> B } -> CThreeWayComparesAs<OrderingType>;
{ B <=> A } -> CThreeWayComparesAs<OrderingType>;
{ C <=> C } -> CThreeWayComparesAs<OrderingType>;
};
template <typename T, typename U = T>
struct TCompareThreeWayResult { };
template <typename T, typename U> requires CThreeWayComparableWith<T, U>
template <typename T, typename U> requires CThreeWayComparable<T, U>
struct TCompareThreeWayResult<T, U>
{
using Type = decltype(DeclVal<const typename TRemoveReference<T>::Type&>() <=> DeclVal<const typename TRemoveReference<U>::Type&>());
};
template <typename T, typename OrderingType = partial_ordering>
concept CSynthThreeWayComparable = CThreeWayComparable<T> ||
requires(const TRemoveReference<T>::Type& A, const TRemoveReference<T>::Type& B)
{
{ A < B } -> CBooleanTestable;
{ B < A } -> CBooleanTestable;
};
template <typename T, typename U = T, typename OrderingType = partial_ordering>
concept CSynthThreeWayComparable = CThreeWayComparable<T, U> || CTotallyOrdered<T, U>;
template <typename T, typename U, typename OrderingType = partial_ordering>
concept CSynthThreeWayComparableWith = CThreeWayComparableWith<T, U> ||
requires(const TRemoveReference<T>::Type& A, const TRemoveReference<U>::Type& B)
{
{ A < B } -> CBooleanTestable;
{ B < A } -> CBooleanTestable;
};
template <typename T, typename U> requires CSynthThreeWayComparableWith<T, U>
template <typename T, typename U = T> requires CSynthThreeWayComparable<T, U>
constexpr decltype(auto) SynthThreeWayCompare(T&& LHS, U&& RHS)
{
if constexpr (CThreeWayComparableWith<T, U>)
if constexpr (CThreeWayComparable<T, U>)
{
return Forward<T>(LHS) <=> Forward<U>(RHS);
}