From a2847b891057aac76ab817952f62472559978014 Mon Sep 17 00:00:00 2001 From: _Redstone_c_ Date: Wed, 2 Feb 2022 19:04:42 +0800 Subject: [PATCH] feat(concept): add basic concepts and the corresponding testing --- .../Private/Testing/ConceptsTesting.cpp | 121 ++++++++++++++++++ .../Private/Testing/TypeTraitsTesting.cpp | 4 + .../Source/Public/Concepts/BuiltinType.h | 18 +++ .../Source/Public/Concepts/Concepts.h | 30 +++++ .../Source/Public/Concepts/Constructible.h | 30 +++++ .../Source/Public/Concepts/Convertible.h | 15 +++ .../Source/Public/Concepts/Derived.h | 16 +++ .../Source/Public/Concepts/Destructible.h | 15 +++ .../Source/Public/Concepts/Same.h | 15 +++ .../Source/Public/Testing/ConceptsTesting.h | 13 ++ 10 files changed, 277 insertions(+) create mode 100644 Redcraft.Utility/Source/Private/Testing/ConceptsTesting.cpp create mode 100644 Redcraft.Utility/Source/Public/Concepts/BuiltinType.h create mode 100644 Redcraft.Utility/Source/Public/Concepts/Concepts.h create mode 100644 Redcraft.Utility/Source/Public/Concepts/Constructible.h create mode 100644 Redcraft.Utility/Source/Public/Concepts/Convertible.h create mode 100644 Redcraft.Utility/Source/Public/Concepts/Derived.h create mode 100644 Redcraft.Utility/Source/Public/Concepts/Destructible.h create mode 100644 Redcraft.Utility/Source/Public/Concepts/Same.h create mode 100644 Redcraft.Utility/Source/Public/Testing/ConceptsTesting.h diff --git a/Redcraft.Utility/Source/Private/Testing/ConceptsTesting.cpp b/Redcraft.Utility/Source/Private/Testing/ConceptsTesting.cpp new file mode 100644 index 0000000..a2a78e1 --- /dev/null +++ b/Redcraft.Utility/Source/Private/Testing/ConceptsTesting.cpp @@ -0,0 +1,121 @@ +#include "Testing/ConceptsTesting.h" +#include "Misc/AssertionMacros.h" +#include "Concepts/Concepts.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +// Warning: The test here is not a complete test, it is only used to determine whether the environment supports the concepts + +NAMESPACE_UNNAMED_BEGIN + +int32 TestObject; +void TestFunction() { } + +struct FTestStructA { }; +struct FTestStructB : FTestStructA { int32 Member; }; +struct FTestStructC { FTestStructC() { } }; +struct FTestStructD { FTestStructD(const FTestStructD&) { } }; +struct FTestStructE { virtual void Member() = 0; }; +struct FTestStructF { int32 MemberA; private: int32 MemberB; }; +struct FTestStructG { char MemberA; float MemberB; short MemberC; int MemberD; }; +struct FTestStructH final : FTestStructE { virtual void Member() override { } }; +struct FTestStructI { int32 MemberA; double MemberB; FTestStructI(int32 A, double B) { } FTestStructI& operator=(int32) { return *this; }; }; +struct FTestStructJ { int32 MemberA; double MemberB; FTestStructJ() { }; }; +struct FTestStructK { int32 MemberA; double MemberB; FTestStructK() = default; }; +struct FTestStructL { int32 MemberA; double MemberB; FTestStructL() = delete; }; +struct FTestStructM { int32 MemberA; double MemberB; FTestStructM(const FTestStructM&) { }; FTestStructM& operator=(const FTestStructM&) { return *this; }; }; +struct FTestStructN { int32 MemberA; double MemberB; FTestStructN(const FTestStructN&) = default; FTestStructN& operator=(const FTestStructN&) = default; }; +struct FTestStructO { int32 MemberA; double MemberB; FTestStructO(const FTestStructO&) = delete; FTestStructO& operator=(const FTestStructO&) = delete; }; +struct FTestStructP { int32 MemberA; double MemberB; FTestStructP(FTestStructP&&) { }; FTestStructP& operator=(FTestStructP&&) { return *this; }; }; +struct FTestStructQ { int32 MemberA; double MemberB; FTestStructQ(FTestStructQ&&) = default; FTestStructQ& operator=(FTestStructQ&&) = default; }; +struct FTestStructR { int32 MemberA; double MemberB; FTestStructR(FTestStructR&&) = delete; FTestStructR& operator=(FTestStructR&&) = delete; }; +struct FTestStructS { int32 MemberA; double MemberB; ~FTestStructS() { } }; +struct FTestStructT { int32 MemberA; double MemberB; ~FTestStructT() = default; }; +struct FTestStructU { int32 MemberA; double MemberB; ~FTestStructU() = delete; }; +struct FTestStructV { int32 MemberA; double MemberB; virtual ~FTestStructV() { }; }; +struct FTestStructW { int32 MemberA; double MemberB; operator FTestStructV() { return FTestStructV(); } }; + +enum ETestEnum { }; +enum class ETestEnumClass { }; +enum class ETestEnumClass8 : uint8 { }; +enum class ETestEnumClass32 : uint32 { }; +enum class ETestEnumClass64 : uint64 { }; + +union FTestUnion { }; + +NAMESPACE_UNNAMED_END + +void TestConcepts() +{ + // Same.h + + always_check(!(CSameAs)); + always_check((CSameAs)); + + // Destructible.h + + always_check(CDestructible); + always_check(CDestructible); + always_check(!CDestructible); + + // Derived.h + + always_check(!(CDerivedFrom)); + always_check((CDerivedFrom)); + always_check(!(CDerivedFrom)); + + // Convertible.h + + always_check((CConvertibleTo)); + always_check(!(CConvertibleTo)); + always_check((CConvertibleTo)); + always_check(!(CConvertibleTo)); + always_check((CConvertibleTo)); + + // Constructible.h + + always_check((CConstructibleFrom)); + always_check((CConstructibleFrom)); + always_check(!(CConstructibleFrom)); + always_check((CConstructibleFrom)); + always_check((CConstructibleFrom)); + + always_check(!CDefaultInitializable); + always_check(CDefaultInitializable); + always_check(CDefaultInitializable); + always_check(!CDefaultInitializable); + + always_check(CMoveConstructible); + always_check(CMoveConstructible); + always_check(!CMoveConstructible); + + always_check(CCopyConstructible); + always_check(CCopyConstructible); + always_check(!CCopyConstructible); + + // BuiltinType.h + + always_check(CIntegral); + always_check(CIntegral); + always_check(!CIntegral); + + always_check(CSignedIntegral); + always_check(!CSignedIntegral); + + always_check(!CUnsignedIntegral); + always_check(CUnsignedIntegral); + + always_check(!CNonBooleanIntegral); + always_check(CNonBooleanIntegral); + always_check(!CNonBooleanIntegral); + + always_check(!CFloatingPoint); + always_check(CFloatingPoint); + +} + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp b/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp index c608dc0..30c846a 100644 --- a/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp +++ b/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp @@ -8,6 +8,8 @@ NAMESPACE_MODULE_BEGIN(Utility) // Warning: The test here is not a complete test, it is only used to determine whether the environment supports the traits +NAMESPACE_UNNAMED_BEGIN + int32 TestObject; void TestFunction() { } @@ -43,6 +45,8 @@ enum class ETestEnumClass64 : uint64 { }; union FTestUnion { }; +NAMESPACE_UNNAMED_END + void TestTypeTraits() { // HelperClasses.h diff --git a/Redcraft.Utility/Source/Public/Concepts/BuiltinType.h b/Redcraft.Utility/Source/Public/Concepts/BuiltinType.h new file mode 100644 index 0000000..6b6d098 --- /dev/null +++ b/Redcraft.Utility/Source/Public/Concepts/BuiltinType.h @@ -0,0 +1,18 @@ +#pragma once + +#include "CoreTypes.h" +#include "TypeTraits/TypeTraits.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +template concept CIntegral = TIsIntegral::Value; +template concept CSignedIntegral = CIntegral && TIsSigned::Value; +template concept CUnsignedIntegral = CIntegral && TIsUnsigned::Value; +template concept CNonBooleanIntegral = CIntegral && !TIsSame::Type, bool>::Value; +template concept CFloatingPoint = TIsFloatingPoint::Value; + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Concepts/Concepts.h b/Redcraft.Utility/Source/Public/Concepts/Concepts.h new file mode 100644 index 0000000..c01449f --- /dev/null +++ b/Redcraft.Utility/Source/Public/Concepts/Concepts.h @@ -0,0 +1,30 @@ +#pragma once + +#include "CoreTypes.h" +#include "Concepts/Same.h" +#include "Concepts/Derived.h" +#include "Concepts/BuiltinType.h" +#include "Concepts/Convertible.h" +#include "Concepts/Destructible.h" +#include "Concepts/Constructible.h" + +//template concept CBooleanTestable; // Prerequisites: Forward +//template concept CMovable; // Prerequisites: CAssignableFrom +//template concept CCopyable; // Prerequisites: CAssignableFrom +//template concept CSemiregular; // Prerequisites: CCopyable +//template concept CRegular; // Prerequisites: CEqualityComparable + +//template concept CAssignableFrom; // Prerequisites: Forward +//template concept CEqualityComparable; // Prerequisites: CBooleanTestable +//template concept CEqualityComparableWith; // Prerequisites: CBooleanTestable +//template concept CTotallyOrdered; // Prerequisites: CBooleanTestable +//template concept CTotallyOrderedWith; // Prerequisites: CBooleanTestable + +//template concept CCommonWith; // Prerequisites: Declval +//template concept CCommonReferenceWith; // Prerequisites: Declval +//template concept CInvocable; // Prerequisites: Invoke, Forward +//template concept CRegularInvocable; // Prerequisites: Invoke, Forward +//template concept CPredicate; // Prerequisites: CBooleanTestable, CRegularInvocable +//template concept CRelation; // Prerequisites: CPredicate +//template concept CEquivalenceRelation // Prerequisites: CRelation +//template concept CStrictWeakOrder // Prerequisites: CRelation diff --git a/Redcraft.Utility/Source/Public/Concepts/Constructible.h b/Redcraft.Utility/Source/Public/Concepts/Constructible.h new file mode 100644 index 0000000..74d3158 --- /dev/null +++ b/Redcraft.Utility/Source/Public/Concepts/Constructible.h @@ -0,0 +1,30 @@ +#pragma once + +#include "CoreTypes.h" +#include "TypeTraits/TypeTraits.h" +#include "Concepts/Convertible.h" + +#include + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +template +concept CConstructibleFrom = CDestructible && TIsConstructible::Value; + +template +concept CDefaultInitializable = CConstructibleFrom && requires { T{}; ::new(static_cast(nullptr)) T; }; + +template +concept CMoveConstructible = CConstructibleFrom && CConvertibleTo; + +template +concept CCopyConstructible = CMoveConstructible && + CConstructibleFrom && CConvertibleTo && + CConstructibleFrom && CConvertibleTo && + CConstructibleFrom && CConvertibleTo; + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Concepts/Convertible.h b/Redcraft.Utility/Source/Public/Concepts/Convertible.h new file mode 100644 index 0000000..dc2f2a3 --- /dev/null +++ b/Redcraft.Utility/Source/Public/Concepts/Convertible.h @@ -0,0 +1,15 @@ +#pragma once + +#include "CoreTypes.h" +#include "TypeTraits/TypeTraits.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +template +concept CConvertibleTo = TIsConvertible::Value && requires(T(&Func)()) { static_cast(Func()); }; + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Concepts/Derived.h b/Redcraft.Utility/Source/Public/Concepts/Derived.h new file mode 100644 index 0000000..763696a --- /dev/null +++ b/Redcraft.Utility/Source/Public/Concepts/Derived.h @@ -0,0 +1,16 @@ +#pragma once + +#include "CoreTypes.h" +#include "TypeTraits/TypeTraits.h" +#include "Concepts/Convertible.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +template +concept CDerivedFrom = TIsBaseOf::Value && CConvertibleTo; + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Concepts/Destructible.h b/Redcraft.Utility/Source/Public/Concepts/Destructible.h new file mode 100644 index 0000000..36c19f8 --- /dev/null +++ b/Redcraft.Utility/Source/Public/Concepts/Destructible.h @@ -0,0 +1,15 @@ +#pragma once + +#include "CoreTypes.h" +#include "TypeTraits/TypeTraits.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +template +concept CDestructible = TIsDestructible::Value; + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Concepts/Same.h b/Redcraft.Utility/Source/Public/Concepts/Same.h new file mode 100644 index 0000000..1a1ee61 --- /dev/null +++ b/Redcraft.Utility/Source/Public/Concepts/Same.h @@ -0,0 +1,15 @@ +#pragma once + +#include "CoreTypes.h" +#include "TypeTraits/TypeTraits.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +template +concept CSameAs = TIsSame::Value && TIsSame::Value; + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Testing/ConceptsTesting.h b/Redcraft.Utility/Source/Public/Testing/ConceptsTesting.h new file mode 100644 index 0000000..8b3232d --- /dev/null +++ b/Redcraft.Utility/Source/Public/Testing/ConceptsTesting.h @@ -0,0 +1,13 @@ +#pragma once + +#include "CoreTypes.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +void REDCRAFTUTILITY_API TestConcepts(); + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END