// This code is in the public domain -- castanyo@yahoo.es #ifndef NV_CORE_PTR_H #define NV_CORE_PTR_H #include #include #include // NULL namespace nv { /** Simple auto pointer template class. * * This is very similar to the standard auto_ptr class, but with some * additional limitations to make its use less error prone: * - Copy constructor and assignment operator are disabled. * - reset method is removed. * * The semantics of the standard auto_ptr are not clear and change depending * on the std implementation. For a discussion of the problems of auto_ptr read: * http://www.awprofessional.com/content/images/020163371X/autoptrupdate\auto_ptr_update.html */ template class AutoPtr { NV_FORBID_COPY(AutoPtr); NV_FORBID_HEAPALLOC(); public: /// Ctor. AutoPtr(T * p = NULL) : m_ptr(p) { } template AutoPtr(Q * p) : m_ptr(static_cast(p)) { } /** Dtor. Deletes owned pointer. */ ~AutoPtr() { delete m_ptr; m_ptr = NULL; } /** Delete owned pointer and assign new one. */ void operator=( T * p ) { if (p != m_ptr) { delete m_ptr; m_ptr = p; } } template void operator=( Q * p ) { if (p != m_ptr) { delete m_ptr; m_ptr = static_cast(p); } } /** Member access. */ T * operator -> () const { nvDebugCheck(m_ptr != NULL); return m_ptr; } /** Get reference. */ T & operator*() const { nvDebugCheck(m_ptr != NULL); return *m_ptr; } /** Get pointer. */ T * ptr() const { return m_ptr; } /** Relinquish ownership of the underlying pointer and returns that pointer. */ T * release() { T * tmp = m_ptr; m_ptr = NULL; return tmp; } /** Const pointer equal comparation. */ friend bool operator == (const AutoPtr & ap, const T * const p) { return (ap.ptr() == p); } /** Const pointer nequal comparation. */ friend bool operator != (const AutoPtr & ap, const T * const p) { return (ap.ptr() != p); } /** Const pointer equal comparation. */ friend bool operator == (const T * const p, const AutoPtr & ap) { return (ap.ptr() == p); } /** Const pointer nequal comparation. */ friend bool operator != (const T * const p, const AutoPtr & ap) { return (ap.ptr() != p); } private: T * m_ptr; }; /// Smart pointer template class. template class SmartPtr { public: // BaseClass must implement addRef() and release(). typedef SmartPtr ThisType; /// Default ctor. SmartPtr() : m_ptr(NULL) { } /** Other type assignment. */ template SmartPtr( const SmartPtr & tc ) { m_ptr = static_cast( tc.ptr() ); if( m_ptr ) { m_ptr->addRef(); } } /** Copy ctor. */ SmartPtr( const ThisType & bc ) { m_ptr = bc.ptr(); if( m_ptr ) { m_ptr->addRef(); } } /** Copy cast ctor. SmartPtr(NULL) is valid. */ explicit SmartPtr( BaseClass * bc ) { m_ptr = bc; if( m_ptr ) { m_ptr->addRef(); } } /** Dtor. */ ~SmartPtr() { set(NULL); } /** @name Accessors: */ //@{ /** -> operator. */ BaseClass * operator -> () const { nvCheck( m_ptr != NULL ); return m_ptr; } /** * operator. */ BaseClass & operator*() const { nvCheck( m_ptr != NULL ); return *m_ptr; } /** Get pointer. */ BaseClass * ptr() const { return m_ptr; } //@} /** @name Mutators: */ //@{ /** Other type assignment. */ template void operator = ( const SmartPtr & tc ) { set( static_cast(tc.ptr()) ); } /** This type assignment. */ void operator = ( const ThisType & bc ) { set( bc.ptr() ); } /** Pointer assignment. */ void operator = ( BaseClass * bc ) { set( bc ); } //@} /** @name Comparators: */ //@{ /** Other type equal comparation. */ template bool operator == ( const SmartPtr & other ) const { return m_ptr == other.ptr(); } /** This type equal comparation. */ bool operator == ( const ThisType & bc ) const { return m_ptr == bc.ptr(); } /** Const pointer equal comparation. */ bool operator == ( const BaseClass * const bc ) const { return m_ptr == bc; } /** Other type not equal comparation. */ template bool operator != ( const SmartPtr & other ) const { return m_ptr != other.ptr(); } /** Other type not equal comparation. */ bool operator != ( const ThisType & bc ) const { return m_ptr != bc.ptr(); } /** Const pointer not equal comparation. */ bool operator != (const BaseClass * const bc) const { return m_ptr != bc; } /** This type lower than comparation. */ bool operator < (const ThisType & p) const { return m_ptr < p.ptr(); } //@} private: /** Set this pointer. */ void set( BaseClass * p ) { if( m_ptr != p ) { if( m_ptr ) m_ptr->release(); if( p ) p->addRef(); m_ptr = p; } } private: BaseClass * m_ptr; }; } // nv namespace #endif // NV_CORE_PTR_H