1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-04-25 13:47:12 +02:00

Minor adjustments to Sqrat types. Improved shared pointers to use less heap allocations for counters.

This commit is contained in:
Sandu Liviu Catalin 2017-02-21 21:19:10 +02:00
parent 6909e46125
commit 178b30bb20
3 changed files with 383 additions and 268 deletions

View File

@ -814,7 +814,7 @@ struct LightObj {
/// \return Squirrel object /// \return Squirrel object
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual HSQOBJECT GetObject() const { HSQOBJECT GetObject() const {
return mObj; return mObj;
} }
@ -824,7 +824,7 @@ struct LightObj {
/// \return Squirrel object /// \return Squirrel object
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
virtual HSQOBJECT& GetObject() { HSQOBJECT& GetObject() {
return mObj; return mObj;
} }
@ -836,6 +836,16 @@ struct LightObj {
return mObj; 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) /// Sets the LightObj to null (removing its references to underlying Squirrel objects)
/// ///
@ -847,6 +857,23 @@ struct LightObj {
sq_resetobject(&mObj); 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
}
}; };
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -147,6 +147,24 @@ public:
sq_pop(vm,1); // pop table 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 /// Binds a raw Squirrel closure to the Table
/// ///

View File

@ -504,6 +504,33 @@ inline string LastErrorString(HSQUIRRELVM vm) {
return string(sqErr, size); 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) /// A smart pointer that retains shared ownership of an object through a pointer (see std::shared_ptr)
/// ///
@ -525,11 +552,66 @@ class SharedPtr
template <class U> template <class U>
friend class WeakPtr; friend class WeakPtr;
typedef SqReferenceCounter Counter;
private: private:
T* m_Ptr; T* m_Ptr;
unsigned int* m_RefCount; Counter* m_Ref;
unsigned int* m_RefCountRefCount;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 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: public:
@ -537,10 +619,9 @@ public:
/// Constructs a new SharedPtr /// Constructs a new SharedPtr
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SharedPtr() : SharedPtr()
m_Ptr (NULL), : m_Ptr(NULL)
m_RefCount (NULL), , m_Ref(NULL)
m_RefCountRefCount(NULL)
{ {
} }
@ -551,12 +632,11 @@ public:
/// \param ptr Should be the return value from a call to the new operator /// \param ptr Should be the return value from a call to the new operator
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SharedPtr(T* ptr) : SharedPtr(T* ptr)
m_Ptr (NULL), : m_Ptr(NULL)
m_RefCount (NULL), , m_Ref(NULL)
m_RefCountRefCount(NULL)
{ {
Init(ptr); Assign(ptr);
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -568,12 +648,11 @@ public:
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <class U> template <class U>
SharedPtr(U* ptr) : SharedPtr(U* ptr)
m_Ptr (NULL), : m_Ptr(NULL)
m_RefCount (NULL), , m_Ref(NULL)
m_RefCountRefCount(NULL)
{ {
Init(ptr); Assign(static_cast<T*>(ptr));
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -583,22 +662,8 @@ public:
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SharedPtr(const SharedPtr<T>& copy) SharedPtr(const SharedPtr<T>& 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 <class U> template <class U>
SharedPtr(const SharedPtr<U>& copy) SharedPtr(const SharedPtr<U>& copy)
: SharedPtr(static_cast<T*>(copy.m_Ptr), copy.m_Ref)
{ {
if (copy.Get() != NULL)
{
m_Ptr = static_cast<T*>(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<T>&& other) SharedPtr(SharedPtr<T>&& other)
: m_Ptr(other.m_Ptr) : m_Ptr(other.m_Ptr)
, m_RefCount(other.m_RefCount) , m_Ref(other.m_Ref)
, m_RefCountRefCount(other.m_RefCountRefCount)
{ {
other.m_Ptr = NULL; other.m_Ptr = NULL;
other.m_RefCount = NULL; other.m_Ref = NULL;
other.m_RefCountRefCount = NULL;
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -656,12 +705,23 @@ public:
template <class U> template <class U>
SharedPtr(SharedPtr<U>&& other) SharedPtr(SharedPtr<U>&& other)
: m_Ptr(static_cast<T*>(other.m_Ptr)) : m_Ptr(static_cast<T*>(other.m_Ptr))
, m_RefCount(other.m_RefCount) , m_Ref(other.m_Ref)
, m_RefCountRefCount(other.m_RefCountRefCount)
{ {
other.m_Ptr = NULL; other.m_Ptr = NULL;
other.m_RefCount = NULL; other.m_Ref = NULL;
other.m_RefCountRefCount = NULL; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Copy constructor
///
/// \param copy WeakPtr to copy
///
/// \tparam U Type of copy (usually doesnt need to be defined explicitly)
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SharedPtr(const WeakPtr<T>& copy)
: SharedPtr(copy.m_Ptr, copy.m_Ref)
{
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -674,22 +734,8 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <class U> template <class U>
SharedPtr(const WeakPtr<U>& copy) SharedPtr(const WeakPtr<U>& copy)
: SharedPtr(static_cast<T*>(copy.m_Ptr), copy.m_Ref)
{ {
if (copy.m_Ptr != NULL)
{
m_Ptr = static_cast<T*>(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<T>& operator=(const SharedPtr<T>& copy) SharedPtr<T>& operator=(const SharedPtr<T>& copy)
{ {
if (this != &copy) Assign(copy.m_Ptr, copy.m_Ref);
{
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;
}
}
return *this; return *this;
} }
@ -742,17 +775,7 @@ public:
template <class U> template <class U>
SharedPtr<T>& operator=(const SharedPtr<U>& copy) SharedPtr<T>& operator=(const SharedPtr<U>& copy)
{ {
Reset(); Assign(static_cast<T*>(copy.m_Ptr), copy.m_Ref);
if (copy.Get() != NULL)
{
m_Ptr = static_cast<T*>(copy.Get());
m_RefCount = copy.m_RefCount;
m_RefCountRefCount = copy.m_RefCountRefCount;
*m_RefCount += 1;
*m_RefCountRefCount += 1;
}
return *this; return *this;
} }
@ -772,12 +795,10 @@ public:
Reset(); Reset();
m_Ptr = other.m_Ptr; m_Ptr = other.m_Ptr;
m_RefCount = other.m_RefCount; m_Ref = other.m_Ref;
m_RefCountRefCount = other.m_RefCountRefCount;
other.m_Ptr = NULL; other.m_Ptr = NULL;
other.m_RefCount = NULL; other.m_Ref = NULL;
other.m_RefCountRefCount = NULL;
} }
return *this; return *this;
@ -801,12 +822,10 @@ public:
Reset(); Reset();
m_Ptr = static_cast<T*>(other.m_Ptr); m_Ptr = static_cast<T*>(other.m_Ptr);
m_RefCount = other.m_RefCount; m_Ref = other.m_Ref;
m_RefCountRefCount = other.m_RefCountRefCount;
other.m_Ptr = NULL; other.m_Ptr = NULL;
other.m_RefCount = NULL; other.m_Ref = NULL;
other.m_RefCountRefCount = NULL;
} }
return *this; return *this;
@ -820,15 +839,7 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Init(T* ptr) void Init(T* ptr)
{ {
Reset(); Assign(ptr);
m_Ptr = ptr;
m_RefCount = new unsigned int;
*m_RefCount = 1;
m_RefCountRefCount = new unsigned int;
*m_RefCountRefCount = 1;
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -842,15 +853,7 @@ public:
template <class U> template <class U>
void Init(U* ptr) void Init(U* ptr)
{ {
Reset(); Assign(static_cast<T*>(ptr));
m_Ptr = static_cast<T*>(ptr);
m_RefCount = new unsigned int;
*m_RefCount = 1;
m_RefCountRefCount = new unsigned int;
*m_RefCountRefCount = 1;
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -861,23 +864,22 @@ public:
{ {
if (m_Ptr != NULL) if (m_Ptr != NULL)
{ {
*m_RefCount -= 1; --(m_Ref->mHard);
*m_RefCountRefCount -= 1;
if (*m_RefCount == 0) if (m_Ref->mHard == 0)
{ {
delete m_Ptr; delete m_Ptr;
} }
if (*m_RefCountRefCount == 0) --(m_Ref->mSoft);
if (m_Ref->mSoft == 0)
{ {
delete m_RefCount; delete m_Ref;
delete m_RefCountRefCount;
} }
m_Ptr = NULL; m_Ptr = NULL;
m_RefCount = NULL; m_Ref = NULL;
m_RefCountRefCount = NULL;
} }
} }
@ -1050,9 +1052,9 @@ public:
/// \return Number of references /// \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 <class U> template <class U>
friend class SharedPtr; friend class SharedPtr;
typedef SqReferenceCounter Counter;
private: private:
T* m_Ptr; T* m_Ptr;
unsigned int* m_RefCount; Counter* m_Ref;
unsigned int* m_RefCountRefCount;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 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: public:
@ -1086,10 +1143,9 @@ public:
/// Constructs a new WeakPtr /// Constructs a new WeakPtr
/// ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
WeakPtr() : WeakPtr()
m_Ptr (NULL), : m_Ptr(NULL)
m_RefCount (NULL), , m_Ref(NULL)
m_RefCountRefCount(NULL)
{ {
} }
@ -1102,20 +1158,7 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
WeakPtr(const WeakPtr<T>& copy) WeakPtr(const WeakPtr<T>& copy)
{ {
if (copy.m_Ptr != NULL) Initialize(copy.m_Ptr, copy.m_Ref);
{
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;
}
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1129,20 +1172,7 @@ public:
template <class U> template <class U>
WeakPtr(const WeakPtr<U>& copy) WeakPtr(const WeakPtr<U>& copy)
{ {
if (copy.m_Ptr != NULL) Initialize(static_cast<T*>(copy.m_Ptr), copy.m_Ref);
{
m_Ptr = static_cast<T*>(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;
}
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1153,12 +1183,10 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
WeakPtr(WeakPtr<T>&& other) WeakPtr(WeakPtr<T>&& other)
: m_Ptr(other.m_Ptr) : m_Ptr(other.m_Ptr)
, m_RefCount(other.m_RefCount) , m_Ref(other.m_Ref)
, m_RefCountRefCount(other.m_RefCountRefCount)
{ {
other.m_Ptr = NULL; other.m_Ptr = NULL;
other.m_RefCount = NULL; other.m_Ref = NULL;
other.m_RefCountRefCount = NULL;
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1172,12 +1200,21 @@ public:
template <class U> template <class U>
WeakPtr(WeakPtr<U>&& other) WeakPtr(WeakPtr<U>&& other)
: m_Ptr(static_cast<T*>(other.m_Ptr)) : m_Ptr(static_cast<T*>(other.m_Ptr))
, m_RefCount(other.m_RefCount) , m_Ref(other.m_Ref)
, m_RefCountRefCount(other.m_RefCountRefCount)
{ {
other.m_Ptr = NULL; other.m_Ptr = NULL;
other.m_RefCount = NULL; other.m_Ref = NULL;
other.m_RefCountRefCount = NULL; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Copy constructor
///
/// \param copy SharedPtr to copy
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
WeakPtr(const SharedPtr<T>& copy)
{
Initialize(copy.m_Ptr, copy.m_Ref);
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1191,20 +1228,7 @@ public:
template <class U> template <class U>
WeakPtr(const SharedPtr<U>& copy) WeakPtr(const SharedPtr<U>& copy)
{ {
if (copy.Get() != NULL) Initialize(static_cast<T*>(copy.m_Ptr), copy.m_Ref);
{
m_Ptr = static_cast<T*>(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;
}
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1226,19 +1250,7 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
WeakPtr<T>& operator=(const WeakPtr<T>& copy) WeakPtr<T>& operator=(const WeakPtr<T>& copy)
{ {
if (this != &copy) Assign(copy.m_Ptr, copy.m_Ref);
{
Reset();
if (copy.m_Ptr != NULL)
{
m_Ptr = copy.m_Ptr;
m_RefCount = copy.m_RefCount;
m_RefCountRefCount = copy.m_RefCountRefCount;
*m_RefCountRefCount += 1;
}
}
return *this; return *this;
} }
@ -1256,16 +1268,7 @@ public:
template <class U> template <class U>
WeakPtr<T>& operator=(const WeakPtr<U>& copy) WeakPtr<T>& operator=(const WeakPtr<U>& copy)
{ {
Reset(); Assign(static_cast<T*>(copy.m_Ptr), copy.m_Ref);
if (copy.m_Ptr != NULL)
{
m_Ptr = static_cast<T*>(copy.m_Ptr);
m_RefCount = copy.m_RefCount;
m_RefCountRefCount = copy.m_RefCountRefCount;
*m_RefCountRefCount += 1;
}
return *this; return *this;
} }
@ -1285,12 +1288,10 @@ public:
Reset(); Reset();
m_Ptr = other.m_Ptr; m_Ptr = other.m_Ptr;
m_RefCount = other.m_RefCount; m_Ref = other.m_Ref;
m_RefCountRefCount = other.m_RefCountRefCount;
other.m_Ptr = NULL; other.m_Ptr = NULL;
other.m_RefCount = NULL; other.m_Ref = NULL;
other.m_RefCountRefCount = NULL;
} }
return *this; return *this;
@ -1314,19 +1315,32 @@ public:
Reset(); Reset();
m_Ptr = static_cast<T*>(other.m_Ptr); m_Ptr = static_cast<T*>(other.m_Ptr);
m_RefCount = other.m_RefCount; m_Ref = other.m_Ref;
m_RefCountRefCount = other.m_RefCountRefCount;
other.m_Ptr = NULL; other.m_Ptr = NULL;
other.m_RefCount = NULL; other.m_Ref = NULL;
other.m_RefCountRefCount = NULL;
} }
return *this; return *this;
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Assigns the WeakPtr /// Assigns the SharedPtr
///
/// \param copy SharedPtr to copy
///
/// \return The WeakPtr itself
///
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
WeakPtr<T>& operator=(const SharedPtr<T>& copy)
{
Assign(copy.m_Ptr, copy.m_Ref);
return *this;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Assigns the SharedPtr
/// ///
/// \param copy SharedPtr to copy /// \param copy SharedPtr to copy
/// ///
@ -1338,16 +1352,7 @@ public:
template <class U> template <class U>
WeakPtr<T>& operator=(const SharedPtr<U>& copy) WeakPtr<T>& operator=(const SharedPtr<U>& copy)
{ {
Reset(); Assign(static_cast<T*>(copy.m_Ptr), copy.m_Ref);
if (copy.Get() != NULL)
{
m_Ptr = static_cast<T*>(copy.Get());
m_RefCount = copy.m_RefCount;
m_RefCountRefCount = copy.m_RefCountRefCount;
*m_RefCountRefCount += 1;
}
return *this; return *this;
} }
@ -1360,7 +1365,7 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool Expired() const bool Expired() const
{ {
return (m_Ptr == NULL || *m_RefCount == 0); return (m_Ptr == NULL || m_Ref->mHard == 0);
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1371,17 +1376,7 @@ public:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SharedPtr<T> Lock() const SharedPtr<T> Lock() const
{ {
SharedPtr<T> other; return SharedPtr<T>(m_Ptr, m_Ref);
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;
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1392,17 +1387,15 @@ public:
{ {
if (m_Ptr != NULL) if (m_Ptr != NULL)
{ {
*m_RefCountRefCount -= 1; --(m_Ref->mSoft);
if (*m_RefCountRefCount == 0) if (m_Ref->mSoft == 0)
{ {
delete m_RefCount; delete m_Ref;
delete m_RefCountRefCount;
} }
m_Ptr = NULL; m_Ptr = NULL;
m_RefCount = NULL; m_Ref = NULL;
m_RefCountRefCount = NULL;
} }
} }
@ -1412,9 +1405,9 @@ public:
/// \return Number of references /// \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; 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 /// @cond DEV
/// Used internally to get and manipulate the underlying type of variables - retrieved from cppreference.com /// Used internally to get and manipulate the underlying type of variables - retrieved from cppreference.com
@ -1650,13 +1720,13 @@ template<class T> struct remove_const<const T>
template<class T> struct remove_volatile {typedef T type;}; template<class T> struct remove_volatile {typedef T type;};
template<class T> struct remove_volatile<volatile T> {typedef T type;}; template<class T> struct remove_volatile<volatile T> {typedef T type;};
template<class T> struct remove_cv {typedef typename remove_volatile<typename remove_const<T>::type>::type type;}; template<class T> struct remove_cv {typedef typename remove_volatile<typename remove_const<T>::type>::type type;};
template<class T> struct is_pointer_helper {static const bool value = false;}; template<class T> struct is_pointer_helper {static constexpr bool value = false;};
template<class T> struct is_pointer_helper<T*> {static const bool value = true;}; template<class T> struct is_pointer_helper<T*> {static constexpr bool value = true;};
template<class T> struct is_pointer_helper<SharedPtr<T> > {static const bool value = true;}; template<class T> struct is_pointer_helper<SharedPtr<T> > {static constexpr bool value = true;};
template<class T> struct is_pointer_helper<WeakPtr<T> > {static const bool value = true;}; template<class T> struct is_pointer_helper<WeakPtr<T> > {static constexpr bool value = true;};
template<class T> struct is_pointer : is_pointer_helper<typename remove_cv<T>::type> {}; template<class T> struct is_pointer : is_pointer_helper<typename remove_cv<T>::type> {};
template<class T> struct is_reference {static const bool value = false;}; template<class T> struct is_reference {static constexpr bool value = false;};
template<class T> struct is_reference<T&> {static const bool value = true;}; template<class T> struct is_reference<T&> {static constexpr bool value = true;};
/// @endcond /// @endcond
} }