first commit
This commit is contained in:
150
include/platform/memory/nshared_ptr.h
Normal file
150
include/platform/memory/nshared_ptr.h
Normal file
@ -0,0 +1,150 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NSHARED_PTR__
|
||||
#define __NSHARED_PTR__
|
||||
|
||||
|
||||
#include "thread/atomic_value.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
/// Weak reference to a shared object.
|
||||
class WeakRef
|
||||
{
|
||||
friend class SharedObject;
|
||||
|
||||
bool is_valid;
|
||||
Threading::Atomic32 refc;
|
||||
|
||||
WeakRef() : is_valid(true) {}
|
||||
|
||||
public:
|
||||
|
||||
bool IsValid() const { return is_valid; }
|
||||
|
||||
int GetRefCount() const { return refc.Get(); }
|
||||
|
||||
void AddRef() { refc.Inc(); }
|
||||
void RemoveRef()
|
||||
{
|
||||
if ((refc.Dec() == 0) && !is_valid)
|
||||
delete this;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
@short Reference counted object.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
class SharedObject
|
||||
{
|
||||
Threading::Atomic32 refc;
|
||||
WeakRef *weak_ref;
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~SharedObject()
|
||||
{
|
||||
if (weak_ref)
|
||||
{
|
||||
if (weak_ref->refc.Get() == 0)
|
||||
delete weak_ref;
|
||||
else
|
||||
weak_ref->is_valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
WeakRef *GetWeakRef()
|
||||
{
|
||||
if (!weak_ref)
|
||||
weak_ref = new WeakRef; // TODO have a specialized, fixed pool allocator for these.
|
||||
return weak_ref;
|
||||
}
|
||||
|
||||
int GetRefCount() const { return refc.Get(); }
|
||||
|
||||
void AddRef() { refc.Inc(); }
|
||||
void RemoveRef()
|
||||
{
|
||||
if (refc.Dec() == 0)
|
||||
{
|
||||
if (weak_ref)
|
||||
weak_ref->is_valid = false;
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
SharedObject() : weak_ref(0) {}
|
||||
};
|
||||
|
||||
/*!
|
||||
@short Strong smart pointer to a reference counted object.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
template <class T> class SharedPtr
|
||||
{
|
||||
T *rc_o;
|
||||
|
||||
public:
|
||||
|
||||
inline operator T *() const { return rc_o; }
|
||||
inline T *c_ptr() const { return rc_o; }
|
||||
|
||||
inline bool IsNull() const { return rc_o ? false : true; }
|
||||
inline bool IsValid() const { return rc_o ? true : false; }
|
||||
|
||||
void Init()
|
||||
{
|
||||
if (rc_o)
|
||||
rc_o->AddRef();
|
||||
}
|
||||
|
||||
inline bool operator == (const T *p) const { return rc_o == p; }
|
||||
inline bool operator != (const T *p) const { return rc_o != p; }
|
||||
inline bool operator == (T *p) const { return rc_o == p; }
|
||||
inline bool operator != (T *p) const { return rc_o != p; }
|
||||
|
||||
inline bool operator == (const SharedPtr &p) const { return rc_o == p.rc_o; }
|
||||
inline bool operator != (const SharedPtr &p) const { return rc_o != p.rc_o; }
|
||||
|
||||
T *operator = (T *p)
|
||||
{
|
||||
if (rc_o != p)
|
||||
{
|
||||
if (rc_o)
|
||||
rc_o->RemoveRef();
|
||||
rc_o = p;
|
||||
Init();
|
||||
}
|
||||
return p;
|
||||
}
|
||||
SharedPtr <T> &operator = (const SharedPtr &p)
|
||||
{
|
||||
*this = p.c_ptr();
|
||||
return *this;
|
||||
}
|
||||
inline T *operator -> () const { return rc_o; }
|
||||
inline T &operator * () const { return *rc_o; }
|
||||
|
||||
explicit SharedPtr(T *p) : rc_o(p) { Init(); }
|
||||
SharedPtr(const SharedPtr &p) : rc_o(p.rc_o) { Init(); }
|
||||
SharedPtr() : rc_o(0) {}
|
||||
|
||||
~SharedPtr()
|
||||
{
|
||||
if (rc_o)
|
||||
rc_o->RemoveRef();
|
||||
}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NSHARED_PTR__
|
||||
Reference in New Issue
Block a user