From f690b693386ef44754fa4528f3c565d563ad9468 Mon Sep 17 00:00:00 2001 From: Shauren Date: Wed, 13 Mar 2024 17:04:26 +0100 Subject: Core/Utils: unique_trackable_ptr improvements * Added comparison operators * Added type casting helper functions --- src/common/Utilities/UniqueTrackablePtr.h | 252 ++++++++++++++++++++++++++++-- 1 file changed, 236 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/common/Utilities/UniqueTrackablePtr.h b/src/common/Utilities/UniqueTrackablePtr.h index b315bbd6437..7b1d9c236db 100644 --- a/src/common/Utilities/UniqueTrackablePtr.h +++ b/src/common/Utilities/UniqueTrackablePtr.h @@ -18,12 +18,11 @@ #ifndef TRINITYCORE_UNIQUE_TRACKABLE_PTR_H #define TRINITYCORE_UNIQUE_TRACKABLE_PTR_H -#include "Define.h" #include namespace Trinity { -template > +template class unique_trackable_ptr; template @@ -36,27 +35,32 @@ class unique_strong_ref_ptr; * \brief Specialized variant of std::shared_ptr that enforces unique ownership and/or std::unique_ptr with std::weak_ptr capabilities * Implementation has the same overhead as a std::shared_ptr, that is, a separate allocation for control block that holds use counters * \tparam T Type of held object - * \tparam Deleter Object deleter (defaults to std::default_delete) */ -template +template class unique_trackable_ptr { public: using element_type = T; using pointer = T*; - using deleter_type = Deleter; - unique_trackable_ptr() : _ptr(nullptr, deleter_type()) { } + unique_trackable_ptr() : _ptr() { } - explicit unique_trackable_ptr(pointer ptr) : _ptr(ptr, deleter_type()) { } + explicit unique_trackable_ptr(pointer ptr) + : _ptr(ptr) { } - explicit unique_trackable_ptr(pointer ptr, deleter_type deleter) : _ptr(ptr, std::move(deleter)) { } + template , std::is_invocable>, int> = 0> + explicit unique_trackable_ptr(pointer ptr, Deleter deleter) + : _ptr(ptr, std::move(deleter)) { } unique_trackable_ptr(unique_trackable_ptr const&) = delete; unique_trackable_ptr(unique_trackable_ptr&& other) noexcept : _ptr(std::move(other._ptr)) { } + template , int> = 0> + unique_trackable_ptr(unique_trackable_ptr&& other) noexcept + : _ptr(std::move(other)._ptr) { } + unique_trackable_ptr& operator=(unique_trackable_ptr const&) = delete; unique_trackable_ptr& operator=(unique_trackable_ptr&& other) noexcept @@ -65,6 +69,13 @@ public: return *this; } + template , int> = 0> + unique_trackable_ptr& operator=(unique_trackable_ptr&& other) noexcept + { + _ptr = std::move(other)._ptr; + return *this; + } + ~unique_trackable_ptr() = default; unique_trackable_ptr& operator=(std::nullptr_t) @@ -99,12 +110,26 @@ public: return static_cast(_ptr); } - void reset(pointer ptr = nullptr, deleter_type deleter = {}) + void reset() + { + _ptr.reset(); + } + + void reset(pointer ptr) + { + _ptr.reset(ptr); + } + + template , std::is_invocable>, int> = 0> + void reset(pointer ptr, Deleter deleter) { _ptr.reset(ptr, std::move(deleter)); } private: + template + friend class unique_trackable_ptr; + template friend class unique_weak_ptr; @@ -139,22 +164,36 @@ public: unique_weak_ptr() = default; - template - unique_weak_ptr(unique_trackable_ptr const& trackable) : _ptr(trackable._ptr) - { - } + unique_weak_ptr(unique_trackable_ptr const& trackable) + : _ptr(trackable._ptr) { } unique_weak_ptr(unique_weak_ptr const& other) = default; + + template , int> = 0> + unique_weak_ptr(unique_weak_ptr const& other) noexcept + : _ptr(other._ptr) { } + unique_weak_ptr(unique_weak_ptr&& other) noexcept = default; - template - unique_weak_ptr& operator=(unique_trackable_ptr const& trackable) + template , int> = 0> + unique_weak_ptr(unique_weak_ptr&& other) noexcept + : _ptr(std::move(other)._ptr) { } + + unique_weak_ptr& operator=(unique_trackable_ptr const& trackable) { _ptr = trackable._ptr; return *this; } unique_weak_ptr& operator=(unique_weak_ptr const& other) = default; + + template , int> = 0> + unique_weak_ptr& operator=(unique_weak_ptr&& other) + { + _ptr = std::move(other)._ptr; + return *this; + } + unique_weak_ptr& operator=(unique_weak_ptr&& other) noexcept = default; ~unique_weak_ptr() = default; @@ -176,6 +215,24 @@ public: } private: + template + friend class unique_weak_ptr; + + template + friend class unique_strong_ref_ptr; + + template + friend unique_weak_ptr static_pointer_cast(unique_weak_ptr const& other); + + template + friend unique_weak_ptr const_pointer_cast(unique_weak_ptr const& other); + + template + friend unique_weak_ptr reinterpret_pointer_cast(unique_weak_ptr const& other); + + template + friend unique_weak_ptr dynamic_pointer_cast(unique_weak_ptr const& other); + std::weak_ptr _ptr; }; @@ -219,17 +276,72 @@ public: return static_cast(_ptr); } - friend std::strong_ordering operator<=>(unique_strong_ref_ptr const&, unique_strong_ref_ptr const&) = default; + operator unique_weak_ptr() const + { + unique_weak_ptr weak; + weak._ptr = _ptr; + return weak; + } private: template friend class unique_weak_ptr; + template + friend unique_strong_ref_ptr static_pointer_cast(unique_strong_ref_ptr const& other); + + template + friend unique_strong_ref_ptr static_pointer_cast(unique_strong_ref_ptr&& other); + + template + friend unique_strong_ref_ptr const_pointer_cast(unique_strong_ref_ptr const& other); + + template + friend unique_strong_ref_ptr const_pointer_cast(unique_strong_ref_ptr&& other); + + template + friend unique_strong_ref_ptr reinterpret_pointer_cast(unique_strong_ref_ptr const& other); + + template + friend unique_strong_ref_ptr reinterpret_pointer_cast(unique_strong_ref_ptr&& other); + + template + friend unique_strong_ref_ptr dynamic_pointer_cast(unique_strong_ref_ptr const& other); + + template + friend unique_strong_ref_ptr dynamic_pointer_cast(unique_strong_ref_ptr&& other); + unique_strong_ref_ptr(std::shared_ptr ptr) : _ptr(std::move(ptr)) { } std::shared_ptr _ptr; }; +// unique_trackable_ptr funcions + +template +bool operator==(unique_trackable_ptr const& left, unique_trackable_ptr const& right) +{ + return left.get() == right.get(); +} + +template +std::strong_ordering operator<=>(unique_trackable_ptr const& left, unique_trackable_ptr const& right) +{ + return left.get() <=> right.get(); +} + +template +bool operator==(unique_trackable_ptr const& left, std::nullptr_t) +{ + return left.get() == nullptr; +} + +template +std::strong_ordering operator<=>(unique_trackable_ptr const& left, std::nullptr_t) +{ + return left.get() <=> nullptr; +} + template std::enable_if_t, unique_trackable_ptr> make_unique_trackable(Args&&... args) { @@ -269,6 +381,114 @@ std::enable_if_t, unique_trackable_ptr> make_uniqu ptr._ptr = std::make_shared(val); return ptr; } + +// unique_weak_ptr funcions + +template +unique_weak_ptr static_pointer_cast(unique_weak_ptr const& other) +{ + unique_weak_ptr to; + to._ptr = std::static_pointer_cast(other._ptr.lock()); + return to; +} + +template +unique_weak_ptr const_pointer_cast(unique_weak_ptr const& other) +{ + unique_weak_ptr to; + to._ptr = std::const_pointer_cast(other._ptr.lock()); + return to; +} + +template +unique_weak_ptr reinterpret_pointer_cast(unique_weak_ptr const& other) +{ + unique_weak_ptr to; + to._ptr = std::reinterpret_pointer_cast(other._ptr.lock()); + return to; +} + +template +unique_weak_ptr dynamic_pointer_cast(unique_weak_ptr const& other) +{ + unique_weak_ptr to; + to._ptr = std::dynamic_pointer_cast(other._ptr.lock()); + return to; +} + +// unique_strong_ref_ptr funcions + +template +bool operator==(unique_strong_ref_ptr const& left, unique_strong_ref_ptr const& right) +{ + return left.get() == right.get(); +} + +template +std::strong_ordering operator<=>(unique_strong_ref_ptr const& left, unique_strong_ref_ptr const& right) +{ + return left.get() <=> right.get(); +} + +template +bool operator==(unique_strong_ref_ptr const& left, std::nullptr_t) +{ + return left.get() == nullptr; +} + +template +std::strong_ordering operator<=>(unique_strong_ref_ptr const& left, std::nullptr_t) +{ + return left.get() <=> nullptr; +} + +template +unique_strong_ref_ptr static_pointer_cast(unique_strong_ref_ptr const& other) +{ + return unique_strong_ref_ptr(std::static_pointer_cast(other._ptr)); +} + +template +unique_strong_ref_ptr static_pointer_cast(unique_strong_ref_ptr&& other) +{ + return unique_strong_ref_ptr(std::static_pointer_cast(std::move(other._ptr))); +} + +template +unique_strong_ref_ptr const_pointer_cast(unique_strong_ref_ptr const& other) +{ + return unique_strong_ref_ptr(std::const_pointer_cast(other._ptr)); +} + +template +unique_strong_ref_ptr const_pointer_cast(unique_strong_ref_ptr&& other) +{ + return unique_strong_ref_ptr(std::const_pointer_cast(std::move(other._ptr))); +} + +template +unique_strong_ref_ptr reinterpret_pointer_cast(unique_strong_ref_ptr const& other) +{ + return unique_strong_ref_ptr(std::reinterpret_pointer_cast(other._ptr)); +} + +template +unique_strong_ref_ptr reinterpret_pointer_cast(unique_strong_ref_ptr&& other) +{ + return unique_strong_ref_ptr(std::reinterpret_pointer_cast(std::move(other._ptr))); +} + +template +unique_strong_ref_ptr dynamic_pointer_cast(unique_strong_ref_ptr const& other) +{ + return unique_strong_ref_ptr(std::dynamic_pointer_cast(other._ptr)); +} + +template +unique_strong_ref_ptr dynamic_pointer_cast(unique_strong_ref_ptr&& other) +{ + return unique_strong_ref_ptr(std::dynamic_pointer_cast(std::move(other._ptr))); +} } #endif // TRINITYCORE_UNIQUE_TRACKABLE_PTR_H -- cgit v1.2.3