feat(miscellaneous): add TSynthThreeWay and the corresponding testing
This commit is contained in:
parent
782f5f5cb2
commit
fd0bebd7be
@ -108,6 +108,14 @@ struct FTestStrongOrdering
|
|||||||
friend strong_ordering operator<=>(FTestStrongOrdering LHS, FTestStrongOrdering RHS) { return LHS.Num <=> RHS.Num; }
|
friend strong_ordering operator<=>(FTestStrongOrdering LHS, FTestStrongOrdering RHS) { return LHS.Num <=> RHS.Num; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FTestSynth
|
||||||
|
{
|
||||||
|
int32 A;
|
||||||
|
FTestSynth(int32 InA) : A(InA) { }
|
||||||
|
friend bool operator==(FTestSynth LHS, FTestSynth RHS) { return LHS.A == RHS.A; }
|
||||||
|
friend bool operator< (FTestSynth LHS, FTestSynth RHS) { return LHS.A < RHS.A; }
|
||||||
|
};
|
||||||
|
|
||||||
NAMESPACE_UNNAMED_END
|
NAMESPACE_UNNAMED_END
|
||||||
|
|
||||||
void TestCompare()
|
void TestCompare()
|
||||||
@ -200,6 +208,17 @@ void TestCompare()
|
|||||||
always_check((TCompareThreeWay<int32>()(0, 0) == strong_ordering::equal));
|
always_check((TCompareThreeWay<int32>()(0, 0) == strong_ordering::equal));
|
||||||
always_check((TCompareThreeWay<void>() (0, 0.0) == strong_ordering::equal));
|
always_check((TCompareThreeWay<void>() (0, 0.0) == strong_ordering::equal));
|
||||||
|
|
||||||
|
|
||||||
|
always_check(TSynthThreeWay{}(FTestPartialOrdering(-1), FTestPartialOrdering( 0)) == partial_ordering::less);
|
||||||
|
always_check(TSynthThreeWay{}(FTestPartialOrdering( 0), FTestPartialOrdering( 0)) == partial_ordering::equivalent);
|
||||||
|
always_check(TSynthThreeWay{}(FTestPartialOrdering( 0), FTestPartialOrdering(-1)) == partial_ordering::greater);
|
||||||
|
|
||||||
|
always_check(TSynthThreeWay{}(FTestPartialOrdering( 0, true), FTestPartialOrdering( 0, false)) == partial_ordering::unordered);
|
||||||
|
|
||||||
|
always_check(TSynthThreeWay{}(FTestSynth(-1), FTestSynth( 0)) == weak_ordering::less);
|
||||||
|
always_check(TSynthThreeWay{}(FTestSynth( 0), FTestSynth( 0)) == weak_ordering::equivalent);
|
||||||
|
always_check(TSynthThreeWay{}(FTestSynth( 0), FTestSynth(-1)) == weak_ordering::greater);
|
||||||
|
|
||||||
always_check((StrongOrder(0, 0) == strong_ordering::equal));
|
always_check((StrongOrder(0, 0) == strong_ordering::equal));
|
||||||
always_check((WeakOrder(0, 0) == strong_ordering::equal));
|
always_check((WeakOrder(0, 0) == strong_ordering::equal));
|
||||||
always_check((PartialOrder(0, 0) == strong_ordering::equal));
|
always_check((PartialOrder(0, 0) == strong_ordering::equal));
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
#include "Templates/Utility.h"
|
||||||
#include "Concepts/Concepts.h"
|
#include "Concepts/Concepts.h"
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ concept CThreeWayComparableWith = CWeaklyEqualityComparableWith<T, U> && CPartia
|
|||||||
CThreeWayComparable<T, OrderingType> && CThreeWayComparable<U, OrderingType> &&
|
CThreeWayComparable<T, OrderingType> && CThreeWayComparable<U, OrderingType> &&
|
||||||
CCommonReferenceWith<const typename TRemoveReference<T>::Type&, const typename TRemoveReference<U>::Type&> &&
|
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> &&
|
CThreeWayComparable<typename TCommonReference<const typename TRemoveReference<T>::Type&, const typename TRemoveReference<U>::Type&>::Type, OrderingType> &&
|
||||||
requires(const TRemoveReference<T>::Type& A, const TRemoveReference<T>::Type& B)
|
requires(const TRemoveReference<T>::Type& A, const TRemoveReference<U>::Type& B)
|
||||||
{
|
{
|
||||||
{ A <=> B } -> CThreeWayComparesAs<OrderingType>;
|
{ A <=> B } -> CThreeWayComparesAs<OrderingType>;
|
||||||
{ B <=> A } -> CThreeWayComparesAs<OrderingType>;
|
{ B <=> A } -> CThreeWayComparesAs<OrderingType>;
|
||||||
@ -67,7 +68,7 @@ struct TCompareThreeWayResult<T, U>
|
|||||||
using Type = decltype(DeclVal<const typename TRemoveReference<T>::Type&>() <=> DeclVal<const typename TRemoveReference<U>::Type&>());
|
using Type = decltype(DeclVal<const typename TRemoveReference<T>::Type&>() <=> DeclVal<const typename TRemoveReference<U>::Type&>());
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T = void> requires CSameAs<T, void> || CThreeWayComparable<T>
|
template <typename T = void> requires (CSameAs<T, void> || CThreeWayComparable<T>)
|
||||||
struct TCompareThreeWay
|
struct TCompareThreeWay
|
||||||
{
|
{
|
||||||
constexpr auto operator()(T&& LHS, T&& RHS) const
|
constexpr auto operator()(T&& LHS, T&& RHS) const
|
||||||
@ -86,6 +87,61 @@ struct TCompareThreeWay<void>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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, 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 = void> requires (CSameAs<T, void> || CSynthThreeWayComparable<T>)
|
||||||
|
struct TSynthThreeWay
|
||||||
|
{
|
||||||
|
constexpr auto operator()(T&& LHS, T&& RHS) const
|
||||||
|
{
|
||||||
|
if constexpr (CThreeWayComparable<T>)
|
||||||
|
{
|
||||||
|
return Forward<T>(LHS) <=> Forward<T>(RHS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Forward<T>(LHS) < Forward<T>(RHS) ? weak_ordering::less : Forward<T>(RHS) < Forward<T>(LHS) ? weak_ordering::greater : weak_ordering::equivalent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct TSynthThreeWay<void>
|
||||||
|
{
|
||||||
|
template <typename T, typename U> requires CSynthThreeWayComparableWith<T, U>
|
||||||
|
constexpr auto operator()(T&& LHS, U&& RHS) const
|
||||||
|
{
|
||||||
|
if constexpr (CThreeWayComparableWith<T, U>)
|
||||||
|
{
|
||||||
|
return Forward<T>(LHS) <=> Forward<U>(RHS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Forward<T>(LHS) < Forward<U>(RHS) ? weak_ordering::less : Forward<U>(RHS) < Forward<T>(LHS) ? weak_ordering::greater : weak_ordering::equivalent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename U = T>
|
||||||
|
struct TSynthThreeWayResult
|
||||||
|
{
|
||||||
|
using Type = decltype(TSynthThreeWay{}(DeclVal<const typename TRemoveReference<T>::Type&>(), DeclVal<const typename TRemoveReference<U>::Type&>()));
|
||||||
|
};
|
||||||
|
|
||||||
NAMESPACE_UNNAMED_BEGIN
|
NAMESPACE_UNNAMED_BEGIN
|
||||||
|
|
||||||
inline constexpr decltype(NAMESPACE_STD::strong_order) StrongOrder;
|
inline constexpr decltype(NAMESPACE_STD::strong_order) StrongOrder;
|
||||||
|
Loading…
Reference in New Issue
Block a user