From 10b8e0fc453ff0af09cdffcf5eae05ea20baa38d Mon Sep 17 00:00:00 2001 From: _Redstone_c_ Date: Wed, 11 Jan 2023 23:14:40 +0800 Subject: [PATCH] fix(templates): fix requires of TUniquePtr and TSharedPtr for arrays --- .../Private/Testing/TemplatesTesting.cpp | 57 +++++++++++++++++ .../Source/Public/Templates/SharedPointer.h | 63 +++++++++++-------- .../Source/Public/Templates/UniquePointer.h | 8 +-- 3 files changed, 99 insertions(+), 29 deletions(-) diff --git a/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp b/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp index 83e5b02..9b3900d 100644 --- a/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp +++ b/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp @@ -1750,6 +1750,20 @@ void TestUniquePointer() always_check( FCounter::Num == 0); always_check(FArrayDeleter::Num == 4); + { + TUniquePtr TempA; + TUniquePtr TempB = MoveTemp(TempA); + TUniquePtr TempC; + TempC = MoveTemp(TempA); + } + + { + TUniquePtr TempA; + TUniquePtr TempB = MoveTemp(TempA); + TUniquePtr TempC; + TempC = MoveTemp(TempA); + } + } void TestSharedPointer() @@ -2205,6 +2219,49 @@ void TestSharedPointer() TSharedRef TempB(Ptr->FuncTest()); } } + + { + TSharedRef TempA = MakeShared(); + TSharedRef TempB = TempA; + TSharedRef TempC = MakeShared(); + TempC = TempA; + } + + { + TSharedRef TempA = MakeShared(4); + TSharedRef TempB = TempA; + TSharedRef TempC = MakeShared(4); + TempC = TempA; + } + + { + TSharedPtr TempA; + TSharedPtr TempB = TempA; + TSharedPtr TempC; + TempC = TempA; + } + + { + TSharedPtr TempA; + TSharedPtr TempB = TempA; + TSharedPtr TempC; + TempC = TempA; + } + + { + TWeakPtr TempA; + TWeakPtr TempB = TempA; + TWeakPtr TempC; + TempC = TempA; + } + + { + TWeakPtr TempA; + TWeakPtr TempB = TempA; + TWeakPtr TempC; + TempC = TempA; + } + } NAMESPACE_UNNAMED_BEGIN diff --git a/Redcraft.Utility/Source/Public/Templates/SharedPointer.h b/Redcraft.Utility/Source/Public/Templates/SharedPointer.h index 162dae8..167a507 100644 --- a/Redcraft.Utility/Source/Public/Templates/SharedPointer.h +++ b/Redcraft.Utility/Source/Public/Templates/SharedPointer.h @@ -290,8 +290,21 @@ public: : Pointer(InPtr), Controller(InController) { } - NODISCARD FORCEINLINE operator TSharedRef() && { check_code({ return TSharedRef(Pointer, Exchange(Controller, nullptr)); }); return TSharedRef(Pointer, Controller); } - NODISCARD FORCEINLINE operator TSharedPtr() && { check_code({ return TSharedPtr(Pointer, Exchange(Controller, nullptr)); }); return TSharedPtr(Pointer, Controller); } + template requires (CArray == CArray && ((!CArray && CConvertibleTo) + || (CArray && CConvertibleTo(*)[], TRemoveExtent(*)[]>))) + NODISCARD FORCEINLINE operator TSharedRef() && + { + check_code({ return TSharedRef(Pointer, Exchange(Controller, nullptr)); }); + return TSharedRef(Pointer, Controller); + } + + template requires (CArray == CArray && ((!CArray && CConvertibleTo) + || (CArray && CConvertibleTo(*)[], TRemoveExtent(*)[]>))) + NODISCARD FORCEINLINE operator TSharedPtr() && + { + check_code({ return TSharedPtr(Pointer, Exchange(Controller, nullptr)); }); + return TSharedPtr(Pointer, Controller); + } # if DO_CHECK @@ -301,7 +314,7 @@ public: private: - TRemoveExtent* Pointer; + TRemoveExtent* Pointer; FSharedController* Controller; }; @@ -671,14 +684,14 @@ public: FORCEINLINE TSharedRef(const TSharedRef& InValue) : TSharedRef(InValue, InValue.Get()) { } /** Constructs a TSharedRef which shares ownership of the array managed by 'InValue'. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TSharedRef(const TSharedRef& InValue) : TSharedRef(InValue, InValue.Get()) { } /** Constructs a TSharedRef which shares ownership of the array managed by 'InValue'. */ FORCEINLINE TSharedRef(TSharedRef&& InValue) : TSharedRef(InValue) { } /** Constructs a TSharedRef which shares ownership of the array managed by 'InValue'. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TSharedRef(TSharedRef&& InValue) : TSharedRef(InValue) { } /** If this owns an array and it is the last TSharedRef owning it, the array is destroyed through the owned deleter. */ @@ -704,7 +717,7 @@ public: } /** Replaces the managed array with the one managed by 'InValue'. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TSharedRef& operator=(const TSharedRef& InValue) { return *this = *reinterpret_cast(&InValue); } /** Replaces the managed array with the one managed by 'InValue'. */ @@ -715,7 +728,7 @@ public: } /** Replaces the managed array with the one managed by 'InValue'. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TSharedRef& operator=(TSharedRef&& InValue) { return *this = MoveTemp(*reinterpret_cast(&InValue)); } /** Compares the pointer values of two TSharedRef. */ @@ -1247,26 +1260,26 @@ public: FORCEINLINE TSharedPtr(const TSharedPtr& InValue) : TSharedPtr(InValue, InValue.Get()) { } /** Constructs a TSharedPtr which shares ownership of the array managed by 'InValue'. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TSharedPtr(const TSharedPtr& InValue) : TSharedPtr(InValue, InValue.Get()) { } /** Constructs a TSharedPtr which shares ownership of the array managed by 'InValue'. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TSharedPtr(const TSharedRef& InValue) : TSharedPtr(InValue, InValue.Get()) { } /** Constructs a TSharedPtr which shares ownership of the array managed by 'InValue'. */ FORCEINLINE TSharedPtr(TSharedPtr&& InValue) : TSharedPtr(MoveTemp(InValue), InValue.Get()) { } /** Constructs a TSharedPtr which shares ownership of the array managed by 'InValue'. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TSharedPtr(TSharedPtr&& InValue) : TSharedPtr(MoveTemp(InValue), InValue.Get()) { } /** Constructs a TSharedPtr which shares ownership of the array managed by 'InValue'. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TSharedPtr(TSharedRef&& InValue) : TSharedPtr(MoveTemp(InValue), InValue.Get()) { } /** Constructs a TSharedPtr which gets ownership of the array managed by 'InValue'. */ - template requires (CConvertibleTo && CArray && (CDestructible || CLValueReference)) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray && (CDestructible || CLValueReference)) FORCEINLINE TSharedPtr(TUniquePtr&& InValue) : TSharedPtr(InValue.Release(), Forward(InValue.GetDeleter())) { } /** If this owns an array and it is the last TSharedPtr owning it, the array is destroyed through the owned deleter. */ @@ -1298,11 +1311,11 @@ public: } /** Replaces the managed array with the one managed by 'InValue'. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TSharedPtr& operator=(const TSharedPtr& InValue) { return *this = *reinterpret_cast(&InValue); } /** Replaces the managed array with the one managed by 'InValue'. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TSharedPtr& operator=(const TSharedRef& InValue) { return *reinterpret_cast*>(this) = InValue; } /** Replaces the managed array with the one managed by 'InValue'. */ @@ -1322,15 +1335,15 @@ public: } /** Replaces the managed array with the one managed by 'InValue'. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TSharedPtr& operator=(TSharedPtr&& InValue) { return *this = MoveTemp(*reinterpret_cast(&InValue)); } /** Replaces the managed array with the one managed by 'InValue'. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TSharedPtr& operator=(TSharedRef&& InValue) { return *reinterpret_cast*>(this) = MoveTemp(InValue); } /** Replaces the managed array with the one managed by 'InValue'. */ - template requires (CConvertibleTo && CArray && (CDestructible || CLValueReference)) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray && (CDestructible || CLValueReference)) FORCEINLINE TSharedPtr& operator=(TUniquePtr&& InValue) { return Swap(*this, TSharedPtr(MoveTemp(InValue))); } /** Effectively the same as calling Reset(). */ @@ -1674,25 +1687,25 @@ public: } /** Constructs new TWeakPtr which shares an array managed by 'InValue'. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE constexpr TWeakPtr(const TWeakPtr& InValue) : TWeakPtr(*reinterpret_cast(&InValue)) { } /** Move constructors. Moves a TWeakPtr instance from 'InValue' into this. */ FORCEINLINE TWeakPtr(TWeakPtr&& InValue) : Pointer(Exchange(InValue.Pointer, nullptr)), Controller(Exchange(InValue.Controller, nullptr)) { } /** Move constructors. Moves a TWeakPtr instance from 'InValue' into this. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE constexpr TWeakPtr(TWeakPtr&& InValue) : TWeakPtr(MoveTemp(*reinterpret_cast(&InValue))) { } /** Constructs a weak pointer from a shared reference. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE constexpr TWeakPtr(const TSharedRef& InValue) : Pointer(InValue.Pointer), Controller(InValue.Controller) { Controller->AddWeakReference(); } /** Constructs a weak pointer from a shared pointer. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE constexpr TWeakPtr(const TSharedPtr& InValue) : Pointer(InValue.Pointer), Controller(InValue.Controller) { if (Controller != nullptr) @@ -1730,7 +1743,7 @@ public: } /** Replaces the managed array with the one managed by 'InValue'. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TWeakPtr& operator=(const TWeakPtr& InValue) { return *this = *reinterpret_cast(&InValue); } /** Replaces the managed array with the one managed by 'InValue'. */ @@ -1750,11 +1763,11 @@ public: } /** Replaces the managed array with the one managed by 'InValue'. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TWeakPtr& operator=(TWeakPtr&& InValue) { return *this = MoveTemp(*reinterpret_cast(&InValue)); } /** Assignment operator sets this weak pointer from a shared reference. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TWeakPtr& operator=(const TSharedRef& InValue) { if (Controller != nullptr) @@ -1771,7 +1784,7 @@ public: } /** Assignment operator sets this weak pointer from a shared pointer. */ - template requires (CConvertibleTo && CArray) + template requires (CConvertibleTo(*)[], T(*)[]> && CArray) FORCEINLINE TWeakPtr& operator=(const TSharedPtr& InValue) { if (Controller != nullptr) diff --git a/Redcraft.Utility/Source/Public/Templates/UniquePointer.h b/Redcraft.Utility/Source/Public/Templates/UniquePointer.h index 97e338e..b35baae 100644 --- a/Redcraft.Utility/Source/Public/Templates/UniquePointer.h +++ b/Redcraft.Utility/Source/Public/Templates/UniquePointer.h @@ -407,7 +407,7 @@ public: /** Move assignment operator. Transfers ownership from 'InValue' to *this. */ template requires (CConvertibleTo && !CArray && !CReference && CAssignableFrom) - FORCEINLINE constexpr TUniquePtr& operator=(TUniquePtr&& InValue) + FORCEINLINE constexpr TUniquePtr& operator=(TUniquePtr&& InValue) { Reset(InValue.Release()); GetDeleter() = Forward(InValue.GetDeleter()); @@ -526,7 +526,7 @@ public: FORCEINLINE constexpr TUniquePtr(TUniquePtr&& InValue) : Storage(InValue.Release(), Forward(InValue.GetDeleter())) { } /** Constructs a TUniquePtr by transferring ownership from 'InValue' to *this and stores the nullptr in 'InValue'. */ - template requires (CConvertibleTo && CArray + template requires (CConvertibleTo(*)[], T(*)[]> && CArray && ((CReference && CSameAs) || (!CReference && CConvertibleTo))) FORCEINLINE constexpr TUniquePtr(TUniquePtr&& InValue) : Storage(InValue.Release(), Forward(InValue.GetDeleter())) { } @@ -542,9 +542,9 @@ public: } /** Move assignment operator. Transfers ownership from 'InValue' to *this. */ - template requires (CConvertibleTo + template requires (CConvertibleTo(*)[], T(*)[]> && CArray && !CReference && CAssignableFrom) - FORCEINLINE constexpr TUniquePtr& operator=(TUniquePtr&& InValue) + FORCEINLINE constexpr TUniquePtr& operator=(TUniquePtr&& InValue) { Reset(InValue.Release()); GetDeleter() = Forward(InValue.GetDeleter());