From fb0d1e978d6f6d38eb03a1a0edbbbbf5ac26b459 Mon Sep 17 00:00:00 2001 From: _Redstone_c_ Date: Mon, 13 Feb 2023 23:31:58 +0800 Subject: [PATCH] refactor(memory): disable comparison of TUniquePtr and TSharedPtr with nullptr --- .../Source/Private/Testing/MemoryTesting.cpp | 32 +++++----- .../Source/Public/Memory/SharedPointer.h | 60 ++++++++++--------- .../Source/Public/Memory/UniquePointer.h | 60 ++++++++++--------- 3 files changed, 80 insertions(+), 72 deletions(-) diff --git a/Redcraft.Utility/Source/Private/Testing/MemoryTesting.cpp b/Redcraft.Utility/Source/Private/Testing/MemoryTesting.cpp index 7be45b2..805f523 100644 --- a/Redcraft.Utility/Source/Private/Testing/MemoryTesting.cpp +++ b/Redcraft.Utility/Source/Private/Testing/MemoryTesting.cpp @@ -291,9 +291,9 @@ void TestUniquePointer() TUniqueRef TempB(PtrB); TUniqueRef TempC(PtrC, FDeleter()); - always_check(TempA == PtrA); + always_check(TempA != nullptr); always_check(TempC != TempB); - always_check((TempA <=> PtrA) == strong_ordering::equal); + always_check((TempA <=> nullptr) == strong_ordering::greater); always_check((TempC <=> TempB) != strong_ordering::equal); int32 TempNum; @@ -344,9 +344,9 @@ void TestUniquePointer() TUniqueRef TempB(PtrB); TUniqueRef TempC(PtrC, FArrayDeleter()); - always_check(TempA == PtrA); + always_check(TempA != nullptr); always_check(TempC != TempB); - always_check((TempA <=> PtrA) == strong_ordering::equal); + always_check((TempA <=> nullptr) == strong_ordering::greater); always_check((TempC <=> TempB) != strong_ordering::equal); int32 TempNum; @@ -397,9 +397,9 @@ void TestUniquePointer() TUniquePtr TempB(PtrB); TUniquePtr TempC(PtrC, FDeleter()); - always_check(TempA == PtrA); + always_check(TempA != nullptr); always_check(TempC != TempB); - always_check((TempA <=> PtrA) == strong_ordering::equal); + always_check((TempA <=> nullptr) == strong_ordering::greater); always_check((TempC <=> TempB) != strong_ordering::equal); int32 TempNum; @@ -462,9 +462,9 @@ void TestUniquePointer() TUniquePtr TempB(PtrB); TUniquePtr TempC(PtrC, FArrayDeleter()); - always_check(TempA == PtrA); + always_check(TempA != nullptr); always_check(TempC != TempB); - always_check((TempA <=> PtrA) == strong_ordering::equal); + always_check((TempA <=> nullptr) == strong_ordering::greater); always_check((TempC <=> TempB) != strong_ordering::equal); int32 TempNum; @@ -540,9 +540,9 @@ void TestSharedPointer() TSharedRef TempB(PtrB, FDeleter()); TSharedRef TempC(PtrC, FDeleter()); - always_check(TempA == PtrA); + always_check(TempA != nullptr); always_check(TempC != TempB); - always_check((TempA <=> PtrA) == strong_ordering::equal); + always_check((TempA <=> nullptr) == strong_ordering::greater); always_check((TempC <=> TempB) != strong_ordering::equal); int32 TempNum; @@ -587,9 +587,9 @@ void TestSharedPointer() TSharedRef TempB(PtrB, FArrayDeleter()); TSharedRef TempC(PtrC, FArrayDeleter()); - always_check(TempA == PtrA); + always_check(TempA != nullptr); always_check(TempC != TempB); - always_check((TempA <=> PtrA) == strong_ordering::equal); + always_check((TempA <=> nullptr) == strong_ordering::greater); always_check((TempC <=> TempB) != strong_ordering::equal); int32 TempNum; @@ -628,9 +628,9 @@ void TestSharedPointer() TSharedPtr TempB(PtrB, FDeleter()); TSharedPtr TempC(PtrC, FDeleter()); - always_check(TempA == PtrA); + always_check(TempA != nullptr); always_check(TempC != TempB); - always_check((TempA <=> PtrA) == strong_ordering::equal); + always_check((TempA <=> nullptr) == strong_ordering::greater); always_check((TempC <=> TempB) != strong_ordering::equal); int32 TempNum; @@ -684,9 +684,9 @@ void TestSharedPointer() TSharedPtr TempB(PtrB, FArrayDeleter()); TSharedPtr TempC(PtrC, FArrayDeleter()); - always_check(TempA == PtrA); + always_check(TempA != nullptr); always_check(TempC != TempB); - always_check((TempA <=> PtrA) == strong_ordering::equal); + always_check((TempA <=> nullptr) == strong_ordering::greater); always_check((TempC <=> TempB) != strong_ordering::equal); int32 TempNum; diff --git a/Redcraft.Utility/Source/Public/Memory/SharedPointer.h b/Redcraft.Utility/Source/Public/Memory/SharedPointer.h index a337533..2374f9a 100644 --- a/Redcraft.Utility/Source/Public/Memory/SharedPointer.h +++ b/Redcraft.Utility/Source/Public/Memory/SharedPointer.h @@ -636,16 +636,18 @@ public: FORCEINLINE TSharedRef& operator=(TSharedRef&& InValue) { return Helper::MoveSharedReference(*this, MoveTemp(InValue)); } /** Compares the pointer values of two TSharedRef. */ - NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() == RHS.Get(); } + template requires (CEqualityComparable*>) + NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() == RHS.Get(); } /** Compares the pointer values of two TSharedRef. */ - NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() <=> RHS.Get(); } + template requires (CThreeWayComparable*>) + NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() <=> RHS.Get(); } - /** Compares the pointer values with a raw pointer. */ - NODISCARD FORCEINLINE constexpr bool operator==(T* InPtr) const& { return Get() == InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; } - /** Compares the pointer values with a raw pointer. */ - NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(T* InPtr) const& { return Get() <=> InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast(nullptr); } /** TSharedRef cannot be initialized by nullptr. */ void Reset(nullptr_t) = delete; @@ -852,18 +854,18 @@ public: FORCEINLINE TSharedRef& operator=(TSharedRef&& InValue) { return Helper::MoveSharedReference(*this, MoveTemp(InValue)); } /** Compares the pointer values of two TSharedRef. */ - NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() == RHS.Get(); } + template requires (CEqualityComparable*>) + NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() == RHS.Get(); } /** Compares the pointer values of two TSharedRef. */ - NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() <=> RHS.Get(); } + template requires (CThreeWayComparable*>) + NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedRef& LHS, const TSharedRef& RHS) { return LHS.Get() <=> RHS.Get(); } - /** Compares the pointer values with a raw pointer. */ - template requires (CNullPointer || (CPointer && CConvertibleTo(*)[], T(*)[]>)) - NODISCARD FORCEINLINE constexpr bool operator==(U InPtr) const& { return Get() == InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; } - /** Compares the pointer values with a raw pointer. */ - template requires (CNullPointer || (CPointer && CConvertibleTo(*)[], T(*)[]>)) - NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(U InPtr) const& { return Get() <=> InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast(nullptr); } /** TSharedRef cannot be initialized by nullptr. */ void Reset(nullptr_t) = delete; @@ -1094,16 +1096,18 @@ public: FORCEINLINE TSharedPtr& operator=(nullptr_t) { Reset(); return *this; } /** Compares the pointer values of two TSharedPtr. */ - NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedPtr& LHS, const TSharedPtr& RHS) { return LHS.Get() == RHS.Get(); } + template requires (CEqualityComparable*>) + NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedPtr& LHS, const TSharedPtr& RHS) { return LHS.Get() == RHS.Get(); } /** Compares the pointer values of two TSharedPtr. */ - NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedPtr& LHS, const TSharedPtr& RHS) { return LHS.Get() <=> RHS.Get(); } + template requires (CThreeWayComparable*>) + NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedPtr& LHS, const TSharedPtr& RHS) { return LHS.Get() <=> RHS.Get(); } - /** Compares the pointer values with a raw pointer. */ - NODISCARD FORCEINLINE constexpr bool operator==(T* InPtr) const& { return Get() == InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; } - /** Compares the pointer values with a raw pointer. */ - NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(T* InPtr) const& { return Get() <=> InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast(nullptr); } /** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */ FORCEINLINE TSharedRef ToSharedRef() const& @@ -1360,18 +1364,18 @@ public: FORCEINLINE TSharedPtr& operator=(nullptr_t) { Reset(); return *this; } /** Compares the pointer values of two TSharedPtr. */ - NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedPtr& LHS, const TSharedPtr& RHS) { return LHS.Get() == RHS.Get(); } + template requires (CEqualityComparable*>) + NODISCARD friend FORCEINLINE constexpr bool operator==(const TSharedPtr& LHS, const TSharedPtr& RHS) { return LHS.Get() == RHS.Get(); } /** Compares the pointer values of two TSharedPtr. */ - NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedPtr& LHS, const TSharedPtr& RHS) { return LHS.Get() <=> RHS.Get(); } + template requires (CThreeWayComparable*>) + NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TSharedPtr& LHS, const TSharedPtr& RHS) { return LHS.Get() <=> RHS.Get(); } - /** Compares the pointer values with a raw pointer. */ - template requires (CNullPointer || (CPointer && CConvertibleTo(*)[], T(*)[]>)) - NODISCARD FORCEINLINE constexpr bool operator==(U InPtr) const& { return Get() == InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; } - /** Compares the pointer values with a raw pointer. */ - template requires (CNullPointer || (CPointer && CConvertibleTo(*)[], T(*)[]>)) - NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(U InPtr) const& { return Get() <=> InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast(nullptr); } /** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */ FORCEINLINE TSharedRef ToSharedRef() const& diff --git a/Redcraft.Utility/Source/Public/Memory/UniquePointer.h b/Redcraft.Utility/Source/Public/Memory/UniquePointer.h index d7c137e..f1d1cbd 100644 --- a/Redcraft.Utility/Source/Public/Memory/UniquePointer.h +++ b/Redcraft.Utility/Source/Public/Memory/UniquePointer.h @@ -177,16 +177,18 @@ public: FORCEINLINE constexpr ~TUniqueRef() { Invoke(GetDeleter(), Get()); } /** Compares the pointer values of two TUniqueRef. */ - NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniqueRef& LHS, const TUniqueRef& RHS) { return LHS.Get() == RHS.Get(); } + template requires (CEqualityComparable*>) + NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniqueRef& LHS, const TUniqueRef& RHS) { return LHS.Get() == RHS.Get(); } /** Compares the pointer values of two TUniqueRef. */ - NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniqueRef& LHS, const TUniqueRef& RHS) { return LHS.Get() <=> RHS.Get(); } + template requires (CThreeWayComparable*>) + NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniqueRef& LHS, const TUniqueRef& RHS) { return LHS.Get() <=> RHS.Get(); } - /** Compares the pointer values with a raw pointer. */ - NODISCARD FORCEINLINE constexpr bool operator==(T* InPtr) const& { return Get() == InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; } - /** Compares the pointer values with a raw pointer. */ - NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(T* InPtr) const& { return Get() <=> InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast(nullptr); } /** TUniqueRef cannot be reset to nullptr. */ void Reset(nullptr_t) = delete; @@ -297,18 +299,18 @@ public: FORCEINLINE constexpr ~TUniqueRef() { Invoke(GetDeleter(), Get()); } /** Compares the pointer values of two TUniqueRef. */ - NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniqueRef& LHS, const TUniqueRef& RHS) { return LHS.Get() == RHS.Get(); } + template requires (CEqualityComparable*>) + NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniqueRef& LHS, const TUniqueRef& RHS) { return LHS.Get() == RHS.Get(); } /** Compares the pointer values of two TUniqueRef. */ - NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniqueRef& LHS, const TUniqueRef& RHS) { return LHS.Get() <=> RHS.Get(); } + template requires (CThreeWayComparable*>) + NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniqueRef& LHS, const TUniqueRef& RHS) { return LHS.Get() <=> RHS.Get(); } - /** Compares the pointer values with a raw pointer. */ - template requires (CNullPointer || (CPointer && CConvertibleTo(*)[], T(*)[]>)) - NODISCARD FORCEINLINE constexpr bool operator==(U InPtr) const& { return Get() == InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; } - /** Compares the pointer values with a raw pointer. */ - template requires (CNullPointer || (CPointer && CConvertibleTo(*)[], T(*)[]>)) - NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(U InPtr) const& { return Get() <=> InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast(nullptr); } /** TUniqueRef cannot be reset to nullptr. */ void Reset(nullptr_t) = delete; @@ -440,16 +442,18 @@ public: FORCEINLINE constexpr TUniquePtr& operator=(nullptr_t) { Reset(); return *this; } /** Compares the pointer values of two TUniquePtr. */ - NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniquePtr& LHS, const TUniquePtr& RHS) { return LHS.Get() == RHS.Get(); } + template requires (CEqualityComparable*>) + NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniquePtr& LHS, const TUniquePtr& RHS) { return LHS.Get() == RHS.Get(); } /** Compares the pointer values of two TUniquePtr. */ - NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniquePtr& LHS, const TUniquePtr& RHS) { return LHS.Get() <=> RHS.Get(); } + template requires (CThreeWayComparable*>) + NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniquePtr& LHS, const TUniquePtr& RHS) { return LHS.Get() <=> RHS.Get(); } - /** Compares the pointer values with a raw pointer. */ - NODISCARD FORCEINLINE constexpr bool operator==(T* InPtr) const& { return Get() == InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; } - /** Compares the pointer values with a raw pointer. */ - NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(T* InPtr) const& { return Get() <=> InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast(nullptr); } /** Returns a pointer to the managed object and releases the ownership. */ NODISCARD FORCEINLINE constexpr T* Release() { return Exchange(Storage.GetPointer(), nullptr); } @@ -577,18 +581,18 @@ public: FORCEINLINE constexpr TUniquePtr& operator=(nullptr_t) { Reset(); return *this; } /** Compares the pointer values of two TUniquePtr. */ - NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniquePtr& LHS, const TUniquePtr& RHS) { return LHS.Get() == RHS.Get(); } + template requires (CEqualityComparable*>) + NODISCARD friend FORCEINLINE constexpr bool operator==(const TUniquePtr& LHS, const TUniquePtr& RHS) { return LHS.Get() == RHS.Get(); } /** Compares the pointer values of two TUniquePtr. */ - NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniquePtr& LHS, const TUniquePtr& RHS) { return LHS.Get() <=> RHS.Get(); } + template requires (CThreeWayComparable*>) + NODISCARD friend FORCEINLINE constexpr strong_ordering operator<=>(const TUniquePtr& LHS, const TUniquePtr& RHS) { return LHS.Get() <=> RHS.Get(); } - /** Compares the pointer values with a raw pointer. */ - template requires (CNullPointer || (CPointer && CConvertibleTo(*)[], T(*)[]>)) - NODISCARD FORCEINLINE constexpr bool operator==(U InPtr) const& { return Get() == InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& { return Get() == nullptr; } - /** Compares the pointer values with a raw pointer. */ - template requires (CNullPointer || (CPointer && CConvertibleTo(*)[], T(*)[]>)) - NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(U InPtr) const& { return Get() <=> InPtr; } + /** Compares the pointer values with nullptr. */ + NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(nullptr_t) const& { return Get() <=> static_cast(nullptr); } /** Returns a pointer to the managed array and releases the ownership. */ NODISCARD FORCEINLINE constexpr T* Release() { return Exchange(Storage.GetPointer(), nullptr); }