#ifndef SHARED_PTR_H_
#define SHARED_PTR_H_
#ifndef NULL
#define NULL 0
#endif
namespace util
{
template <class T>
class shared_ptr;
template <class T>
class shared_data
{
private:
friend class shared_ptr<T>;
explicit shared_data(T *pT): _M_ptr(pT)
{
_M_nCount = 1;
}
~shared_data()
{
delete _M_ptr;
}
void operator++()
{
++_M_nCount;
}
void operator--()
{
--_M_nCount;
if (_M_nCount == 0)
{
delete this;
}
}
T &operator *()const
{
return *_M_ptr;
}
T *operator->()const
{
return _M_ptr;
}
bool operator == (T *pT)const
{
return _M_ptr == pT;
}
T *get()
{
return _M_ptr;
}
int use_count()
{
return _M_nCount;
}
private:
T *_M_ptr;
unsigned int _M_nCount;
};
template <class T>
class shared_ptr
{
typedef shared_data<T> element;
public:
explicit shared_ptr(T *pT): _M_pD(NULL)
{
_M_pD = new element(pT);
}
explicit shared_ptr(): _M_pD(NULL)
{
}
// copy constructor
shared_ptr(const shared_ptr < T > &rT)
{
_M_pD = rT.get_element();
if (_M_pD != NULL)
{
++(*_M_pD);
}
}
~shared_ptr()
{
if (_M_pD != NULL)
{
--(*_M_pD);
}
}
// assignment operator
shared_ptr < T > &operator = (const shared_ptr < T > &rT)
{
if (_M_pD != NULL)
{
--(*_M_pD);
}
_M_pD = rT.get_element();
if (_M_pD != NULL)
{
++(*_M_pD);
}
return *this;
}
// assignment operator
shared_ptr < T > &operator = (shared_ptr < T > &rT)
{
if (_M_pD != NULL)
{
--(*_M_pD);
}
_M_pD = rT.get_element();
if (_M_pD != NULL)
{
++(*_M_pD);
}
return *this;
}
T &operator *()const
{
return _M_pD->operator *();
}
T *operator->()const
{
return _M_pD->operator->();
}
bool operator == (shared_ptr < T > &rT)const
{
return rT.get_element() == _M_pD;
}
bool operator == (T *pT)const
{
if (_M_pD == NULL)
{
return pT == NULL;
}
return *_M_pD == pT;
}
T *get()
{
if (_M_pD == NULL)
{
return NULL;
}
else
{
return _M_pD->get();
}
}
void release()
{
if (_M_pD != NULL)
{
--(*_M_pD);
_M_pD = NULL;
}
}
void reset(T *pT)
{
if (_M_pD != NULL)
{
--(*_M_pD);
_M_pD = NULL;
}
_M_pD = new element(pT);
}
private:
element *get_element()const
{
return _M_pD;
}
element *_M_pD;
};
}
#endif