From 178b30bb20bfcbdb6e1847a69f4d38633fc7a14f Mon Sep 17 00:00:00 2001 From: Sandu Liviu Catalin Date: Tue, 21 Feb 2017 21:19:10 +0200 Subject: [PATCH] Minor adjustments to Sqrat types. Improved shared pointers to use less heap allocations for counters. --- include/sqrat/sqratObject.h | 31 +- include/sqrat/sqratTable.h | 18 ++ include/sqrat/sqratUtil.h | 602 ++++++++++++++++++++---------------- 3 files changed, 383 insertions(+), 268 deletions(-) diff --git a/include/sqrat/sqratObject.h b/include/sqrat/sqratObject.h index e4134b00..11af3d75 100644 --- a/include/sqrat/sqratObject.h +++ b/include/sqrat/sqratObject.h @@ -814,7 +814,7 @@ struct LightObj { /// \return Squirrel object /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - virtual HSQOBJECT GetObject() const { + HSQOBJECT GetObject() const { return mObj; } @@ -824,7 +824,7 @@ struct LightObj { /// \return Squirrel object /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - virtual HSQOBJECT& GetObject() { + HSQOBJECT& GetObject() { return mObj; } @@ -836,6 +836,16 @@ struct LightObj { return mObj; } + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Gets the Squirrel VM for this Object (copy) + /// + /// \return Squirrel VM associated with the Object + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline HSQUIRRELVM GetVM() const { + return DefaultVM::Get(); + } + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Sets the LightObj to null (removing its references to underlying Squirrel objects) /// @@ -847,6 +857,23 @@ struct LightObj { sq_resetobject(&mObj); } } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Binds a Table or Class to the object (can be used to facilitate namespaces) + /// + /// \param name The key in the table being assigned a Table or Class + /// \param obj Table or Class that is being placed in the table + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Bind(const SQChar* name, LightObj& obj) { + HSQUIRRELVM vm = DefaultVM::Get(); + sq_pushobject(vm, mObj); + sq_pushstring(vm, name, -1); + sq_pushobject(vm, obj.mObj); + sq_newslot(vm, -3, false); + sq_pop(vm,1); // pop table + } + }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/sqrat/sqratTable.h b/include/sqrat/sqratTable.h index 75feca7e..1cc532bd 100644 --- a/include/sqrat/sqratTable.h +++ b/include/sqrat/sqratTable.h @@ -147,6 +147,24 @@ public: sq_pop(vm,1); // pop table } + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Binds a Table or Class to the Table (can be used to facilitate namespaces) + /// + /// \param name The key in the table being assigned a Table or Class + /// \param obj Table or Class that is being placed in the table + /// + /// \remarks + /// Bind cannot be called "inline" like other functions because it introduces order-of-initialization bugs. + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Bind(const SQChar* name, LightObj& obj) { + sq_pushobject(vm, GetObject()); + sq_pushstring(vm, name, -1); + sq_pushobject(vm, obj.GetObject()); + sq_newslot(vm, -3, false); + sq_pop(vm,1); // pop table + } + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// Binds a raw Squirrel closure to the Table /// diff --git a/include/sqrat/sqratUtil.h b/include/sqrat/sqratUtil.h index b35e984e..0cdfab03 100644 --- a/include/sqrat/sqratUtil.h +++ b/include/sqrat/sqratUtil.h @@ -504,6 +504,33 @@ inline string LastErrorString(HSQUIRRELVM vm) { return string(sqErr, size); } +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/// Used internally to store the counters of managed pointers. +/// +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +struct SqReferenceCounter { + typedef unsigned int ValueType; ///< The type of value that is used to represent a count. + + ValueType mHard; ///< Strong reference count. If equal to zero, the object has been destroyed. + ValueType mSoft; ///< Weak reference count. If equal to zero, the counter has been destroyed. + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Default constructor + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + SqReferenceCounter() + : mHard(0), mSoft(0) + { } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Construct with specific counts + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + SqReferenceCounter(ValueType hard, ValueType soft) + : mHard(hard), mSoft(soft) + { } +}; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// A smart pointer that retains shared ownership of an object through a pointer (see std::shared_ptr) /// @@ -525,11 +552,66 @@ class SharedPtr template friend class WeakPtr; + typedef SqReferenceCounter Counter; + private: T* m_Ptr; - unsigned int* m_RefCount; - unsigned int* m_RefCountRefCount; + Counter* m_Ref; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Constructs with explicit pointer and counter. + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + SharedPtr(T * ptr, Counter * ref) + : m_Ptr(ptr) + , m_Ref(ref) + { + if (m_Ptr != NULL) + { + ++(m_Ref->mHard); + ++(m_Ref->mSoft); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Assigns a new pointer. + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Assign(T * ptr) noexcept + { + if (m_Ptr != ptr) + { + Reset(); + + if (ptr != NULL) + { + m_Ptr = ptr; + m_Ref = new Counter(1,1); + } + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Assigns a new pointer and counter. + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Assign(T * ptr, Counter * ref) noexcept + { + if (m_Ptr != ptr) + { + Reset(); + + if (ptr != NULL) + { + m_Ptr = ptr; + m_Ref = ref; + + ++(m_Ref->mHard); + ++(m_Ref->mSoft); + } + } + } public: @@ -537,10 +619,9 @@ public: /// Constructs a new SharedPtr /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - SharedPtr() : - m_Ptr (NULL), - m_RefCount (NULL), - m_RefCountRefCount(NULL) + SharedPtr() + : m_Ptr(NULL) + , m_Ref(NULL) { } @@ -551,12 +632,11 @@ public: /// \param ptr Should be the return value from a call to the new operator /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - SharedPtr(T* ptr) : - m_Ptr (NULL), - m_RefCount (NULL), - m_RefCountRefCount(NULL) + SharedPtr(T* ptr) + : m_Ptr(NULL) + , m_Ref(NULL) { - Init(ptr); + Assign(ptr); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -568,12 +648,11 @@ public: /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template - SharedPtr(U* ptr) : - m_Ptr (NULL), - m_RefCount (NULL), - m_RefCountRefCount(NULL) + SharedPtr(U* ptr) + : m_Ptr(NULL) + , m_Ref(NULL) { - Init(ptr); + Assign(static_cast(ptr)); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -583,22 +662,8 @@ public: /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// SharedPtr(const SharedPtr& copy) + : SharedPtr(copy.m_Ptr, copy.m_Ref) { - if (copy.Get() != NULL) - { - m_Ptr = copy.Get(); - m_RefCount = copy.m_RefCount; - m_RefCountRefCount = copy.m_RefCountRefCount; - - *m_RefCount += 1; - *m_RefCountRefCount += 1; - } - else - { - m_Ptr = NULL; - m_RefCount = NULL; - m_RefCountRefCount = NULL; - } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -611,22 +676,8 @@ public: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template SharedPtr(const SharedPtr& copy) + : SharedPtr(static_cast(copy.m_Ptr), copy.m_Ref) { - if (copy.Get() != NULL) - { - m_Ptr = static_cast(copy.Get()); - m_RefCount = copy.m_RefCount; - m_RefCountRefCount = copy.m_RefCountRefCount; - - *m_RefCount += 1; - *m_RefCountRefCount += 1; - } - else - { - m_Ptr = NULL; - m_RefCount = NULL; - m_RefCountRefCount = NULL; - } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -637,12 +688,10 @@ public: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// SharedPtr(SharedPtr&& other) : m_Ptr(other.m_Ptr) - , m_RefCount(other.m_RefCount) - , m_RefCountRefCount(other.m_RefCountRefCount) + , m_Ref(other.m_Ref) { - other.m_Ptr = NULL; - other.m_RefCount = NULL; - other.m_RefCountRefCount = NULL; + other.m_Ptr = NULL; + other.m_Ref = NULL; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -656,12 +705,23 @@ public: template SharedPtr(SharedPtr&& other) : m_Ptr(static_cast(other.m_Ptr)) - , m_RefCount(other.m_RefCount) - , m_RefCountRefCount(other.m_RefCountRefCount) + , m_Ref(other.m_Ref) + { + other.m_Ptr = NULL; + other.m_Ref = NULL; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Copy constructor + /// + /// \param copy WeakPtr to copy + /// + /// \tparam U Type of copy (usually doesnt need to be defined explicitly) + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + SharedPtr(const WeakPtr& copy) + : SharedPtr(copy.m_Ptr, copy.m_Ref) { - other.m_Ptr = NULL; - other.m_RefCount = NULL; - other.m_RefCountRefCount = NULL; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -674,22 +734,8 @@ public: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template SharedPtr(const WeakPtr& copy) + : SharedPtr(static_cast(copy.m_Ptr), copy.m_Ref) { - if (copy.m_Ptr != NULL) - { - m_Ptr = static_cast(copy.m_Ptr); - m_RefCount = copy.m_RefCount; - m_RefCountRefCount = copy.m_RefCountRefCount; - - *m_RefCount += 1; - *m_RefCountRefCount += 1; - } - else - { - m_Ptr = NULL; - m_RefCount = NULL; - m_RefCountRefCount = NULL; - } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -711,20 +757,7 @@ public: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// SharedPtr& operator=(const SharedPtr& copy) { - if (this != ©) - { - Reset(); - - if (copy.Get() != NULL) - { - m_Ptr = copy.Get(); - m_RefCount = copy.m_RefCount; - m_RefCountRefCount = copy.m_RefCountRefCount; - - *m_RefCount += 1; - *m_RefCountRefCount += 1; - } - } + Assign(copy.m_Ptr, copy.m_Ref); return *this; } @@ -742,17 +775,7 @@ public: template SharedPtr& operator=(const SharedPtr& copy) { - Reset(); - - if (copy.Get() != NULL) - { - m_Ptr = static_cast(copy.Get()); - m_RefCount = copy.m_RefCount; - m_RefCountRefCount = copy.m_RefCountRefCount; - - *m_RefCount += 1; - *m_RefCountRefCount += 1; - } + Assign(static_cast(copy.m_Ptr), copy.m_Ref); return *this; } @@ -772,12 +795,10 @@ public: Reset(); m_Ptr = other.m_Ptr; - m_RefCount = other.m_RefCount; - m_RefCountRefCount = other.m_RefCountRefCount; + m_Ref = other.m_Ref; - other.m_Ptr = NULL; - other.m_RefCount = NULL; - other.m_RefCountRefCount = NULL; + other.m_Ptr = NULL; + other.m_Ref = NULL; } return *this; @@ -801,12 +822,10 @@ public: Reset(); m_Ptr = static_cast(other.m_Ptr); - m_RefCount = other.m_RefCount; - m_RefCountRefCount = other.m_RefCountRefCount; + m_Ref = other.m_Ref; - other.m_Ptr = NULL; - other.m_RefCount = NULL; - other.m_RefCountRefCount = NULL; + other.m_Ptr = NULL; + other.m_Ref = NULL; } return *this; @@ -820,15 +839,7 @@ public: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Init(T* ptr) { - Reset(); - - m_Ptr = ptr; - - m_RefCount = new unsigned int; - *m_RefCount = 1; - - m_RefCountRefCount = new unsigned int; - *m_RefCountRefCount = 1; + Assign(ptr); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -842,15 +853,7 @@ public: template void Init(U* ptr) { - Reset(); - - m_Ptr = static_cast(ptr); - - m_RefCount = new unsigned int; - *m_RefCount = 1; - - m_RefCountRefCount = new unsigned int; - *m_RefCountRefCount = 1; + Assign(static_cast(ptr)); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -861,23 +864,22 @@ public: { if (m_Ptr != NULL) { - *m_RefCount -= 1; - *m_RefCountRefCount -= 1; + --(m_Ref->mHard); - if (*m_RefCount == 0) + if (m_Ref->mHard == 0) { delete m_Ptr; } - if (*m_RefCountRefCount == 0) + --(m_Ref->mSoft); + + if (m_Ref->mSoft == 0) { - delete m_RefCount; - delete m_RefCountRefCount; + delete m_Ref; } - m_Ptr = NULL; - m_RefCount = NULL; - m_RefCountRefCount = NULL; + m_Ptr = NULL; + m_Ref = NULL; } } @@ -1050,9 +1052,9 @@ public: /// \return Number of references /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - unsigned int Count() const + Counter::ValueType Count() const { - return m_RefCount ? *m_RefCount : 0; + return m_Ref ? m_Ref->mHard : 0; } }; @@ -1074,11 +1076,66 @@ class WeakPtr template friend class SharedPtr; + typedef SqReferenceCounter Counter; + private: T* m_Ptr; - unsigned int* m_RefCount; - unsigned int* m_RefCountRefCount; + Counter* m_Ref; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Constructs with explicit pointer and counter. + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + WeakPtr(T * ptr, Counter * ref) + : m_Ptr(ptr) + , m_Ref(ref) + { + if (m_Ptr != NULL) + { + ++(m_Ref->mSoft); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Initializes the pointer and counter. + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Initialize(T * ptr, Counter * ref) noexcept + { + if (ptr != NULL) + { + m_Ptr = ptr; + m_Ref = ref; + + ++(m_Ref->mSoft); + } + else + { + m_Ptr = NULL; + m_Ref = NULL; + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Assigns a new pointer and counter. + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Assign(T * ptr, Counter * ref) noexcept + { + if (m_Ptr != ptr) + { + Reset(); + + if (ptr != NULL) + { + m_Ptr = ptr; + m_Ref = ref; + + ++(m_Ref->mSoft); + } + } + } public: @@ -1086,10 +1143,9 @@ public: /// Constructs a new WeakPtr /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - WeakPtr() : - m_Ptr (NULL), - m_RefCount (NULL), - m_RefCountRefCount(NULL) + WeakPtr() + : m_Ptr(NULL) + , m_Ref(NULL) { } @@ -1102,20 +1158,7 @@ public: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// WeakPtr(const WeakPtr& copy) { - if (copy.m_Ptr != NULL) - { - m_Ptr = copy.m_Ptr; - m_RefCount = copy.m_RefCount; - m_RefCountRefCount = copy.m_RefCountRefCount; - - *m_RefCountRefCount += 1; - } - else - { - m_Ptr = NULL; - m_RefCount = NULL; - m_RefCountRefCount = NULL; - } + Initialize(copy.m_Ptr, copy.m_Ref); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1129,20 +1172,7 @@ public: template WeakPtr(const WeakPtr& copy) { - if (copy.m_Ptr != NULL) - { - m_Ptr = static_cast(copy.m_Ptr); - m_RefCount = copy.m_RefCount; - m_RefCountRefCount = copy.m_RefCountRefCount; - - *m_RefCountRefCount += 1; - } - else - { - m_Ptr = NULL; - m_RefCount = NULL; - m_RefCountRefCount = NULL; - } + Initialize(static_cast(copy.m_Ptr), copy.m_Ref); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1153,12 +1183,10 @@ public: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// WeakPtr(WeakPtr&& other) : m_Ptr(other.m_Ptr) - , m_RefCount(other.m_RefCount) - , m_RefCountRefCount(other.m_RefCountRefCount) + , m_Ref(other.m_Ref) { - other.m_Ptr = NULL; - other.m_RefCount = NULL; - other.m_RefCountRefCount = NULL; + other.m_Ptr = NULL; + other.m_Ref = NULL; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1172,12 +1200,21 @@ public: template WeakPtr(WeakPtr&& other) : m_Ptr(static_cast(other.m_Ptr)) - , m_RefCount(other.m_RefCount) - , m_RefCountRefCount(other.m_RefCountRefCount) + , m_Ref(other.m_Ref) { - other.m_Ptr = NULL; - other.m_RefCount = NULL; - other.m_RefCountRefCount = NULL; + other.m_Ptr = NULL; + other.m_Ref = NULL; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Copy constructor + /// + /// \param copy SharedPtr to copy + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + WeakPtr(const SharedPtr& copy) + { + Initialize(copy.m_Ptr, copy.m_Ref); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1191,20 +1228,7 @@ public: template WeakPtr(const SharedPtr& copy) { - if (copy.Get() != NULL) - { - m_Ptr = static_cast(copy.Get()); - m_RefCount = copy.m_RefCount; - m_RefCountRefCount = copy.m_RefCountRefCount; - - *m_RefCountRefCount += 1; - } - else - { - m_Ptr = NULL; - m_RefCount = NULL; - m_RefCountRefCount = NULL; - } + Initialize(static_cast(copy.m_Ptr), copy.m_Ref); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1226,19 +1250,7 @@ public: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// WeakPtr& operator=(const WeakPtr& copy) { - if (this != ©) - { - Reset(); - - if (copy.m_Ptr != NULL) - { - m_Ptr = copy.m_Ptr; - m_RefCount = copy.m_RefCount; - m_RefCountRefCount = copy.m_RefCountRefCount; - - *m_RefCountRefCount += 1; - } - } + Assign(copy.m_Ptr, copy.m_Ref); return *this; } @@ -1256,16 +1268,7 @@ public: template WeakPtr& operator=(const WeakPtr& copy) { - Reset(); - - if (copy.m_Ptr != NULL) - { - m_Ptr = static_cast(copy.m_Ptr); - m_RefCount = copy.m_RefCount; - m_RefCountRefCount = copy.m_RefCountRefCount; - - *m_RefCountRefCount += 1; - } + Assign(static_cast(copy.m_Ptr), copy.m_Ref); return *this; } @@ -1284,13 +1287,11 @@ public: { Reset(); - m_Ptr = other.m_Ptr; - m_RefCount = other.m_RefCount; - m_RefCountRefCount = other.m_RefCountRefCount; + m_Ptr = other.m_Ptr; + m_Ref = other.m_Ref; - other.m_Ptr = NULL; - other.m_RefCount = NULL; - other.m_RefCountRefCount = NULL; + other.m_Ptr = NULL; + other.m_Ref = NULL; } return *this; @@ -1313,20 +1314,33 @@ public: { Reset(); - m_Ptr = static_cast(other.m_Ptr); - m_RefCount = other.m_RefCount; - m_RefCountRefCount = other.m_RefCountRefCount; + m_Ptr = static_cast(other.m_Ptr); + m_Ref = other.m_Ref; - other.m_Ptr = NULL; - other.m_RefCount = NULL; - other.m_RefCountRefCount = NULL; + other.m_Ptr = NULL; + other.m_Ref = NULL; } return *this; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// Assigns the WeakPtr + /// Assigns the SharedPtr + /// + /// \param copy SharedPtr to copy + /// + /// \return The WeakPtr itself + /// + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + WeakPtr& operator=(const SharedPtr& copy) + { + Assign(copy.m_Ptr, copy.m_Ref); + + return *this; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Assigns the SharedPtr /// /// \param copy SharedPtr to copy /// @@ -1338,16 +1352,7 @@ public: template WeakPtr& operator=(const SharedPtr& copy) { - Reset(); - - if (copy.Get() != NULL) - { - m_Ptr = static_cast(copy.Get()); - m_RefCount = copy.m_RefCount; - m_RefCountRefCount = copy.m_RefCountRefCount; - - *m_RefCountRefCount += 1; - } + Assign(static_cast(copy.m_Ptr), copy.m_Ref); return *this; } @@ -1360,7 +1365,7 @@ public: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool Expired() const { - return (m_Ptr == NULL || *m_RefCount == 0); + return (m_Ptr == NULL || m_Ref->mHard == 0); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1371,17 +1376,7 @@ public: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// SharedPtr Lock() const { - SharedPtr other; - if (m_Ptr != NULL) - { - other.m_Ptr = m_Ptr; - other.m_RefCount = m_RefCount; - other.m_RefCountRefCount = m_RefCountRefCount; - - *m_RefCount += 1; - *m_RefCountRefCount += 1; - } - return other; + return SharedPtr(m_Ptr, m_Ref); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1392,17 +1387,15 @@ public: { if (m_Ptr != NULL) { - *m_RefCountRefCount -= 1; + --(m_Ref->mSoft); - if (*m_RefCountRefCount == 0) + if (m_Ref->mSoft == 0) { - delete m_RefCount; - delete m_RefCountRefCount; + delete m_Ref; } - m_Ptr = NULL; - m_RefCount = NULL; - m_RefCountRefCount = NULL; + m_Ptr = NULL; + m_Ref = NULL; } } @@ -1412,9 +1405,9 @@ public: /// \return Number of references /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - unsigned int Count() const + Counter::ValueType Count() const { - return m_RefCountRefCount ? *m_RefCountRefCount : 0; + return m_Ref ? m_Ref->mSoft : 0; } }; @@ -1641,6 +1634,83 @@ struct StackStrF StackStrF & operator = (StackStrF && o) = delete; }; +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/// RAII approach to make sure an instance is deleted regardless of what exceptions are thrown. +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +template < typename T > struct DeleteGuard +{ +private: + + // -------------------------------------------------------------------------------------------- + T * m_Ptr; // Pointer to the instance to manage. + +public: + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Default constructor. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + DeleteGuard(T * ptr) + : m_Ptr(ptr) + { + /* ... */ + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Copy constructor. (disabled) + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + DeleteGuard(const DeleteGuard & o) = delete; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Move constructor. (disabled) + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + DeleteGuard(DeleteGuard && o) = delete; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Destructor. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ~DeleteGuard() + { + if (m_Ptr) + { + delete m_Ptr; + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Copy assignment operator. (disabled) + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + DeleteGuard & operator = (const DeleteGuard & o) = delete; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Move assignment operator. (disabled) + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + DeleteGuard & operator = (DeleteGuard && o) = delete; + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Implicit conversion the managed instance type. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + operator T * () const + { + return m_Ptr; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Retrieve the managed instance. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + T * Get() const + { + return m_Ptr; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Release the managed instance. + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Release() + { + m_Ptr = nullptr; + } +}; + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// @cond DEV /// Used internally to get and manipulate the underlying type of variables - retrieved from cppreference.com @@ -1650,13 +1720,13 @@ template struct remove_const template struct remove_volatile {typedef T type;}; template struct remove_volatile {typedef T type;}; template struct remove_cv {typedef typename remove_volatile::type>::type type;}; -template struct is_pointer_helper {static const bool value = false;}; -template struct is_pointer_helper {static const bool value = true;}; -template struct is_pointer_helper > {static const bool value = true;}; -template struct is_pointer_helper > {static const bool value = true;}; +template struct is_pointer_helper {static constexpr bool value = false;}; +template struct is_pointer_helper {static constexpr bool value = true;}; +template struct is_pointer_helper > {static constexpr bool value = true;}; +template struct is_pointer_helper > {static constexpr bool value = true;}; template struct is_pointer : is_pointer_helper::type> {}; -template struct is_reference {static const bool value = false;}; -template struct is_reference {static const bool value = true;}; +template struct is_reference {static constexpr bool value = false;}; +template struct is_reference {static constexpr bool value = true;}; /// @endcond }