Equalizer 1.0

refPtr.h

00001 
00002 /* Copyright (c) 2005-2011, Stefan Eilemann <eile@equalizergraphics.com> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1q as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #ifndef COBASE_REFPTR_H
00019 #define COBASE_REFPTR_H
00020 
00021 #include <co/base/debug.h>
00022 
00023 #include <iostream>
00024 #include <typeinfo>
00025 #include <stdlib.h>
00026 
00027 //#define EQ_REFERENCED_DEBUG
00028 #ifdef EQ_REFERENCED_DEBUG
00029 #  define EQ_REFERENCED_ARGS const void* holder
00030 #  define EQ_REFERENCED_PARAM (const void*)(this)
00031 #else
00032 #  define EQ_REFERENCED_ARGS
00033 #  define EQ_REFERENCED_PARAM
00034 #endif
00035 
00036 namespace co
00037 {
00038 namespace base
00039 {
00045     template<class T> class RefPtr 
00046     {
00047     public:
00049         RefPtr()                     : _ptr( 0 )         {}
00050 
00052         RefPtr( T* const ptr )       : _ptr( ptr )       { _ref(); }
00053 
00055         RefPtr( const RefPtr& from ) : _ptr( from._ptr ) { _ref(); }
00056 
00061         template< class O > RefPtr( RefPtr< O > from )
00062                 : _ptr( from.get( )) { _ref(); }
00063 
00065         ~RefPtr() { _unref(); _ptr = 0; }
00066 
00068         RefPtr& operator = ( const RefPtr& rhs )
00069             {
00070                 if( _ptr == rhs._ptr )
00071                     return *this;
00072 
00073                 T* tmp = _ptr;
00074                 _ptr = rhs._ptr;
00075                 _ref();
00076                 if( tmp ) tmp->unref( EQ_REFERENCED_PARAM );
00077                 return *this;
00078             }
00079 
00081         RefPtr& operator = ( T* ptr )
00082             {
00083                 if( _ptr == ptr )
00084                     return *this;
00085 
00086                 T* tmp = _ptr;
00087                 _ptr = ptr;
00088                 _ref();
00089                 if( tmp ) tmp->unref( EQ_REFERENCED_PARAM );
00090                 return *this;
00091             }
00092 
00097         bool operator == ( const RefPtr& rhs ) const 
00098             { return ( _ptr == rhs._ptr ); }
00099 
00104         bool operator != ( const RefPtr& rhs ) const
00105             { return ( _ptr != rhs._ptr ); }
00106 
00111         bool operator < ( const RefPtr& rhs ) const
00112             { return ( _ptr < rhs._ptr ); }
00113 
00118         bool operator > ( const RefPtr& rhs ) const
00119             { return ( _ptr > rhs._ptr ); }
00120 
00122         bool operator ! () const               { return ( _ptr==0 ); }
00123 
00128         bool operator == ( const T* ptr ) const { return ( _ptr == ptr ); }
00129 
00134         bool operator != ( const T* ptr ) const { return ( _ptr != ptr ); }
00135 
00137         T*       operator->()       
00138             { EQASSERTINFO( _ptr, typeid(*this).name( )); return _ptr; }
00140         const T* operator->() const
00141             { EQASSERTINFO( _ptr, typeid(*this).name( )); return _ptr; }
00143         T&       operator*()        
00144             { EQASSERTINFO( _ptr, typeid(*this).name( )); return *_ptr; }
00146         const T& operator*() const  
00147             { EQASSERTINFO( _ptr, typeid(*this).name( )); return *_ptr; }
00148 
00150         T*       get()                { return _ptr; }
00152         const T* get() const          { return _ptr; }
00153 
00155         bool isValid() const { return ( _ptr != 0 ); }
00156         
00157     private:
00158         T* _ptr;
00159 
00161         void _ref()   { if(_ptr) _ptr->ref( EQ_REFERENCED_PARAM ); }
00162 
00164         void _unref() 
00165         {
00166             if(_ptr)
00167             {
00168 #ifndef NDEBUG
00169                 const bool abondon = (_ptr->getRefCount() == 1);
00170                 _ptr->unref( EQ_REFERENCED_PARAM );
00171                 if( abondon ) 
00172                     _ptr = 0;
00173 #else
00174                 _ptr->unref( EQ_REFERENCED_PARAM );
00175 #endif
00176             }
00177         }
00178     };
00179 
00181     template< class T >
00182     inline std::ostream& operator << ( std::ostream& os, const RefPtr<T>& rp )
00183     {
00184         const T* p = rp.get();
00185         if( p )
00186         {
00187             os << disableFlush << "RP<" << *p << ">";
00188 #ifdef EQ_REFERENCED_DEBUG
00189             os << std::endl;
00190             p->printHolders( os );
00191 #endif
00192             os << enableFlush;
00193         }
00194         else
00195             os << "RP< NULL >";
00196 
00197         return os;
00198     }
00199 
00200     template< class T > inline std::string className( const RefPtr<T>& rp )
00201     { return className( rp.get( )); }
00202 }
00203 
00204 }
00205 #endif //COBASE_REFPTR_H
Generated on Sun May 8 2011 19:11:07 for Equalizer 1.0 by  doxygen 1.7.3