#pragma once #include #include "RefCount.h" #include "SharedPtr.h" class WeakPtrBase { public: ~WeakPtrBase() { Reset(); } void Reset() { if (_refCount) { Reset(); } } protected: RefCount* _refCount; WeakPtrBase() : _refCount(nullptr) { } explicit WeakPtrBase(RefCount* refCount) : _refCount(refCount) { } void ResetIntern(); bool LockIntern() const; }; template class WeakPtr : public WeakPtrBase { template friend class WeakPtr; template friend class EnableSharedFromThis; public: WeakPtr() { } WeakPtr(std::nullptr_t) { } WeakPtr(const WeakPtr& other) : WeakPtrBase(other._refCount), _object(other._object) { if (_refCount) { shared_ptr_increase_ref_count(_refCount->weakRefCount); } } WeakPtr(WeakPtr&& other) : WeakPtrBase(other._refCount), _object(other._object) { other._refCount = nullptr; other._object = nullptr; } template requires std::assignable_from WeakPtr(const SharedPtr& sharedPtr) : WeakPtrBase(sharedPtr._refCount), _object(static_cast(sharedPtr.GetPointer())) { if (_refCount) { shared_ptr_increase_ref_count(_refCount->weakRefCount); } } template explicit WeakPtr(const SharedPtr& sharedPtr) : WeakPtrBase(sharedPtr._refCount), _object(static_cast(sharedPtr.GetPointer())) { if (_refCount) { shared_ptr_increase_ref_count(_refCount->weakRefCount); } } WeakPtr& operator=(const WeakPtr& other) { Reset(); _object = other._object; _refCount = other._refCount; if (_refCount) { shared_ptr_increase_ref_count(_refCount->weakRefCount); } return *this; } template requires std::assignable_from WeakPtr& operator=(const WeakPtr& other) { Reset(); _object = static_cast(static_cast(other._object)); _refCount = other._refCount; if (_refCount) { shared_ptr_increase_ref_count(_refCount->weakRefCount); } return *this; } template requires std::assignable_from WeakPtr& operator=(const SharedPtr& sharedPtr) { Reset(); _object = static_cast(sharedPtr.GetPointer()); _refCount = sharedPtr._refCount; if (_refCount) { shared_ptr_increase_ref_count(_refCount->weakRefCount); } return *this; } WeakPtr& operator=(WeakPtr&& other) { Reset(); _object = other._object; _refCount = other._refCount; other._object = nullptr; other._refCount = nullptr; return *this; } template requires std::assignable_from WeakPtr& operator=(WeakPtr&& other) { Reset(); _object = static_cast(static_cast(other._object)); _refCount = other._refCount; other._object = nullptr; other._refCount = nullptr; return *this; } SharedPtr Lock() const { if (_refCount && LockIntern()) { return SharedPtr(_object, _refCount); } else { return SharedPtr(); } } private: T* _object; WeakPtr(T* object, RefCount* refCount) : WeakPtrBase(refCount), _object(object) { } };