#pragma once #include "CoreTypes.h" #include "Templates/Utility.h" #include "TypeTraits/TypeTraits.h" #include NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) // The result of the three-way comparison operator is the built-in type of the compiler, which is directly introduced here. typedef NAMESPACE_STD::partial_ordering partial_ordering; typedef NAMESPACE_STD::weak_ordering weak_ordering; typedef NAMESPACE_STD::strong_ordering strong_ordering; NAMESPACE_PRIVATE_BEGIN template struct TCommonComparisonCategory { using Type = void; }; template<> struct TCommonComparisonCategory<0> { using Type = strong_ordering; }; template<> struct TCommonComparisonCategory<2> { using Type = partial_ordering; }; template<> struct TCommonComparisonCategory<4> { using Type = weak_ordering; }; template<> struct TCommonComparisonCategory<6> { using Type = partial_ordering; }; NAMESPACE_PRIVATE_END template struct TCommonComparisonCategory : NAMESPACE_PRIVATE::TCommonComparisonCategory<(0u | ... | ( CSameAs ? 0u : CSameAs ? 4u : CSameAs ? 2u : 1u ) )> { }; template concept CThreeWayComparesAs = CSameAs::Type, OrderingType>; template concept CThreeWayComparable = CWeaklyEqualityComparable && CPartiallyOrdered && CCommonReference&, const TRemoveReference&> && requires(const TRemoveReference& A, const TRemoveReference& B, const TRemoveReference&, const TRemoveReference&>::Type>& C) { { A <=> A } -> CThreeWayComparesAs; { B <=> B } -> CThreeWayComparesAs; { A <=> B } -> CThreeWayComparesAs; { B <=> A } -> CThreeWayComparesAs; { C <=> C } -> CThreeWayComparesAs; }; template requires CThreeWayComparable struct TCompareThreeWayResult { using Type = decltype(DeclVal&>() <=> DeclVal&>()); }; template concept CSynthThreeWayComparable = CThreeWayComparable || CTotallyOrdered; template requires CSynthThreeWayComparable constexpr decltype(auto) SynthThreeWayCompare(T&& LHS, U&& RHS) { if constexpr (CThreeWayComparable) { return Forward(LHS) <=> Forward(RHS); } else { return Forward(LHS) < Forward(RHS) ? weak_ordering::less : Forward(RHS) < Forward(LHS) ? weak_ordering::greater : weak_ordering::equivalent; } } template struct TSynthThreeWayResult { using Type = decltype(SynthThreeWayCompare(DeclVal&>(), DeclVal&>())); }; NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END