#pragma once #include "CoreTypes.h" #include "Templates/Utility.h" #include "Concepts/Concepts.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 | ... | ( TIsSame::Value ? 0u : TIsSame::Value ? 4u : TIsSame::Value ? 2u : 1u ) )> { }; template concept CThreeWayComparesAs = CSameAs::Type, OrderingType>; template concept CThreeWayComparable = CWeaklyEqualityComparableWith && CPartiallyOrderedWith && requires(const TRemoveReference::Type& A, const TRemoveReference::Type& B) { { A <=> B } -> CThreeWayComparesAs; }; template concept CThreeWayComparableWith = CWeaklyEqualityComparableWith && CPartiallyOrderedWith && CThreeWayComparable && CThreeWayComparable && CCommonReferenceWith::Type&, const typename TRemoveReference::Type&> && CThreeWayComparable::Type&, const typename TRemoveReference::Type&>::Type, OrderingType> && requires(const TRemoveReference::Type& A, const TRemoveReference::Type& B) { { A <=> B } -> CThreeWayComparesAs; { B <=> A } -> CThreeWayComparesAs; }; template struct TCompareThreeWayResult { }; template requires CThreeWayComparableWith struct TCompareThreeWayResult { using Type = decltype(DeclVal::Type&>() <=> DeclVal::Type&>()); }; template requires (CSameAs || CThreeWayComparable) struct TCompareThreeWay { constexpr auto operator()(T&& LHS, T&& RHS) const { return Forward(LHS) <=> Forward(RHS); } }; template <> struct TCompareThreeWay { template requires CThreeWayComparableWith constexpr auto operator()(T&& LHS, U&& RHS) const { return Forward(LHS) <=> Forward(RHS); } }; template concept CSynthThreeWayComparable = CThreeWayComparable || requires(const TRemoveReference::Type& A, const TRemoveReference::Type& B) { { A < B } -> CBooleanTestable; { B < A } -> CBooleanTestable; }; template concept CSynthThreeWayComparableWith = CThreeWayComparableWith || requires(const TRemoveReference::Type& A, const TRemoveReference::Type& B) { { A < B } -> CBooleanTestable; { B < A } -> CBooleanTestable; }; template requires (CSameAs || CSynthThreeWayComparable) struct TSynthThreeWay { constexpr auto operator()(T&& LHS, T&& RHS) const { 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 TSynthThreeWay { template requires CSynthThreeWayComparableWith constexpr auto operator()(T&& LHS, U&& RHS) const { if constexpr (CThreeWayComparableWith) { 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(TSynthThreeWay{}(DeclVal::Type&>(), DeclVal::Type&>())); }; NAMESPACE_UNNAMED_BEGIN inline constexpr decltype(NAMESPACE_STD::strong_order) StrongOrder; inline constexpr decltype(NAMESPACE_STD::weak_order) WeakOrder; inline constexpr decltype(NAMESPACE_STD::partial_order) PartialOrder; inline constexpr decltype(NAMESPACE_STD::compare_strong_order_fallback) CompareStrongOrderFallback; inline constexpr decltype(NAMESPACE_STD::compare_weak_order_fallback) CompareWeakOrderFallback; inline constexpr decltype(NAMESPACE_STD::compare_partial_order_fallback) ComparePartialOrderFallback; NAMESPACE_UNNAMED_END NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END