#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 TCommonComparisonCategoryBasic { }; template<> struct TCommonComparisonCategoryBasic<0> { using Type = strong_ordering; }; template<> struct TCommonComparisonCategoryBasic<2> { using Type = partial_ordering; }; template<> struct TCommonComparisonCategoryBasic<4> { using Type = weak_ordering; }; template<> struct TCommonComparisonCategoryBasic<6> { using Type = partial_ordering; }; template struct TCommonComparisonCategoryImpl : TCommonComparisonCategoryBasic <(0u | ... | ( CSameAs ? 0u : CSameAs ? 4u : CSameAs ? 2u : 1u ) )> { }; NAMESPACE_PRIVATE_END template using TCommonComparisonCategory = typename NAMESPACE_PRIVATE::TCommonComparisonCategoryImpl::Type; template concept CThreeWayComparesAs = CSameAs, OrderingType>; template concept CThreeWayComparable = CWeaklyEqualityComparable && CPartiallyOrdered && CCommonReference&, const TRemoveReference&> && requires(const TRemoveReference& A, const TRemoveReference& B, const TRemoveReference&, const TRemoveReference&>>& C) { { A <=> A } -> CThreeWayComparesAs; { B <=> B } -> CThreeWayComparesAs; { A <=> B } -> CThreeWayComparesAs; { B <=> A } -> CThreeWayComparesAs; { C <=> C } -> CThreeWayComparesAs; }; template requires (CThreeWayComparable) using TCompareThreeWayResult = 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 requires (CSynthThreeWayComparable) using TSynthThreeWayResult = decltype(SynthThreeWayCompare(DeclVal&>(), DeclVal&>())); NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END