/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #ifndef __NWEAK_PTR__ #define __NWEAK_PTR__ #include "memory/nshared_ptr.h" namespace GS { /*! @short Weak pointer to a reference counted object. @author Emmanuel Julien (ejulien@gsworks.fr) */ template class WeakPtr { private: T *rc_o; WeakRef *wref; public: T *c_ptr() const { return wref && wref->IsValid() ? rc_o : 0; } bool IsValid() const { return wref && wref->IsValid() ? true : false; } bool IsNull() const { return !IsValid(); } /// Lock pointed object to a strong pointer. bool Lock(SharedPtr &p) { if (IsNull()) return false; p = rc_o; return true; } SharedPtr Lock() const { return SharedPtr (IsValid() ? rc_o : 0); } void Init() { if (!rc_o) wref = 0; else { wref = rc_o->GetWeakRef(); wref->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 WeakPtr &p) const { return rc_o == p.rc_o; } inline bool operator != (const WeakPtr &p) const { return rc_o != p.rc_o; } WeakPtr &operator = (const WeakPtr &p) { if (rc_o != p.rc_o) { WeakRef *old_wref = wref; rc_o = p.rc_o; Init(); if (old_wref) old_wref->RemoveRef(); } return *this; } inline T *operator -> () const { return rc_o; } inline T &operator * () const { return *rc_o; } WeakPtr(T *p = 0) : rc_o(p) { Init(); } WeakPtr(const WeakPtr &p) : rc_o(p.rc_o) { Init(); } WeakPtr(const SharedPtr &p) : rc_o(p.c_ptr()) { Init(); } ~WeakPtr() { if (wref) wref->RemoveRef(); } }; } // GS #endif // __NWEAK_PTR__