From f65d756bff8d4c5cbc15bd0322a2ae8e6b896a21 Mon Sep 17 00:00:00 2001 From: Ellie Hermaszewska Date: Tue, 29 Oct 2024 14:49:26 +0800 Subject: format * format * Minor test fixes * enable checking cpp format in ci --- source/core/slang-smart-pointer.h | 518 ++++++++++++++++++-------------------- 1 file changed, 250 insertions(+), 268 deletions(-) (limited to 'source/core/slang-smart-pointer.h') diff --git a/source/core/slang-smart-pointer.h b/source/core/slang-smart-pointer.h index a45f7a8ad..46070f0b8 100644 --- a/source/core/slang-smart-pointer.h +++ b/source/core/slang-smart-pointer.h @@ -6,118 +6,124 @@ #include "slang-type-traits.h" #include "slang.h" -#include "slang.h" - namespace Slang { - // Base class for all reference-counted objects - class SLANG_RT_API RefObject +// Base class for all reference-counted objects +class SLANG_RT_API RefObject +{ +private: + UInt referenceCount; + +public: + RefObject() + : referenceCount(0) { - private: - UInt referenceCount; + } - public: - RefObject() - : referenceCount(0) - {} + RefObject(const RefObject&) + : referenceCount(0) + { + } - RefObject(const RefObject &) - : referenceCount(0) - {} + RefObject& operator=(const RefObject&) { return *this; } - RefObject& operator=(const RefObject&) { return *this; } + virtual ~RefObject() {} - virtual ~RefObject() - {} + UInt addReference() { return ++referenceCount; } - UInt addReference() - { - return ++referenceCount; - } + UInt decreaseReference() { return --referenceCount; } - UInt decreaseReference() + UInt releaseReference() + { + SLANG_ASSERT(referenceCount != 0); + if (--referenceCount == 0) { - return --referenceCount; + delete this; + return 0; } + return referenceCount; + } - UInt releaseReference() - { - SLANG_ASSERT(referenceCount != 0); - if(--referenceCount == 0) - { - delete this; - return 0; - } - return referenceCount; - } + bool isUniquelyReferenced() + { + SLANG_ASSERT(referenceCount != 0); + return referenceCount == 1; + } - bool isUniquelyReferenced() - { - SLANG_ASSERT(referenceCount != 0); - return referenceCount == 1; - } + UInt debugGetReferenceCount() { return referenceCount; } +}; - UInt debugGetReferenceCount() - { - return referenceCount; - } - }; +SLANG_FORCE_INLINE void addReference(RefObject* obj) +{ + if (obj) + obj->addReference(); +} - SLANG_FORCE_INLINE void addReference(RefObject* obj) +SLANG_FORCE_INLINE void releaseReference(RefObject* obj) +{ + if (obj) + obj->releaseReference(); +} + +// For straight dynamic cast. +// Use instead of dynamic_cast as it allows for replacement without using Rtti in the future +template +SLANG_FORCE_INLINE T* dynamicCast(RefObject* obj) +{ + return dynamic_cast(obj); +} +template +SLANG_FORCE_INLINE const T* dynamicCast(const RefObject* obj) +{ + return dynamic_cast(obj); +} + +// Like a dynamicCast, but allows a type to implement a specific implementation that is suitable for +// it +template +SLANG_FORCE_INLINE T* as(RefObject* obj) +{ + return dynamicCast(obj); +} +template +SLANG_FORCE_INLINE const T* as(const RefObject* obj) +{ + return dynamicCast(obj); +} + +// "Smart" pointer to a reference-counted object +template +struct SLANG_RT_API RefPtr +{ + RefPtr() + : pointer(nullptr) { - if(obj) obj->addReference(); } - SLANG_FORCE_INLINE void releaseReference(RefObject* obj) + RefPtr(T* p) + : pointer(p) { - if(obj) obj->releaseReference(); + addReference(p); } - // For straight dynamic cast. - // Use instead of dynamic_cast as it allows for replacement without using Rtti in the future - template - SLANG_FORCE_INLINE T* dynamicCast(RefObject* obj) { return dynamic_cast(obj); } - template - SLANG_FORCE_INLINE const T* dynamicCast(const RefObject* obj) { return dynamic_cast(obj); } - - // Like a dynamicCast, but allows a type to implement a specific implementation that is suitable for it - template - SLANG_FORCE_INLINE T* as(RefObject* obj) { return dynamicCast(obj); } - template - SLANG_FORCE_INLINE const T* as(const RefObject* obj) { return dynamicCast(obj); } - - // "Smart" pointer to a reference-counted object - template struct SLANG_RT_API RefPtr + RefPtr(RefPtr const& p) + : pointer(p.pointer) { - RefPtr() - : pointer(nullptr) - {} - - RefPtr(T* p) - : pointer(p) - { - addReference(p); - } - - RefPtr(RefPtr const& p) - : pointer(p.pointer) - { - addReference(p.pointer); - } + addReference(p.pointer); + } - RefPtr(RefPtr&& p) - : pointer(p.pointer) - { - p.pointer = nullptr; - } + RefPtr(RefPtr&& p) + : pointer(p.pointer) + { + p.pointer = nullptr; + } - template - RefPtr(RefPtr const& p, - typename EnableIf::Value, void>::type * = 0) - : pointer(static_cast(p)) - { - addReference(static_cast(p)); - } + template + RefPtr(RefPtr const& p, typename EnableIf::Value, void>::type* = 0) + : pointer(static_cast(p)) + { + addReference(static_cast(p)); + } #if 0 void operator=(T* p) @@ -129,226 +135,202 @@ namespace Slang } #endif - void operator=(RefPtr const& p) - { - T* old = pointer; - addReference(p.pointer); - pointer = p.pointer; - releaseReference(old); - } + void operator=(RefPtr const& p) + { + T* old = pointer; + addReference(p.pointer); + pointer = p.pointer; + releaseReference(old); + } - void operator=(RefPtr&& p) - { - T* old = pointer; - pointer = p.pointer; - p.pointer = old; - } + void operator=(RefPtr&& p) + { + T* old = pointer; + pointer = p.pointer; + p.pointer = old; + } - template - typename EnableIf::value, void>::type - operator=(RefPtr const& p) - { - T* old = pointer; - addReference(p.pointer); - pointer = p.pointer; - releaseReference(old); - } + template + typename EnableIf::value, void>::type operator=(RefPtr const& p) + { + T* old = pointer; + addReference(p.pointer); + pointer = p.pointer; + releaseReference(old); + } - HashCode getHashCode() const - { - // Note: We need a `RefPtr` to hash the same as a `T*`, - // so that a `T*` can be used as a key in a dictionary with - // `RefPtr` keys, and vice versa. - // - return Slang::getHashCode(pointer); - } + HashCode getHashCode() const + { + // Note: We need a `RefPtr` to hash the same as a `T*`, + // so that a `T*` can be used as a key in a dictionary with + // `RefPtr` keys, and vice versa. + // + return Slang::getHashCode(pointer); + } - bool operator==(const T * ptr) const - { - return pointer == ptr; - } + bool operator==(const T* ptr) const { return pointer == ptr; } - bool operator!=(const T * ptr) const - { - return pointer != ptr; - } + bool operator!=(const T* ptr) const { return pointer != ptr; } - bool operator==(RefPtr const& ptr) const - { - return pointer == ptr.pointer; - } + bool operator==(RefPtr const& ptr) const { return pointer == ptr.pointer; } - bool operator!=(RefPtr const& ptr) const - { - return pointer != ptr.pointer; - } + bool operator!=(RefPtr const& ptr) const { return pointer != ptr.pointer; } - template - RefPtr dynamicCast() const - { - return RefPtr(Slang::dynamicCast(pointer)); - } + template + RefPtr dynamicCast() const + { + return RefPtr(Slang::dynamicCast(pointer)); + } - template - RefPtr as() const - { - return RefPtr(Slang::as(pointer)); - } + template + RefPtr as() const + { + return RefPtr(Slang::as(pointer)); + } - template - bool is() const { return Slang::as(pointer) != nullptr; } + template + bool is() const + { + return Slang::as(pointer) != nullptr; + } - ~RefPtr() - { - releaseReference(static_cast(pointer)); - } + ~RefPtr() { releaseReference(static_cast(pointer)); } - T& operator*() const - { - return *pointer; - } + T& operator*() const { return *pointer; } - T* operator->() const - { - return pointer; - } + T* operator->() const { return pointer; } - T * Ptr() const - { - return pointer; - } + T* Ptr() const { return pointer; } - T* get() const - { - return pointer; - } + T* get() const { return pointer; } - operator T*() const - { - return pointer; - } + operator T*() const { return pointer; } - void attach(T* p) - { - T* old = pointer; - pointer = p; - releaseReference(old); - } + void attach(T* p) + { + T* old = pointer; + pointer = p; + releaseReference(old); + } - T* detach() - { - auto rs = pointer; - pointer = nullptr; - return rs; - } + T* detach() + { + auto rs = pointer; + pointer = nullptr; + return rs; + } - void swapWith(RefPtr& rhs) - { - auto rhsPtr = rhs.pointer; - rhs.pointer = pointer; - pointer = rhsPtr; - } + void swapWith(RefPtr& rhs) + { + auto rhsPtr = rhs.pointer; + rhs.pointer = pointer; + pointer = rhsPtr; + } - SLANG_FORCE_INLINE void setNull() - { - releaseReference(pointer); - pointer = nullptr; - } + SLANG_FORCE_INLINE void setNull() + { + releaseReference(pointer); + pointer = nullptr; + } - /// Get ready for writing (nulls contents) - SLANG_FORCE_INLINE T** writeRef() { *this = nullptr; return &pointer; } + /// Get ready for writing (nulls contents) + SLANG_FORCE_INLINE T** writeRef() + { + *this = nullptr; + return &pointer; + } - /// Get for read access - SLANG_FORCE_INLINE T*const* readRef() const { return &pointer; } + /// Get for read access + SLANG_FORCE_INLINE T* const* readRef() const { return &pointer; } - private: - T* pointer; - }; +private: + T* pointer; +}; - // Helper type for implementing weak pointers. The object being pointed at weakly creates a WeakSink object - // that other objects can reference and share. When the object is destroyed it detaches the sink - // doing so will make other users call to 'get' return null. Thus any user of the WeakSink, must check if the weakly pointed to - // things pointer is nullptr before using. - template - class WeakSink : public RefObject +// Helper type for implementing weak pointers. The object being pointed at weakly creates a WeakSink +// object that other objects can reference and share. When the object is destroyed it detaches the +// sink doing so will make other users call to 'get' return null. Thus any user of the WeakSink, +// must check if the weakly pointed to things pointer is nullptr before using. +template +class WeakSink : public RefObject +{ +public: + WeakSink(T* ptr) + : m_ptr(ptr) { - public: - WeakSink(T* ptr): - m_ptr(ptr) - { - } + } - SLANG_FORCE_INLINE T* get() const { return m_ptr; } - SLANG_FORCE_INLINE void detach() { m_ptr = nullptr; } + SLANG_FORCE_INLINE T* get() const { return m_ptr; } + SLANG_FORCE_INLINE void detach() { m_ptr = nullptr; } - private: - T* m_ptr; - }; +private: + T* m_ptr; +}; - // A pointer that can be transformed to hold either a weak reference or a strong reference. - template - class TransformablePtr - { - private: - T* m_weakPtr = nullptr; - RefPtr m_strongPtr; +// A pointer that can be transformed to hold either a weak reference or a strong reference. +template +class TransformablePtr +{ +private: + T* m_weakPtr = nullptr; + RefPtr m_strongPtr; - public: - TransformablePtr() = default; - TransformablePtr(T* ptr) { *this = ptr; } - TransformablePtr(RefPtr ptr) { *this = ptr; } - TransformablePtr(const TransformablePtr& ptr) = default; - TransformablePtr& operator=(const TransformablePtr& ptr) = default; +public: + TransformablePtr() = default; + TransformablePtr(T* ptr) { *this = ptr; } + TransformablePtr(RefPtr ptr) { *this = ptr; } + TransformablePtr(const TransformablePtr& ptr) = default; + TransformablePtr& operator=(const TransformablePtr& ptr) = default; - void promoteToStrongReference() { m_strongPtr = m_weakPtr; } - void demoteToWeakReference() { m_strongPtr = nullptr; } - bool isStrongReference() const { return m_strongPtr != nullptr; } + void promoteToStrongReference() { m_strongPtr = m_weakPtr; } + void demoteToWeakReference() { m_strongPtr = nullptr; } + bool isStrongReference() const { return m_strongPtr != nullptr; } - T& operator*() const { return *m_weakPtr; } + T& operator*() const { return *m_weakPtr; } - T* operator->() const { return m_weakPtr; } + T* operator->() const { return m_weakPtr; } - T* Ptr() const { return m_weakPtr; } - T* get() const { return m_weakPtr; } + T* Ptr() const { return m_weakPtr; } + T* get() const { return m_weakPtr; } - operator T*() const { return m_weakPtr; } - operator RefPtr() const { return m_weakPtr; } + operator T*() const { return m_weakPtr; } + operator RefPtr() const { return m_weakPtr; } - TransformablePtr& operator=(T* ptr) - { - m_weakPtr = ptr; - m_strongPtr = ptr; - return *this; - } - template - TransformablePtr& operator=(const RefPtr& ptr) - { - m_weakPtr = ptr.Ptr(); - m_strongPtr = ptr; - return *this; - } - - HashCode getHashCode() const - { - // Note: We need a `RefPtr` to hash the same as a `T*`, - // so that a `T*` can be used as a key in a dictionary with - // `RefPtr` keys, and vice versa. - // - return Slang::getHashCode(m_weakPtr); - } + TransformablePtr& operator=(T* ptr) + { + m_weakPtr = ptr; + m_strongPtr = ptr; + return *this; + } + template + TransformablePtr& operator=(const RefPtr& ptr) + { + m_weakPtr = ptr.Ptr(); + m_strongPtr = ptr; + return *this; + } - bool operator==(const T* ptr) const { return m_weakPtr == ptr; } + HashCode getHashCode() const + { + // Note: We need a `RefPtr` to hash the same as a `T*`, + // so that a `T*` can be used as a key in a dictionary with + // `RefPtr` keys, and vice versa. + // + return Slang::getHashCode(m_weakPtr); + } - bool operator!=(const T* ptr) const { return m_weakPtr != ptr; } + bool operator==(const T* ptr) const { return m_weakPtr == ptr; } - bool operator==(RefPtr const& ptr) const { return m_weakPtr == ptr.Ptr(); } + bool operator!=(const T* ptr) const { return m_weakPtr != ptr; } - bool operator!=(RefPtr const& ptr) const { return m_weakPtr != ptr.Ptr(); } + bool operator==(RefPtr const& ptr) const { return m_weakPtr == ptr.Ptr(); } - bool operator==(TransformablePtr const& ptr) const { return m_weakPtr == ptr.m_weakPtr; } + bool operator!=(RefPtr const& ptr) const { return m_weakPtr != ptr.Ptr(); } - bool operator!=(TransformablePtr const& ptr) const { return m_weakPtr != ptr.m_weakPtr; } - }; -} + bool operator==(TransformablePtr const& ptr) const { return m_weakPtr == ptr.m_weakPtr; } + + bool operator!=(TransformablePtr const& ptr) const { return m_weakPtr != ptr.m_weakPtr; } +}; +} // namespace Slang #endif -- cgit v1.2.3