feat(concept): add concepts that depend on templates such as Forward and add corresponding tests

This commit is contained in:
_Redstone_c_ 2022-02-04 15:47:57 +08:00
parent 3724188602
commit bafcadc68f
9 changed files with 279 additions and 15 deletions

View File

@ -114,6 +114,75 @@ void TestConcepts()
always_check(!CFloatingPoint<int32>);
always_check(CFloatingPoint<float>);
// BooleanTestable.h
always_check(CBooleanTestable<bool>);
always_check(CBooleanTestable<int32>);
always_check(CBooleanTestable<float>);
always_check(!CBooleanTestable<FTestStructA>);
// Assignable.h
always_check((CAssignableFrom<int32&, int64>));
always_check((CAssignableFrom<int32&, int32>));
always_check((CAssignableFrom<int32&, int8>));
always_check(!(CAssignableFrom<FTestStructI&, int32>));
always_check(!(CAssignableFrom<FTestStructA&, void>));
// Common.h
always_check((CCommonWith<int32, int32>));
always_check((CCommonWith<int8, int32>));
always_check((CCommonWith<float, double>));
always_check(!(CCommonWith<FTestStructA, int32>));
always_check((CCommonReferenceWith<int8, int32>));
always_check((CCommonReferenceWith<float, int32>));
always_check((CCommonReferenceWith<float, double>));
always_check(!(CCommonReferenceWith<FTestStructA, double>));
// Comparable.h
always_check((CEqualityComparable<int32>));
always_check(!(CEqualityComparable<FTestStructA>));
always_check((CEqualityComparableWith<int32, int32>));
always_check((CEqualityComparableWith<int32, int64>));
always_check(!(CEqualityComparableWith<FTestStructA, FTestStructA>));
always_check((CTotallyOrdered<int32>));
always_check(!(CTotallyOrdered<FTestStructA>));
always_check((CTotallyOrderedWith<int32, int32>));
always_check((CTotallyOrderedWith<int32, int64>));
always_check(!(CTotallyOrderedWith<FTestStructA, FTestStructA>));
// Objects.h
always_check(CMovable<int32>);
always_check(CCopyable<int32>);
always_check(CSemiregular<int32>);
always_check(CRegular<int32>);
always_check(CMovable<FTestStructQ>);
always_check(!CCopyable<FTestStructQ>);
always_check(!CSemiregular<FTestStructQ>);
always_check(!CRegular<FTestStructQ>);
always_check(CMovable<FTestStructN>);
always_check(CCopyable<FTestStructN>);
always_check(!CSemiregular<FTestStructN>);
always_check(!CRegular<FTestStructN>);
// Swappable.h
always_check(CSwappable<int32>);
always_check(CSwappable<FTestStructG>);
always_check(CSwappable<FTestStructN>);
// always_check(!CSwappable<FSingleton>);
always_check((CSwappableWith<int32&, int32&>));
}
NAMESPACE_MODULE_END(Utility)

View File

@ -0,0 +1,23 @@
#pragma once
#include "CoreTypes.h"
#include "Concepts/Common.h"
#include "Templates/Templates.h"
#include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
template <typename T, typename U>
concept CAssignableFrom =
TIsLValueReference<T>::Value &&
CCommonReferenceWith<const typename TRemoveReference<T>::Type&, const typename TRemoveReference<U>::Type&> &&
requires(T A, U&& B)
{
{ A = Forward<U>(B) } -> CSameAs<T>;
};
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -0,0 +1,18 @@
#pragma once
#include "CoreTypes.h"
#include "Templates/Utility.h"
#include "Concepts/Convertible.h"
#include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
template <typename T>
concept CBooleanTestable = CConvertibleTo<T, bool> &&
requires(T && B) { { !Forward<T>(B) } -> CConvertibleTo<bool>; };
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -0,0 +1,40 @@
#pragma once
#include "CoreTypes.h"
#include "Concepts/Same.h"
#include "Templates/Templates.h"
#include "Concepts/Convertible.h"
#include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
template <typename T, typename U>
concept CCommonReferenceWith =
requires
{
typename TCommonReference<T, U>::Type;
typename TCommonReference<U, T>::Type;
} &&
CSameAs<typename TCommonReference<T, U>::Type, typename TCommonReference<U, T>::Type> &&
CConvertibleTo<T, typename TCommonReference<T, U>::Type>&&
CConvertibleTo<U, typename TCommonReference<T, U>::Type>;
template <typename T, typename U>
concept CCommonWith =
requires
{
typename TCommonType<T, U>::Type;
typename TCommonType<U, T>::Type;
requires CSameAs<typename TCommonType<T, U>::Type, typename TCommonType<U, T>::Type>;
static_cast<TCommonType<T, U>::Type>(DeclVal<T>());
static_cast<TCommonType<T, U>::Type>(DeclVal<U>());
} &&
CCommonReferenceWith<const T&, const U&> &&
CCommonReferenceWith<typename TCommonType<T, U>::Type&, typename TCommonReference<const T&, const U&>::Type> &&
CSameAs<typename TCommonReference<T, U>::Type, typename TCommonReference<U, T>::Type>;
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -0,0 +1,59 @@
#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

