diff --git a/common/ptr.h b/common/ptr.h index c4720cc1fe0..6911fd983a9 100644 --- a/common/ptr.h +++ b/common/ptr.h @@ -112,65 +112,6 @@ private: DL _deleter; }; -/** - * A base class for both SharedPtr and WeakPtr. - * - * This base class encapsulates the logic for the reference counter - * used by both. - */ -template -class BasePtr : public SafeBool > { -#if !defined(__GNUC__) || GCC_ATLEAST(3, 0) - template friend class BasePtr; -#endif -public: - typedef T ValueType; - typedef T *PointerType; - typedef T &ReferenceType; - - BasePtr() : _tracker(nullptr), _pointer(nullptr) { - } - - explicit BasePtr(std::nullptr_t) : _tracker(nullptr), _pointer(nullptr) { - } - - template - explicit BasePtr(T2 *p) : _tracker(p ? (new BasePtrTrackerImpl(p)) : nullptr), _pointer(p) { - } - - template - BasePtr(T2 *p, DL d) : _tracker(p ? new BasePtrTrackerDeletionImpl(p, d) : nullptr), _pointer(p) { - } - - BasePtr(const BasePtr &r) : _tracker(r._tracker), _pointer(r._pointer) { - } - - template - BasePtr(const BasePtr &r) : _tracker(r._tracker), _pointer(r._pointer) { - } - - ~BasePtr() { - } - - /** - * Implicit conversion operator to bool for convenience, to make - * checks like "if (sharedPtr) ..." possible. - */ - bool operator_bool() const { - return _pointer != nullptr; - } - -protected: - template - void assign(const BasePtr &r) { - _tracker = r._tracker; - _pointer = r._pointer; - } - - BasePtrTrackerInternal *_tracker; - T *_pointer; -}; - template class WeakPtr; @@ -216,75 +157,69 @@ class WeakPtr; * a plain pointer is only possible via SharedPtr::get. */ template -class SharedPtr : public BasePtr { +class SharedPtr : public SafeBool > { + template + friend class WeakPtr; + template + friend class SharedPtr; public: // Invariant: If _tracker is non-null, then the object is alive typedef T *PointerType; typedef T &ReferenceType; + typedef BasePtrTrackerInternal::RefValue RefValue; - SharedPtr() : BasePtr() { + SharedPtr() : _pointer(nullptr), _tracker(nullptr) { } - SharedPtr(std::nullptr_t) : BasePtr() { + SharedPtr(std::nullptr_t) : _pointer(nullptr), _tracker(nullptr) { } ~SharedPtr() { - if (this->_tracker) - this->_tracker->decStrong(); + if (_tracker) + _tracker->decStrong(); } template - explicit SharedPtr(T2 *p) : BasePtr(p) { + explicit SharedPtr(T2 *p) : _pointer(p), _tracker(p ? (new BasePtrTrackerImpl(p)) : nullptr) { } template - SharedPtr(T2 *p, DL d) : BasePtr(p, d) { + SharedPtr(T2 *p, DL d) : _pointer(p), _tracker(p ? (new BasePtrTrackerDeletionImpl(p, d)) : nullptr) { } - SharedPtr(const SharedPtr &r) : BasePtr(r) { - if (this->_tracker) - this->_tracker->incStrong(); - } - - SharedPtr(const WeakPtr &r) { - reset(r); + SharedPtr(const SharedPtr &r) : _pointer(r._pointer), _tracker(r._tracker) { + if (_tracker) + _tracker->incStrong(); } template - SharedPtr(const SharedPtr &r) : BasePtr(r) { - if (this->_tracker) - this->_tracker->incStrong(); + SharedPtr(const SharedPtr &r) : _pointer(r._pointer), _tracker(r._tracker) { + if (_tracker) + _tracker->incStrong(); + } + + template + explicit SharedPtr(const WeakPtr &r) : _pointer(nullptr), _tracker(nullptr) { + if (r._tracker && r._tracker->isAlive()) { + _pointer = r._pointer; + _tracker = r._tracker; + _tracker->incStrong(); + } } SharedPtr &operator=(const SharedPtr &r) { - BasePtrTrackerInternal *oldTracker = this->_tracker; - - this->assign(r); - - if (this->_tracker) - this->_tracker->incStrong(); - if (oldTracker) - oldTracker->decStrong(); - + reset(r); return *this; } template SharedPtr &operator=(const SharedPtr &r) { - BasePtrTrackerInternal *oldTracker = this->_tracker; - - this->assign(r); - - if (this->_tracker) - this->_tracker->incStrong(); - if (oldTracker) - oldTracker->decStrong(); - + reset(r); return *this; } - T &operator*() const { assert(this->_pointer); return *this->_pointer; } - T *operator->() const { assert(this->_pointer); return this->_pointer; } + T &operator*() const { assert(_pointer); return *_pointer; } + T *operator->() const { assert(_pointer); return _pointer; } /** * Returns the plain pointer value. Be sure you know what you @@ -292,16 +227,33 @@ public: * * @return the pointer the SharedPtr object manages */ - PointerType get() const { return this->_pointer; } + PointerType get() const { return _pointer; } template bool operator==(const SharedPtr &r) const { - return this->_pointer == r.get(); + return _pointer == r.get(); } template bool operator!=(const SharedPtr &r) const { - return this->_pointer != r.get(); + return _pointer != r.get(); + } + + /** + * Implicit conversion operator to bool for convenience, to make + * checks like "if (sharedPtr) ..." possible. + */ + bool operator_bool() const { + return _pointer != nullptr; + } + + /** + * Returns the number of strong references to the object. + */ + int refCount() const { + if (_tracker == nullptr) + return 0; + return _tracker->getStrongCount(); } /** @@ -310,52 +262,49 @@ public: * debugging purposes. */ bool unique() const { - return this->_tracker != nullptr && this->_tracker->getStrongCount() == 1; + return refCount() == 1; } /** * Resets the object to a NULL pointer. */ void reset() { - if (this->_tracker) - this->_tracker->decStrong(); - this->_tracker = nullptr; - this->_pointer = nullptr; + if (_tracker) + _tracker->decStrong(); + _tracker = nullptr; + _pointer = nullptr; } /** - * Resets the object to the specified pointer + * Resets the object to the specified shared pointer */ - void reset(const BasePtr &r) { - BasePtrTrackerInternal *oldTracker = this->_tracker; + template + void reset(const SharedPtr &r) { + BasePtrTrackerInternal *oldTracker = _tracker; - this->assign(r); - - if (this->_tracker && this->_tracker->isAlive()) { - this->_tracker->incStrong(); - } else { - this->_tracker = nullptr; - this->_pointer = nullptr; - } + _pointer = r._pointer; + _tracker = r._tracker; + if (_tracker) + _tracker->incStrong(); if (oldTracker) oldTracker->decStrong(); } /** - * Resets the object to the specified pointer + * Resets the object to the specified weak pointer */ template - void reset(const BasePtr &r) { - BasePtrTrackerInternal *oldTracker = this->_tracker; + void reset(const WeakPtr &r) { + BasePtrTrackerInternal *oldTracker = _tracker; - this->assign(r); - - if (this->_tracker && this->_tracker->isAlive()) { - this->_tracker->incStrong(); + if (r._tracker && r._tracker->isAlive()) { + _tracker = r._tracker; + _pointer = r._pointer; + _tracker->incStrong(); } else { - this->_tracker = nullptr; - this->_pointer = nullptr; + _tracker = nullptr; + _pointer = nullptr; } if (oldTracker) @@ -366,46 +315,57 @@ public: * Resets the object to the specified pointer */ void reset(T *ptr) { - if (this->_tracker) - this->_tracker->decStrong(); + if (_tracker) + _tracker->decStrong(); - this->_pointer = ptr; - this->_tracker = new BasePtrTrackerImpl(ptr); + _pointer = ptr; + _tracker = new BasePtrTrackerImpl(ptr); } + +private: + T *_pointer; + BasePtrTrackerInternal *_tracker; }; + + /** * Implements a smart pointer that holds a non-owning ("weak") refrence to * a pointer. It needs to be converted to a SharedPtr to access it. */ template -class WeakPtr : public BasePtr { +class WeakPtr : public SafeBool > { + template + friend class WeakPtr; + template + friend class SharedPtr; public: - WeakPtr() : BasePtr() { + WeakPtr() : _pointer(nullptr), _tracker(nullptr) { } - WeakPtr(std::nullptr_t) : BasePtr() { + WeakPtr(std::nullptr_t) : _pointer(nullptr), _tracker(nullptr) { } - WeakPtr(const WeakPtr &r) : BasePtr(r) { - if (this->_tracker) - this->_tracker->incWeak(); - } - - WeakPtr(const BasePtr &r) : BasePtr(r) { - if (this->_tracker) - this->_tracker->incWeak(); + WeakPtr(const WeakPtr &r) : _pointer(r._pointer), _tracker(r._tracker) { + if (_tracker) + _tracker->incWeak(); } ~WeakPtr() { - if (this->_tracker) - this->_tracker->decWeak(); + if (_tracker) + _tracker->decWeak(); } template - WeakPtr(const BasePtr &r) : BasePtr(r) { - if (this->_tracker) - this->_tracker->incWeak(); + WeakPtr(const WeakPtr &r) : _pointer(r._pointer), _tracker(r._tracker) { + if (_tracker) + _tracker->incWeak(); + } + + template + WeakPtr(const SharedPtr &r) : _pointer(r._pointer), _tracker(r._tracker) { + if (_tracker) + _tracker->incWeak(); } /** @@ -417,17 +377,27 @@ public: /** * Implicit conversion operator to bool for convenience, to make - * checks like "if (sharedPtr) ..." possible. + * checks like "if (weakPtr) ..." possible. This only checks if the + * weak pointer contains a pointer, not that the pointer is live. */ bool operator_bool() const { - return this->_pointer != nullptr; + return _pointer != nullptr; + } + + /** + * Returns the number of strong references to the object. + */ + int refCount() const { + if (_tracker == nullptr) + return 0; + return _tracker->getStrongCount(); } /** * Returns whether the referenced object isn't valid */ bool expired() const { - return this->_tracker == nullptr || this->_tracker->getStrongCount() == 0; + return _tracker == nullptr || _tracker->getStrongCount() == 0; } WeakPtr &operator=(const WeakPtr &r) { @@ -441,13 +411,8 @@ public: return *this; } - WeakPtr &operator=(const BasePtr &r) { - reset(r); - return *this; - } - template - WeakPtr &operator=(const BasePtr &r) { + WeakPtr &operator=(const SharedPtr &r) { reset(r); return *this; } @@ -456,40 +421,47 @@ public: * Resets the object to a NULL pointer. */ void reset() { - if (this->_tracker) - this->_tracker->decWeak(); - this->_tracker = nullptr; - this->_pointer = nullptr; + if (_tracker) + _tracker->decWeak(); + _tracker = nullptr; + _pointer = nullptr; } /** - * Resets the object to the specified pointer - */ - void reset(const BasePtr &r) { - BasePtrTrackerInternal *oldTracker = this->_tracker; - - this->assign(r); - - if (this->_tracker) - this->_tracker->incWeak(); - if (oldTracker) - oldTracker->decWeak(); - } - - /** - * Resets the object to the specified pointer + * Resets the object to the specified shared pointer */ template - void reset(const BasePtr &r) { - BasePtrTrackerInternal *oldTracker = this->_tracker; + void reset(const SharedPtr &r) { + BasePtrTrackerInternal *oldTracker = _tracker; - this->assign(r); + _pointer = r._pointer; + _tracker = r._tracker; - if (this->_tracker) - this->_tracker->incWeak(); + if (_tracker) + _tracker->incWeak(); if (oldTracker) oldTracker->decWeak(); } + + /** + * Resets the object to the specified weak pointer + */ + template + void reset(const WeakPtr &r) { + BasePtrTrackerInternal *oldTracker = _tracker; + + _pointer = r._pointer; + _tracker = r._tracker; + + if (_tracker) + _tracker->incWeak(); + if (oldTracker) + oldTracker->decWeak(); + } + +private: + T *_pointer; + BasePtrTrackerInternal *_tracker; }; template diff --git a/devtools/create_project/scripts/scummvm.natvis b/devtools/create_project/scripts/scummvm.natvis index 73fab76710c..63b94bff620 100644 --- a/devtools/create_project/scripts/scummvm.natvis +++ b/devtools/create_project/scripts/scummvm.natvis @@ -130,6 +130,15 @@ + + nullptr + {*_pointer} + + _pointer + _tracker->_strongRefCount + + + nullptr {*_pointer}