123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- #pragma once
- #include <assert.h>
- #include <winpr/interlocked.h>
- template<class T> class CSmartPointer
- {
- public:
- CSmartPointer():m_pPoint(NULL),m_pnReference(NULL){}
- CSmartPointer(T *pPoint) :m_pPoint(pPoint), m_pnReference(NULL){}
- CSmartPointer(const CSmartPointer<T> &Point)
- :m_pPoint(Point.m_pPoint),m_pnReference(Point.m_pnReference)
- {
- if(m_pnReference)
- InterlockedIncrement(m_pnReference);
- }
- ~CSmartPointer()
- {
- Clear();
- }
- CSmartPointer<T> &operator=(T *pPoint)
- {
- if(pPoint!=m_pPoint)
- {
- Clear();
- m_pPoint=pPoint;
- }
- return *this;
- }
- CSmartPointer<T> &operator =(const CSmartPointer<T> &Point)
- {
- if(Point.m_pPoint!=m_pPoint)
- {
- Clear();
- m_pPoint=Point.m_pPoint;
- m_pnReference=Point.m_pnReference;
- if(m_pnReference)
- InterlockedIncrement(m_pnReference);
- }
- return *this;
- }
- bool operator ==(T *pPoint)const
- {
- return m_pPoint==pPoint;
- }
- bool operator ==(const CSmartPointer<T> &Point)const
- {
- return m_pPoint==Point.m_pPoint;
- }
- bool operator !=(T *pPoint)const
- {
- return m_pPoint!=pPoint;
- }
- bool operator !=(const CSmartPointer<T> &Point)const
- {
- return m_pPoint!=Point.m_pPoint;
- }
-
- void Attach(T *pPoint)
- {
- Attach(pPoint, NULL);
- }
- void Attach(T *pPoint,LONG *pnReference)
- {
- if(m_pPoint!=pPoint)
- {
- Clear();
- m_pPoint=pPoint;
- m_pnReference=pnReference;
- if(pnReference!=NULL && *pnReference>0)
- InterlockedIncrement(m_pnReference);
- else
- m_pnReference = new LONG(1);
- }
- }
- T *Detach()
- {
- if(m_pnReference)
- {
- if (*m_pnReference != 1)
- {
- assert(false);
- return NULL;
- }
- else
- {
- delete m_pnReference;
- m_pnReference=NULL;
- }
- }
- T *pRet=m_pPoint;
- m_pPoint=NULL;
- return pRet;
- }
- void AddRef()
- {
- if (m_pnReference != NULL && *m_pnReference > 0)
- InterlockedIncrement(m_pnReference);
- }
- void SubRef()
- {
- if (m_pnReference)
- {
- LONG nRef = InterlockedDecrement(m_pnReference);
- if (nRef == 0)
- {
- delete m_pPoint;
- delete m_pnReference;
- }
- m_pnReference = NULL;
- }
- }
- void Clear()
- {
- if(m_pnReference)
- {
- LONG nRef=InterlockedDecrement(m_pnReference);
- if(nRef==0)
- {
- delete m_pPoint;
- delete m_pnReference;
- }
- m_pnReference=NULL;
- }
- m_pPoint=NULL;
- }
- T *operator ->() const
- {
- return m_pPoint;
- }
- /*operator T*() const
- {
- return m_pPoint;
- }*/
- T* GetRawPointer() const
- {
- return m_pPoint;
- }
- #if 1
- template<class P>
- CSmartPointer<P> ConvertCase()
- {
- CSmartPointer<P> pRet;
- try
- {
- if (m_pnReference != NULL)
- pRet.Attach(dynamic_cast<P *>(m_pPoint),m_pnReference);
- else
- pRet = dynamic_cast<P *>(m_pPoint); // if not managed originally, ret pointer should not be managed too!!!
- }
- catch(...)
- {
- return NULL;
- }
- return pRet;
- }
- #else
- template<class P>
- CSmartPointer<P> ConvertCase() // do this a little bit brute-force
- {
- CSmartPointer<P> pRet;
- P **pp = (P**)((char*)(&pRet) + (size_t)(&((CSmartPointer*)0)->m_pPoint));
- *pp = dynamic_cast<P *>(m_pPoint);
- LONG **pr = (LONG**)((char*)(&pRet) + (size_t)(&((CSmartPointer*)0)->m_pnReference));
- *pr = m_pnReference;
- if(m_pnReference)
- InterlockedIncrement(m_pnReference);
- return pRet;
- }
- #endif
- private:
- T *m_pPoint;
- LONG *m_pnReference;
- };
|