Redcraft/Redcraft.Utility/Source/Public/Concepts/Comparable.h

60 lines
1.9 KiB
C++

#pragma once
#include "CoreTypes.h"
#include "Concepts/Common.h"
#include "TypeTraits/TypeTraits.h"
#include "Concepts/BooleanTestable.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
template <typename T, typename U>
concept CWeaklyEqualityComparableWith =
requires(const TRemoveReference<T>::Type & A, const TRemoveReference<U>::Type & B)
{
{ A == B } -> CBooleanTestable;
{ A != B } -> CBooleanTestable;
{ B == A } -> CBooleanTestable;
{ B != A } -> CBooleanTestable;
};
template <typename T>
concept CEqualityComparable = CWeaklyEqualityComparableWith<T, T>;
template <typename T, typename U>
concept CEqualityComparableWith =
CEqualityComparable<T> &&
CEqualityComparable<U> &&
CWeaklyEqualityComparableWith<T, U> &&
CCommonReferenceWith<const typename TRemoveReference<T>::Type&, const typename TRemoveReference<U>::Type&> &&
CEqualityComparable<typename TCommonReference<const typename TRemoveReference<T>::Type&, const typename TRemoveReference<U>::Type&>::Type>;
template <typename T, typename U>
concept CPartiallyOrderedWith =
requires(const TRemoveReference<T>::Type& A, const TRemoveReference<U>::Type& B)
{
{ A < B } -> CBooleanTestable;
{ A > B } -> CBooleanTestable;
{ A <= B } -> CBooleanTestable;
{ A >= B } -> CBooleanTestable;
{ B < A } -> CBooleanTestable;
{ B > A } -> CBooleanTestable;
{ B <= A } -> CBooleanTestable;
{ B >= A } -> CBooleanTestable;
};
template <typename T>
concept CTotallyOrdered = CEqualityComparable<T> && CPartiallyOrderedWith<T, T>;
template <typename T, typename U>
concept CTotallyOrderedWith =
CTotallyOrdered<T> && CTotallyOrdered<U> &&
CPartiallyOrderedWith<T, U> &&
CEqualityComparableWith<T, U> &&
CTotallyOrdered<typename TCommonReference<const typename TRemoveReference<T>::Type&, const typename TRemoveReference<U>::Type&>::Type>;
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END