#ifndef SPTR_H #define SPTR_H #include #include namespace Bu { template class SPtr; template< typename Tb, typename Ta > SPtr SPtrCast( SPtr src ); template class SPtr { template friend SPtr SPtrCast( SPtr pt ); public: SPtr() : pRefCnt( NULL ), pData( NULL ) { } ~SPtr() { decCount(); } SPtr( const SPtr &src ) : pRefCnt( src.pRefCnt ), pData( src.pData ) { if( pRefCnt ) (*pRefCnt) += 1; } SPtr( T *pSrc ) : pRefCnt( NULL ), pData( pSrc ) { if( pData ) { pRefCnt = new int32_t; (*pRefCnt) = 1; } } int32_t count() const { return *pRefCnt; } const T *operator->() const { return pData; } const T &operator*() const { return *pData; } T *operator->() { return pData; } T &operator*() { return *pData; } SPtr operator=( const SPtr &src ) { decCount(); pRefCnt = src.pRefCnt; pData = src.pData; if( pRefCnt ) (*pRefCnt) += 1; return *this; } const SPtr operator=( const SPtr &src ) const { decCount(); pRefCnt = src.pRefCnt; pData = src.pData; if( pRefCnt ) (*pRefCnt) += 1; return *this; } bool operator==( const SPtr &src ) const { return pData == src.pData; } bool operator==( const T *src ) const { return pData == src; } operator bool() const { return pRefCnt != NULL; } bool isSet() const { return pRefCnt != NULL; } private: void decCount() const { if( pRefCnt ) { (*pRefCnt) -= 1; //printf("Decrementing ref-count to %d\n", *pRefCnt ); if( (*pRefCnt) == 0 ) { delete pRefCnt; delete pData; pRefCnt = NULL; pData = NULL; } } } mutable int32_t *pRefCnt; mutable T *pData; }; template< typename Tb, typename Ta > SPtr SPtrCast( SPtr src ) { SPtr ret; ret.pRefCnt = src.pRefCnt; ret.pData = dynamic_cast(src.pData); if( ret.pRefCnt ) (*(ret.pRefCnt)) += 1; return ret; } } #endif