From 97fbe0fc84eda320d38001acfb0842eaac3a11b8 Mon Sep 17 00:00:00 2001 From: _Redstone_c_ Date: Wed, 22 Dec 2021 23:24:25 +0800 Subject: [PATCH] feat(typetraits): add TypeTraits/Miscellaneous.h and the corresponding testing --- .../Private/Testing/TypeTraitsTesting.cpp | 147 +++++++++++++++++- .../Source/Public/TypeTraits/Miscellaneous.h | 62 ++++++++ 2 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 Redcraft.Utility/Source/Public/TypeTraits/Miscellaneous.h diff --git a/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp b/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp index 4eb5ef6..097869e 100644 --- a/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp +++ b/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp @@ -5,6 +5,7 @@ #include "TypeTraits/CompositeType.h" #include "TypeTraits/TypeProperties.h" #include "TypeTraits/SupportedOperations.h" +#include "TypeTraits/Miscellaneous.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) @@ -16,7 +17,7 @@ int32 TestObject; void TestFunction() { } struct FTestStructA { }; -struct FTestStructB { int32 Member; }; +struct FTestStructB : FTestStructA { int32 Member; }; struct FTestStructC { FTestStructC() { } }; struct FTestStructD { FTestStructD(const FTestStructD&) { } }; struct FTestStructE { virtual void Member() = 0; }; @@ -37,9 +38,13 @@ 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 { }; @@ -301,6 +306,146 @@ void TestTypeTraits() always_check(!TypeTraits::THasVirtualDestructor::Value); always_check(TypeTraits::THasVirtualDestructor::Value); + + // Miscellaneous.h + + always_check(TypeTraits::TRank::Value == 3); + always_check(TypeTraits::TRank::Value == 4); + always_check(TypeTraits::TRank::Value == 0); + + always_check(TypeTraits::TExtent::Value == 1); + always_check((TypeTraits::TExtent::Value == 2)); + always_check(TypeTraits::TExtent::Value == 0); + + always_check(!(TypeTraits::TIsSame::Value)); + always_check((TypeTraits::TIsSame::Value)); + + always_check(!(TypeTraits::TIsBaseOf::Value)); + always_check(!(TypeTraits::TIsBaseOf::Value)); + always_check((TypeTraits::TIsBaseOf::Value)); + + always_check((TypeTraits::TIsConvertible::Value)); + always_check(!(TypeTraits::TIsConvertible::Value)); + always_check((TypeTraits::TIsConvertible::Value)); + always_check(!(TypeTraits::TIsConvertible::Value)); + always_check((TypeTraits::TIsConvertible::Value)); + + always_check((TypeTraits::TIsInvocable::Value)); + always_check((TypeTraits::TIsInvocable::Value)); + always_check((TypeTraits::TIsInvocable::Value)); + always_check(!(TypeTraits::TIsInvocable::Value)); + always_check(!(TypeTraits::TIsInvocable::Value)); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check(!(TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + + TypeTraits::TAlignedStorage<32, 4>::Type Aligned4; + TypeTraits::TAlignedStorage<32, 8>::Type Aligned8; + TypeTraits::TAlignedStorage<32, 16>::Type Aligned16; + TypeTraits::TAlignedStorage<32, 32>::Type Aligned32; + always_check((int64)(&Aligned4) % 4 == 0); + always_check((int64)(&Aligned8) % 8 == 0); + always_check((int64)(&Aligned16) % 16 == 0); + always_check((int64)(&Aligned32) % 32 == 0); + + always_check(sizeof(TypeTraits::TAlignedUnion<8, int32, int32>::Type) == 8); + always_check(sizeof(TypeTraits::TAlignedUnion<0, int8, int32>::Type) == 4); + always_check(sizeof(TypeTraits::TAlignedUnion<0, int32, int64>::Type) == 8); + always_check(sizeof(TypeTraits::TAlignedUnion<0, int32, double>::Type) == 8); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + + always_check((TypeTraits::TIsSame::Type>::Value)); + always_check((TypeTraits::TIsSame::Type>::Value)); + } NAMESPACE_MODULE_END(Utility) diff --git a/Redcraft.Utility/Source/Public/TypeTraits/Miscellaneous.h b/Redcraft.Utility/Source/Public/TypeTraits/Miscellaneous.h new file mode 100644 index 0000000..6dc09e5 --- /dev/null +++ b/Redcraft.Utility/Source/Public/TypeTraits/Miscellaneous.h @@ -0,0 +1,62 @@ +#pragma once + +#include "CoreTypes.h" +#include "TypeTraits/HelperClasses.h" + +#include + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) +NAMESPACE_BEGIN(TypeTraits) + +NAMESPACE_PRIVATE_BEGIN + +template +struct TMaximum; + +template <> +struct TMaximum<> : TConstant { }; + +template +struct TMaximum : TConstant { }; + +template +struct TMaximum : TMaximum<(First < Second ? Second : First), Others...> { }; + +NAMESPACE_PRIVATE_END + +template struct TRank : TConstant> { }; +template struct TExtent : TConstant> { }; + +template struct TIsSame : TBoolConstant> { }; +template struct TIsBaseOf : TBoolConstant> { }; +template struct TIsConvertible : TBoolConstant> { }; +template struct TIsInvocable : TBoolConstant> { }; + +template struct TRemoveConst { using Type = NAMESPACE_STD::remove_const_t; }; +template struct TRemoveVolatile { using Type = NAMESPACE_STD::remove_volatile_t; }; +template struct TRemoveCV { using Type = NAMESPACE_STD::remove_cv_t; }; +template struct TRemovePointer { using Type = NAMESPACE_STD::remove_pointer_t; }; +template struct TRemoveReference { using Type = NAMESPACE_STD::remove_reference_t; }; +template struct TRemoveCVRef { using Type = NAMESPACE_STD::remove_cvref_t; }; +template struct TRemoveExtent { using Type = NAMESPACE_STD::remove_extent_t; }; +template struct TRemoveAllExtents { using Type = NAMESPACE_STD::remove_all_extents_t; }; + +template struct TMakeSigned { using Type = NAMESPACE_STD::make_signed_t; }; +template struct TMakeUnsigned { using Type = NAMESPACE_STD::make_unsigned_t; }; + +template struct TAlignedStorage { class Type { struct alignas(Align) { uint8 Pad[Size]; } Padding; }; }; +template struct TAlignedUnion { using Type = TAlignedStorage::Value, NAMESPACE_PRIVATE::TMaximum::Value>::Type; }; +template struct TDecay { using Type = NAMESPACE_STD::decay_t; }; +template struct TEnableIf { using Type = NAMESPACE_STD::enable_if_t; }; +template struct TConditional { using Type = NAMESPACE_STD::conditional_t; }; +template struct TCommonType { using Type = NAMESPACE_STD::common_type_t; }; +template struct TUnderlyingType { using Type = NAMESPACE_STD::underlying_type_t; }; +template struct TInvokeResult { using Type = NAMESPACE_STD::invoke_result_t; }; +template struct TVoid { using Type = void; }; + +NAMESPACE_END(TypeTraits) +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END