From 60b4ec6f585240daa9c29767057c01220c7d2a49 Mon Sep 17 00:00:00 2001 From: _Redstone_c_ Date: Fri, 10 Dec 2021 21:43:57 +0800 Subject: [PATCH] feat(typetraits): add TypeTraits/PrimaryType.h and the corresponding testing --- .../Private/Testing/TypeTraitsTesting.cpp | 113 ++++++++++++++++++ .../Source/Public/Testing/TypeTraitsTesting.h | 13 ++ .../Source/Public/TypeTraits/HelperClasses.h | 52 ++++++++ .../Source/Public/TypeTraits/PrimaryType.h | 44 +++++++ 4 files changed, 222 insertions(+) create mode 100644 Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp create mode 100644 Redcraft.Utility/Source/Public/Testing/TypeTraitsTesting.h create mode 100644 Redcraft.Utility/Source/Public/TypeTraits/HelperClasses.h create mode 100644 Redcraft.Utility/Source/Public/TypeTraits/PrimaryType.h diff --git a/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp b/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp new file mode 100644 index 0000000..842d6eb --- /dev/null +++ b/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp @@ -0,0 +1,113 @@ +#include "Testing/TypeTraitsTesting.h" +#include "Misc/AssertionMacros.h" +#include "TypeTraits/HelperClasses.h" +#include "TypeTraits/PrimaryType.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 traits + +int32 TestObject; +void TestFunction() { } + +struct FTestStruct { }; + +enum ETestEnum { }; + +enum class ETestEnumClass { }; + +union FTestUnion { }; + +void TestTypeTraits() +{ + // HelperClasses.h + + always_check(TypeTraits::TIntegralConstant<1>::Value == 1); + always_check(static_cast(TypeTraits::TIntegralConstant<2>::Value) == 2); + always_check(TypeTraits::TIntegralConstant<3>() == 3); + + always_check(!TypeTraits::FFalse::Value); + always_check(TypeTraits::FTrue::Value); + + always_check(TypeTraits::TAnd::Value); + always_check(!TypeTraits::TAnd::Value); + always_check((TypeTraits::TAnd::Value)); + always_check(!(TypeTraits::TAnd::Value)); + always_check(!(TypeTraits::TAnd::Value)); + always_check(!(TypeTraits::TAnd::Value)); + + always_check(TypeTraits::TOr::Value); + always_check(!TypeTraits::TOr::Value); + always_check((TypeTraits::TOr::Value)); + always_check((TypeTraits::TOr::Value)); + always_check((TypeTraits::TOr::Value)); + always_check(!(TypeTraits::TOr::Value)); + + always_check(!TypeTraits::TNot::Value); + always_check(TypeTraits::TNot::Value); + + // PrimaryType.h + + always_check(!TypeTraits::TIsVoid::Value); + always_check(TypeTraits::TIsVoid::Value); + always_check(TypeTraits::TIsVoid::Value); + always_check(TypeTraits::TIsVoid::Value); + always_check(TypeTraits::TIsVoid::Value); + + always_check(!TypeTraits::TIsNullPointer::Value); + always_check(TypeTraits::TIsNullPointer::Value); + + always_check(TypeTraits::TIsIntegral::Value); + always_check(!TypeTraits::TIsIntegral::Value); + + always_check(!TypeTraits::TIsFloatingPoint::Value); + always_check(TypeTraits::TIsFloatingPoint::Value); + + always_check(!TypeTraits::TIsArray::Value); + always_check(TypeTraits::TIsArray::Value); + always_check(TypeTraits::TIsArray::Value); + + always_check(!TypeTraits::TIsPointer::Value); + always_check(TypeTraits::TIsPointer::Value); + + always_check(!TypeTraits::TIsLValueReference::Value); + always_check(TypeTraits::TIsLValueReference::Value); + always_check(!TypeTraits::TIsLValueReference::Value); + + always_check(!TypeTraits::TIsRValueReference::Value); + always_check(!TypeTraits::TIsRValueReference::Value); + always_check(TypeTraits::TIsRValueReference::Value); + + always_check(TypeTraits::TIsMemberObjectPointer::Value); + always_check(!TypeTraits::TIsMemberObjectPointer::Value); + + always_check(!TypeTraits::TIsMemberFunctionPointer::Value); + always_check(TypeTraits::TIsMemberFunctionPointer::Value); + + always_check(!TypeTraits::TIsEnum::Value); + always_check(!TypeTraits::TIsEnum::Value); + always_check(TypeTraits::TIsEnum::Value); + always_check(TypeTraits::TIsEnum::Value); + + always_check(!TypeTraits::TIsUnion::Value); + always_check(!TypeTraits::TIsUnion::Value); + always_check(TypeTraits::TIsUnion::Value); + + always_check(!TypeTraits::TIsUnion::Value); + always_check(!TypeTraits::TIsUnion::Value); + always_check(TypeTraits::TIsUnion::Value); + + always_check(!TypeTraits::TIsFunction::Value); + always_check(!TypeTraits::TIsFunction::Value); + always_check(!TypeTraits::TIsFunction::Value); + always_check(TypeTraits::TIsFunction::Value); + + always_check(!TypeTraits::TIsEnumClass::Value); + always_check(TypeTraits::TIsEnumClass::Value); +} + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Testing/TypeTraitsTesting.h b/Redcraft.Utility/Source/Public/Testing/TypeTraitsTesting.h new file mode 100644 index 0000000..369b559 --- /dev/null +++ b/Redcraft.Utility/Source/Public/Testing/TypeTraitsTesting.h @@ -0,0 +1,13 @@ +#pragma once + +#include "CoreTypes.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +void REDCRAFTUTILITY_API TestTypeTraits(); + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/TypeTraits/HelperClasses.h b/Redcraft.Utility/Source/Public/TypeTraits/HelperClasses.h new file mode 100644 index 0000000..e2bc9f4 --- /dev/null +++ b/Redcraft.Utility/Source/Public/TypeTraits/HelperClasses.h @@ -0,0 +1,52 @@ +#pragma once + +#include "CoreTypes.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) +NAMESPACE_BEGIN(TypeTraits) + +template +struct TConstant +{ + using Type = InType; + static constexpr Type Value = InValue; + constexpr operator Type() const { return Value; } + constexpr Type operator()() const { return Value; } +}; + +template +using TBoolConstant = TConstant; + +template +using TIntegralConstant = TConstant; + +using FTrue = TBoolConstant; +using FFalse = TBoolConstant; + +template +struct TAnd; + +template +struct TAnd : TBoolConstant::Value> { }; + +template <> +struct TAnd<> : FTrue { }; + +template +struct TOr; + +template +struct TOr : TBoolConstant::Value> { }; + +template <> +struct TOr<> : FFalse { }; + +template +struct TNot : TBoolConstant { }; + +NAMESPACE_END(TypeTraits) +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/TypeTraits/PrimaryType.h b/Redcraft.Utility/Source/Public/TypeTraits/PrimaryType.h new file mode 100644 index 0000000..847c9ac --- /dev/null +++ b/Redcraft.Utility/Source/Public/TypeTraits/PrimaryType.h @@ -0,0 +1,44 @@ +#pragma once + +#include "CoreTypes.h" +#include "TypeTraits/HelperClasses.h" + +#include + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) +NAMESPACE_BEGIN(TypeTraits) + +template struct TIsVoid : TBoolConstant> { }; +template struct TIsNullPointer : TBoolConstant> { }; +template struct TIsIntegral : TBoolConstant> { }; +template struct TIsFloatingPoint : TBoolConstant> { }; +template struct TIsArray : TBoolConstant> { }; +template struct TIsPointer : TBoolConstant> { }; +template struct TIsLValueReference : TBoolConstant> { }; +template struct TIsRValueReference : TBoolConstant> { }; +template struct TIsMemberObjectPointer : TBoolConstant> { }; +template struct TIsMemberFunctionPointer : TBoolConstant> { }; +template struct TIsEnum : TBoolConstant> { }; +template struct TIsUnion : TBoolConstant> { }; +template struct TIsClass : TBoolConstant> { }; +template struct TIsFunction : TBoolConstant> { }; + +NAMESPACE_PRIVATE_BEGIN + +static char(&Resolve(int))[2]; +static char Resolve(...); + +template +struct TIsEnumConvertibleToInt : TBoolConstant { }; + +NAMESPACE_PRIVATE_END + +template +struct TIsEnumClass : TBoolConstant, TNot>>::Value> { }; + +NAMESPACE_END(TypeTraits) +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END