// smartpointer.h: interface for the SmartPointer classes.
//
//////////////////////////////////////////////////////////////////////
#if !defined(SMARTPOINTER_H__BD2313DE_E4F7_49CB_BE4C_E25F030A9BA5__INCLUDED_)
#define SMARTPOINTER_H__BD2313DE_E4F7_49CB_BE4C_E25F030A9BA5__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifdef BOOL
#undef BOOL
#endif
#include <windows.h>
#include <algorithm>
#include <assert.h>
/**
* class: CScopedPtrT
* 智能指针, 不提供引用计数功能, 离开作用域自动释放指针
* 非线程安全
*/
template<class T>
class CScopedPtrT
{
public:
typedef T element_type;
explicit CScopedPtrT( T* p = NULL ): m_p( p ) // never throws
{
}
~CScopedPtrT() // never throws
{
if ( m_p )
delete m_p;
}
void reset(T * p = NULL) // never throws
{
assert( p == NULL || p != m_p ); // catch self-reset errors
this_type(p).swap(*this);
}
T& operator*() const // never throws
{
assert( m_p != NULL );
return *m_p;
}
T* operator->() const // never throws
{
assert( m_p != NULL );
return m_p;
}
T* get(void) const // never throws
{
return m_p;
}
void swap(CScopedPtrT & b) // never throws
{
T* tmp = b.m_p;
b.m_p = m_p;
m_p = tmp;
}
private:
T * m_p; // contained pointer
typedef CScopedPtrT<T> this_type;
// noncopyable
CScopedPtrT(CScopedPtrT const &);
CScopedPtrT & operator=(CScopedPtrT const &);
void operator==( CScopedPtrT const& ) const;
void operator!=( CScopedPtrT const& ) const;
};
class CShared
{
public:
CShared() : m_ref(0), m_bNoDelete(false)
{
}
CShared(const CShared&): m_ref(0), m_bNoDelete(false)
{
}
virtual ~CShared()
{
}
void _incRef()
{
#if defined(_WIN32)
assert(InterlockedExchangeAdd(&m_ref, 0) >= 0);
InterlockedIncrement(&m_ref);
#endif
}
void _decRef()
{
#if defined(_WIN32)
assert(InterlockedExchangeAdd(&m_ref, 0) > 0);
if(InterlockedDecrement(&m_ref) == 0 && !m_bNoDelete)
{
m_bNoDelete = true;
delete this;
}
#endif
}
int _getRef() const
{
#if defined(_WIN32)
return InterlockedExchangeAdd(const_cast<LONG*>(&m_ref), 0);
#endif
}
void _setNoDelete(bool b)
{
m_bNoDelete = b;
}
protected:
#if defined(_WIN32)
long m_ref;
#endif
bool m_bNoDelete;
};
/**
* class: CIntrusivePtrT
* 智能指针, 不提供引用计数功能, 需要使用者继承 CShared 类
* 非线程安全
*/
template<class T>
class CIntrusivePtrT
{
private:
typedef CIntrusivePtrT<T> this_type;
public:
typedef T element_type;
CIntrusivePtrT(): m_p( NULL )
{
}
CIntrusivePtrT( T * p, bool add_ref = true ): m_p( p )
{
if( m_p != NULL && add_ref )
this->m_p->_incRef();
}
CIntrusivePtrT( CIntrusivePtrT<T> const & rhs ) : m_p( rhs.get() )
{
if( m_p != 0 )
this->m_p->_incRef();
}
~CIntrusivePtrT()
{
if( m_p != 0 )
this->m_p->_decRef();
}
template<class U> CIntrusivePtrT & operator=(CIntrusivePtrT<U> const & rhs)
{
this_type(rhs).swap(*this);
return *this;
}
CIntrusivePtrT & operator=(CIntrusivePtrT const & rhs)
{
this_type(rhs).swap(*this);
return *this;
}
CIntrusivePtrT & operator=(T * rhs)
{
this_type(rhs).swap(*this);
return *this;
}
void reset()
{
this_type().swap( *this );
}
void reset( T * rhs )
{
this_type( rhs ).swap( *this );
}
T * get() const
{
return m_p;
}
T & operator*() const
{
assert( m_p != 0 );
return *m_p;
}
T * operator->() const
{
assert( m_p != 0 );
return m_p;
}
void swap(CIntrusivePtrT & rhs)
{
T * tmp = m_p;
m_p = rhs.m_p;
rhs.m_p = tmp;
}
private:
T * m_p; // contained pointer
};
/**
* class: CSharePtrT
* 智能指针, 提供引用计数功能
* 非线程安全
*/
template<class T>
class CSharePtrT
{
public:
typedef T element_type;
typedef T value_type;
typedef T* pointer;
CSharePtrT(): m_p(NULL), m_ref(NULL)
{
m_ref = new long();
*m_ref = 0;
}
explicit CSharePtrT( T* p ): m_p( p ), m_ref(NULL)
{
m_ref = new long();
*m_ref = 0;
if ( m_p != NULL )
InterlockedIncrement(m_ref);
}
CSharePtrT( CSharePtrT<T> & r ) : m_p( r.m_p ), m_ref( r.m_ref ) // never throws
{
InterlockedIncrement(m_ref);
}
~CSharePtrT()
{
if ( m_p != NULL )
{
if( InterlockedDecrement(m_ref) == 0 )
{
delete m_ref;
delete m_p;
}
}
}
// assignment
CSharePtrT & operator=( CSharePtrT & r ) // never throws
{
this_type(r).swap(*this);
return *this;
}
void reset(void)
{
this_type().swap(*this);
}
void reset(T* p)
{
assert(p == 0 || p != m_p); // catch self-reset errors
this_type(p).swap(*this);
}
T& operator* () const // never throws
{
assert(m_p != 0);
return *m_p;
}
T * operator-> () const // never throws
{
assert(m_p != 0);
return m_p;
}
T * get(void) const // never throws
{
return m_p;
}
bool unique(void) const // never throws
{
return use_count() == 1;
}
long use_count(void) const // never throws
{
if ( m_ref != NULL )
{
return *m_ref;
}
else
{
return 0;
}
}
void swap(CSharePtrT<T> & other) // never throws
{
std::swap(m_p, other.m_p);
std::swap(m_ref, other.m_ref);
}
private:
T* m_p; // contained pointer
long* m_ref; // reference counter
typedef CSharePtrT<T> this_type;
};
#endif // !defined(SMARTPOINTER_H__BD2313DE_E4F7_49CB_BE4C_E25F030A9BA5__INCLUDED_)