#ifndef BU_SPTR_H #define BU_SPTR_H #include <stdint.h> #include <stdio.h> namespace Bu { template<typename T> class SPtr; template< typename Tb, typename Ta > SPtr<Tb> SPtrCast( SPtr<Ta> src ); template<typename T> class SPtr { template<typename Tb, typename Ta> friend SPtr<Tb> SPtrCast( SPtr<Ta> pt ); public: SPtr() : pRefCnt( NULL ), pData( NULL ) { } ~SPtr() { decCount(); } SPtr( const SPtr<T> &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; } } /** * Get the number of references to this pointer. *@returns (int32_t) The number of references to this pointer. */ int32_t count() const { return *pRefCnt; } /** * Pointer access operator. *@returns (const T *) */ const T *operator->() const { return pData; } /** * Dereference operator. *@returns (const T &) The value at the end of the pointer. */ const T &operator*() const { return *pData; } /** * Pointer access operator. *@returns (T *) */ T *operator->() { return pData; } /** * Dereference operator. *@returns (T &) The value at the end of the pointer. */ T &operator*() { return *pData; } /** * Assignment operator. *@param src (const SPtr<T> &) */ SPtr<T> operator=( const SPtr<T> &src ) { decCount(); pRefCnt = src.pRefCnt; pData = src.pData; if( pRefCnt ) (*pRefCnt) += 1; return *this; } /** * Assignment operator. *@param src (const SPtr<T> &) */ const SPtr<T> operator=( const SPtr<T> &src ) const { decCount(); pRefCnt = src.pRefCnt; pData = src.pData; if( pRefCnt ) (*pRefCnt) += 1; return *this; } /** * Equals comparison operator. *@param src (const SPtr<T> &) The SPtr to compare to. *@returns (bool) Are the equal? */ bool operator==( const SPtr<T> &src ) const { return pData == src.pData; } /** * Equals comparison operator. *@param src (const T *) The pointer to compare to. *@returns (bool) Are the equal? */ bool operator==( const T *src ) const { return pData == src; } /** * Boolean cast operator. Do we have a pointer? */ operator bool() const { return pRefCnt != NULL; } /** * Do we have a pointer? *@returns (bool) Do we have a pointer? */ 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<Tb> SPtrCast( SPtr<Ta> src ) { SPtr<Tb> ret; ret.pRefCnt = src.pRefCnt; ret.pData = dynamic_cast<Tb *>(src.pData); if( ret.pRefCnt ) (*(ret.pRefCnt)) += 1; return ret; } } #endif