diff --git a/Redcraft.Utility/Source/Public/Templates/SharedPointer.h b/Redcraft.Utility/Source/Public/Templates/SharedPointer.h index d4a1bc3..469cc91 100644 --- a/Redcraft.Utility/Source/Public/Templates/SharedPointer.h +++ b/Redcraft.Utility/Source/Public/Templates/SharedPointer.h @@ -465,6 +465,10 @@ private: }; +struct FSharedPtrConstructor { explicit FSharedPtrConstructor() = default; }; + +inline constexpr FSharedPtrConstructor SharedPtrConstructor{ }; + NAMESPACE_PRIVATE_END /** @@ -714,20 +718,16 @@ private: T* Pointer; NAMESPACE_PRIVATE::FSharedController* Controller; - template - FORCEINLINE TSharedRef(const TSharedPtr& InValue, T* InPtr) - : Pointer(InPtr), Controller(InValue.Controller) + FORCEINLINE TSharedRef(NAMESPACE_PRIVATE::FSharedPtrConstructor, const TSharedPtr& InValue) + : Pointer(InValue.Pointer), Controller(InValue.Controller) { Controller->AddSharedReference(); } - template - FORCEINLINE TSharedRef(TSharedPtr&& InValue, T* InPtr) - : Pointer(InPtr), Controller(InValue.Controller) - { - InValue.Pointer = nullptr; - InValue.Controller = nullptr; - } + FORCEINLINE TSharedRef(NAMESPACE_PRIVATE::FSharedPtrConstructor, TSharedPtr&& InValue) + : Pointer(Exchange(InValue.Pointer, nullptr)) + , Controller(Exchange(InValue.Controller, nullptr)) + { } FORCEINLINE TSharedRef(T* InPtr, NAMESPACE_PRIVATE::FSharedController* InController) : Pointer(InPtr), Controller(InController) @@ -936,20 +936,16 @@ private: T* Pointer; NAMESPACE_PRIVATE::FSharedController* Controller; - template - FORCEINLINE TSharedRef(const TSharedPtr& InValue, T* InPtr) - : Pointer(InPtr), Controller(InValue.Controller) + FORCEINLINE TSharedRef(NAMESPACE_PRIVATE::FSharedPtrConstructor, const TSharedPtr& InValue) + : Pointer(InValue.Pointer), Controller(InValue.Controller) { Controller->AddSharedReference(); } - template - FORCEINLINE TSharedRef(TSharedPtr&& InValue, T* InPtr) - : Pointer(InPtr), Controller(InValue.Controller) - { - InValue.Pointer = nullptr; - InValue.Controller = nullptr; - } + FORCEINLINE TSharedRef(NAMESPACE_PRIVATE::FSharedPtrConstructor, TSharedPtr&& InValue) + : Pointer(Exchange(InValue.Pointer, nullptr)) + , Controller(Exchange(InValue.Controller, nullptr)) + { } FORCEINLINE TSharedRef(T* InPtr, NAMESPACE_PRIVATE::FSharedController* InController) : Pointer(InPtr), Controller(InController) @@ -1111,25 +1107,19 @@ public: NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(T* InPtr) const& { return Get() <=> InPtr; } /** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */ - FORCEINLINE TSharedRef ToSharedRef(T* InPtr) const& + FORCEINLINE TSharedRef ToSharedRef() const& { - checkf(IsValid() && InPtr != nullptr, TEXT("TSharedRef cannot be initialized by nullptr.")); - return TSharedRef(*this, InPtr); + checkf(IsValid(), TEXT("TSharedRef cannot be initialized by nullptr.")); + return TSharedRef(NAMESPACE_PRIVATE::SharedPtrConstructor, *this); } /** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */ - FORCEINLINE TSharedRef ToSharedRef(T* InPtr) && + FORCEINLINE TSharedRef ToSharedRef() && { - checkf(IsValid() && InPtr != nullptr, TEXT("TSharedRef cannot be initialized by nullptr.")); - return TSharedRef(MoveTemp(*this), InPtr); + checkf(IsValid(), TEXT("TSharedRef cannot be initialized by nullptr.")); + return TSharedRef(NAMESPACE_PRIVATE::SharedPtrConstructor, *this); } - /** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */ - FORCEINLINE TSharedRef ToSharedRef() const& { return ToSharedRef(Get()); } - - /** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */ - FORCEINLINE TSharedRef ToSharedRef() && { return ToSharedRef(Get()); } - /** Replaces the managed object. */ FORCEINLINE void Reset(T* InPtr = nullptr) { *this = MoveTemp(TSharedPtr(InPtr)); } @@ -1385,27 +1375,19 @@ public: NODISCARD FORCEINLINE constexpr strong_ordering operator<=>(U InPtr) const& { return Get() <=> InPtr; } /** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */ - template requires (CPointer && CConvertibleTo(*)[], T(*)[]>) - FORCEINLINE TSharedRef ToSharedRef(U InPtr) const& + FORCEINLINE TSharedRef ToSharedRef() const& { - checkf(IsValid() && InPtr != nullptr, TEXT("TSharedRef cannot be initialized by nullptr.")); - return TSharedRef(*this, InPtr); + checkf(IsValid(), TEXT("TSharedRef cannot be initialized by nullptr.")); + return TSharedRef(NAMESPACE_PRIVATE::SharedPtrConstructor, *this); } /** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */ - template requires (CPointer&& CConvertibleTo(*)[], T(*)[]>) - FORCEINLINE TSharedRef ToSharedRef(U InPtr)&& + FORCEINLINE TSharedRef ToSharedRef() && { - checkf(IsValid() && InPtr != nullptr, TEXT("TSharedRef cannot be initialized by nullptr.")); - return TSharedRef(MoveTemp(*this), InPtr); + checkf(IsValid(), TEXT("TSharedRef cannot be initialized by nullptr.")); + return TSharedRef(NAMESPACE_PRIVATE::SharedPtrConstructor, *this); } - /** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */ - FORCEINLINE TSharedRef ToSharedRef() const& { return ToSharedRef(Get()); } - - /** Converts a shared pointer to a shared reference. The pointer MUST be valid or an assertion will trigger. */ - FORCEINLINE TSharedRef ToSharedRef() && { return ToSharedRef(Get()); } - /** Replaces the managed array. */ template requires (CNullPointer || (CPointer && CConvertibleTo(*)[], T(*)[]>)) FORCEINLINE void Reset(U InPtr = nullptr) { *this = MoveTemp(TSharedPtr(InPtr)); }