From 52cd65dbadf3988c21baa2a6789f72b742af090e Mon Sep 17 00:00:00 2001 From: _Redstone_c_ Date: Mon, 16 Jan 2023 19:27:39 +0800 Subject: [PATCH] feat(templates): add TPointerTraits and the corresponding testing --- .../Private/Testing/TemplatesTesting.cpp | 23 +++++++ .../Source/Public/Templates/PointerTraits.h | 64 +++++++++++++++++++ .../Source/Public/Templates/SharedPointer.h | 4 ++ .../Source/Public/Templates/Templates.h | 1 + .../Source/Public/Templates/UniquePointer.h | 4 ++ 5 files changed, 96 insertions(+) create mode 100644 Redcraft.Utility/Source/Public/Templates/PointerTraits.h diff --git a/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp b/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp index 9b3900d..beb1ae7 100644 --- a/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp +++ b/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp @@ -2297,6 +2297,29 @@ void TestMiscTemplates() always_check(TestFunctionB(&ObjectA) == 1); always_check(TestFunctionB(AddressOf(ObjectA)) == 0); always_check(AddressOf(TestMiscTemplates) == &TestMiscTemplates); + + always_check(!TPointerTraits::bIsPointer); + + always_check(TPointerTraits::bIsPointer); + always_check((CSameAs::PointerType, int64*>)); + always_check((CSameAs::ElementType, int64>)); + always_check(TPointerTraits::ToAddress(nullptr) == nullptr); + + always_check(TPointerTraits::bIsPointer); + always_check((CSameAs::PointerType, int64(*)[]>)); + always_check((CSameAs::ElementType, int64>)); + always_check(TPointerTraits::ToAddress(nullptr) == nullptr); + + always_check(TPointerTraits>::bIsPointer); + always_check((CSameAs>::PointerType, TSharedPtr>)); + always_check((CSameAs>::ElementType, int64>)); + always_check(TPointerTraits>::ToAddress(nullptr) == nullptr); + + always_check(TPointerTraits>::bIsPointer); + always_check((CSameAs>::PointerType, TSharedPtr>)); + always_check((CSameAs>::ElementType, int64>)); + always_check(TPointerTraits>::ToAddress(nullptr) == nullptr); + } NAMESPACE_END(Testing) diff --git a/Redcraft.Utility/Source/Public/Templates/PointerTraits.h b/Redcraft.Utility/Source/Public/Templates/PointerTraits.h new file mode 100644 index 0000000..7d1b8ec --- /dev/null +++ b/Redcraft.Utility/Source/Public/Templates/PointerTraits.h @@ -0,0 +1,64 @@ +#pragma once + +#include "CoreTypes.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +/** The class template provides the standardized way to access certain properties of pointer-like types. */ +template +struct TPointerTraits +{ + static constexpr bool bIsPointer = false; +}; + +/** A specialization of TPointerTraits is provided for pointer types T*. */ +template +struct TPointerTraits +{ + static constexpr bool bIsPointer = true; + + using PointerType = T*; + using ElementType = T; + + static FORCEINLINE constexpr ElementType* ToAddress(PointerType InPtr) + { + return InPtr; + } +}; + +/** A specialization of TPointerTraits is provided for array pointer types T(*)[]. */ +template +struct TPointerTraits +{ + static constexpr bool bIsPointer = true; + + using PointerType = T(*)[]; + using ElementType = T; + + static FORCEINLINE constexpr ElementType* ToAddress(PointerType InPtr) + { + return InPtr; + } +}; + +/** A specialization of TPointerTraits is provided for pointer-like type. */ +#define DEFINE_TPointerTraits(TPtr) \ + template \ + struct TPointerTraits> \ + { \ + static constexpr bool bIsPointer = true; \ + \ + using PointerType = TPtr; \ + using ElementType = TPtr::ElementType; \ + \ + static FORCEINLINE constexpr ElementType* ToAddress(const PointerType& InPtr) \ + { \ + return InPtr.Get(); \ + } \ + }; + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Templates/SharedPointer.h b/Redcraft.Utility/Source/Public/Templates/SharedPointer.h index 469cc91..4c6db25 100644 --- a/Redcraft.Utility/Source/Public/Templates/SharedPointer.h +++ b/Redcraft.Utility/Source/Public/Templates/SharedPointer.h @@ -8,6 +8,7 @@ #include "Memory/MemoryOperator.h" #include "Templates/Noncopyable.h" #include "TypeTraits/PrimaryType.h" +#include "Templates/PointerTraits.h" #include "Templates/UniquePointer.h" #include "TypeTraits/Miscellaneous.h" #include "TypeTraits/TypeProperties.h" @@ -1896,6 +1897,9 @@ NODISCARD FORCEINLINE TSharedPtr ReinterpretCast(TSharedPtr&& InValue) return TSharedPtr(MoveTemp(InValue), reinterpret_cast(InValue.Get())); } +DEFINE_TPointerTraits(TSharedRef); +DEFINE_TPointerTraits(TSharedPtr); + NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/Templates/Templates.h b/Redcraft.Utility/Source/Public/Templates/Templates.h index 6efe6d8..0b9c1a5 100644 --- a/Redcraft.Utility/Source/Public/Templates/Templates.h +++ b/Redcraft.Utility/Source/Public/Templates/Templates.h @@ -15,5 +15,6 @@ #include "Templates/Function.h" #include "Templates/Atomic.h" #include "Templates/ScopeHelper.h" +#include "Templates/PointerTraits.h" #include "Templates/UniquePointer.h" #include "Templates/SharedPointer.h" diff --git a/Redcraft.Utility/Source/Public/Templates/UniquePointer.h b/Redcraft.Utility/Source/Public/Templates/UniquePointer.h index 1a0e5fd..e1e2e46 100644 --- a/Redcraft.Utility/Source/Public/Templates/UniquePointer.h +++ b/Redcraft.Utility/Source/Public/Templates/UniquePointer.h @@ -5,6 +5,7 @@ #include "Templates/Utility.h" #include "Templates/Noncopyable.h" #include "TypeTraits/PrimaryType.h" +#include "Templates/PointerTraits.h" #include "TypeTraits/Miscellaneous.h" #include "TypeTraits/TypeProperties.h" #include "TypeTraits/SupportedOperations.h" @@ -682,6 +683,9 @@ void MakeUnique(Ts&&...) = delete; static_assert(sizeof(TUniqueRef) == sizeof(int32*), "The byte size of TUniqueRef is unexpected"); static_assert(sizeof(TUniquePtr) == sizeof(int32*), "The byte size of TUniquePtr is unexpected"); +DEFINE_TPointerTraits(TUniqueRef); +DEFINE_TPointerTraits(TUniquePtr); + NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END