From 5c2c1b4a4848dc44db72b58c37d1ce5404d5ad7c Mon Sep 17 00:00:00 2001 From: _Redstone_c_ Date: Sun, 15 Jan 2023 18:14:09 +0800 Subject: [PATCH] fix(templates): fix TSharedFromThis not working for indirectly derived --- .../Source/Public/Templates/SharedPointer.h | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/Redcraft.Utility/Source/Public/Templates/SharedPointer.h b/Redcraft.Utility/Source/Public/Templates/SharedPointer.h index 66e3e27..d4a1bc3 100644 --- a/Redcraft.Utility/Source/Public/Templates/SharedPointer.h +++ b/Redcraft.Utility/Source/Public/Templates/SharedPointer.h @@ -521,15 +521,18 @@ public: protected: - FORCEINLINE TSharedFromThis() = default; - FORCEINLINE TSharedFromThis(const TSharedFromThis&) = default; - FORCEINLINE TSharedFromThis(TSharedFromThis&&) = default; - FORCEINLINE TSharedFromThis& operator=(const TSharedFromThis&) = default; - FORCEINLINE TSharedFromThis& operator=(TSharedFromThis&&) = default; - FORCEINLINE ~TSharedFromThis() = default; + FORCEINLINE constexpr TSharedFromThis() : WeakThis() { } + + FORCEINLINE TSharedFromThis(const TSharedFromThis&) : TSharedFromThis() { } + + FORCEINLINE TSharedFromThis& operator=(const TSharedFromThis&) { return *this; } + + FORCEINLINE ~TSharedFromThis() = default; private: + using SharedFromThisType = TSharedFromThis; + // Here it is updated by the private constructor of TSharedRef or TSharedPtr. mutable TWeakPtr WeakThis; @@ -730,16 +733,18 @@ private: : Pointer(InPtr), Controller(InController) { check(!((Pointer == nullptr) ^ (Controller == nullptr))); - - if constexpr (CClass) + + if constexpr (CClass && !CVolatile && requires { typename T::SharedFromThisType; }) { - if constexpr (CDerivedFrom>) + using SharedFromThisType = T::SharedFromThisType; + + if constexpr (CDerivedFrom) { if (Pointer != nullptr) { - const TSharedFromThis& SharedFromThis = *Pointer; + const SharedFromThisType& SharedFromThis = *Pointer; checkf(!SharedFromThis.DoesSharedInstanceExist(), TEXT("This object is incorrectly managed by multiple TSharedRef or TSharedPtr.")); - SharedFromThis.WeakThis = *this; + SharedFromThis.WeakThis = ConstCast>(*this); } } } @@ -1206,15 +1211,17 @@ private: { check(!((Pointer == nullptr) ^ (Controller == nullptr))); - if constexpr (CClass) + if constexpr (CClass && !CVolatile && requires { typename T::SharedFromThisType; }) { - if constexpr (CDerivedFrom>) + using SharedFromThisType = T::SharedFromThisType; + + if constexpr (CDerivedFrom) { if (Pointer != nullptr) { - const TSharedFromThis& SharedFromThis = *Pointer; + const SharedFromThisType& SharedFromThis = *Pointer; checkf(!SharedFromThis.DoesSharedInstanceExist(), TEXT("This object is incorrectly managed by multiple TSharedRef or TSharedPtr.")); - SharedFromThis.WeakThis = *this; + SharedFromThis.WeakThis = ConstCast>(*this); } } }