View File

@ -3,25 +3,16 @@
#include "CoreTypes.h"
#include "Concepts/Same.h"
#include "Concepts/Derived.h"
#include "Concepts/Objects.h"
#include "Concepts/Swappable.h"
#include "Concepts/Assignable.h"
#include "Concepts/Comparable.h"
#include "Concepts/BuiltinType.h"
#include "Concepts/Convertible.h"
#include "Concepts/Destructible.h"
#include "Concepts/Constructible.h"
#include "Concepts/BooleanTestable.h"
//template <typename T> concept CBooleanTestable; // Prerequisites: Forward
//template <typename T> concept CMovable; // Prerequisites: CAssignableFrom
//template <typename T> concept CCopyable; // Prerequisites: CAssignableFrom
//template <typename T> concept CSemiregular; // Prerequisites: CCopyable
//template <typename T> concept CRegular; // Prerequisites: CEqualityComparable
//template <typename T, typename U> concept CAssignableFrom; // Prerequisites: Forward
//template <typename T> concept CEqualityComparable; // Prerequisites: CBooleanTestable
//template <typename T, typename U> concept CEqualityComparableWith; // Prerequisites: CBooleanTestable
//template <typename T> concept CTotallyOrdered; // Prerequisites: CBooleanTestable
//template <typename T, typename U> concept CTotallyOrderedWith; // Prerequisites: CBooleanTestable
//template <typename T, typename U> concept CCommonWith; // Prerequisites: Declval
//template <typename T, typename U> concept CCommonReferenceWith; // Prerequisites: Declval
//template <typename F, typename... Args> concept CInvocable; // Prerequisites: Invoke, Forward
//template <typename F, typename... Args> concept CRegularInvocable; // Prerequisites: Invoke, Forward
//template <typename F, typename... Args> concept CPredicate; // Prerequisites: CBooleanTestable, CRegularInvocable

View File

@ -1,8 +1,9 @@
#pragma once
#include "CoreTypes.h"
#include "TypeTraits/TypeTraits.h"
#include "Concepts/Convertible.h"
#include "TypeTraits/TypeTraits.h"
#include "Concepts/Destructible.h"
#include <new>

View File

@ -0,0 +1,36 @@
#pragma once
#include "CoreTypes.h"
#include "Concepts/Swappable.h"
#include "Concepts/Assignable.h"
#include "Concepts/Comparable.h"
#include "TypeTraits/TypeTraits.h"
#include "Concepts/Constructible.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
template <typename T>
concept CMovable =
TIsObject<T>::Value &&
CMoveConstructible<T> &&
CAssignableFrom<T&, T> &&
CSwappable<T>;
template <typename T>
concept CCopyable = CMovable<T> &&
CCopyConstructible<T> &&
CAssignableFrom<T&, T&> &&
CAssignableFrom<T&, const T&> &&
CAssignableFrom<T&, const T>;
template <typename T>
concept CSemiregular = CCopyable<T> && CDefaultInitializable<T>;
template <typename T>
concept CRegular = CSemiregular<T> && CEqualityComparable<T>;
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END

View File

@ -0,0 +1,27 @@
#pragma once
#include "CoreTypes.h"
#include "Concepts/Common.h"
#include "Templates/Templates.h"
#include "TypeTraits/TypeTraits.h"
NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
template <typename T>
concept CSwappable = requires(T& A, T& B) { Swap(A, B); };
template <typename T, typename U>
concept CSwappableWith = CCommonReferenceWith<T, U> &&
requires(T&& A, U&& B)
{
Swap(Forward<T>(A), Forward<T>(A));
Swap(Forward<U>(B), Forward<U>(B));
Swap(Forward<T>(A), Forward<U>(B));
Swap(Forward<U>(B), Forward<T>(A));
};
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END