Equalizer  1.2.1
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 CO_REFERENCED_DEBUG
00028 #ifdef CO_REFERENCED_DEBUG
00029 #  define CO_REFERENCED_ARGS const void* holder
00030 #  define CO_REFERENCED_PARAM (const void*)(this)
00031 #else
00032 #  define CO_REFERENCED_ARGS
00033 #  define CO_REFERENCED_PARAM
00034 #endif
00035 
00036 namespace co
00037 {
00038 namespace base
00039 {
00045     template< class T > class RefPtr 
00046     {
00047         typedef T* RefPtr::*bool_t;
00048 
00049     public:
00051         RefPtr()                     : _ptr( 0 )         {}
00052 
00054         RefPtr( T* const ptr )       : _ptr( ptr )       { _ref(); }
00055 
00057         RefPtr( const RefPtr& from ) : _ptr( from._ptr ) { _ref(); }
00058 
00063         template< class O > RefPtr( RefPtr< O > from )
00064                 : _ptr( from.get( )) { _ref(); }
00065 
00067         ~RefPtr() { _unref(); _ptr = 0; }
00068 
00070         RefPtr& operator = ( const RefPtr& rhs )
00071             {
00072                 if( _ptr == rhs._ptr )
00073                     return *this;
00074 
00075                 T* tmp = _ptr;
00076                 _ptr = rhs._ptr;
00077                 _ref();
00078                 if( tmp ) tmp->unref( CO_REFERENCED_PARAM );
00079                 return *this;
00080             }
00081 
00083         RefPtr& operator = ( T* ptr )
00084             {
00085                 if( _ptr == ptr )
00086                     return *this;
00087 
00088                 T* tmp = _ptr;
00089                 _ptr = ptr;
00090                 _ref();
00091                 if( tmp ) tmp->unref( CO_REFERENCED_PARAM );
00092                 return *this;
00093             }
00094 
00099         bool operator == ( const RefPtr& rhs ) const 
00100             { return ( _ptr == rhs._ptr ); }
00101 
00106         bool operator != ( const RefPtr& rhs ) const
00107             { return ( _ptr != rhs._ptr ); }
00108 
00113         operator bool_t() const { return _ptr == 0 ? 0 : &RefPtr::_ptr; }
00114 
00119         bool operator < ( const RefPtr& rhs ) const
00120             { return ( _ptr < rhs._ptr ); }
00121 
00126         bool operator > ( const RefPtr& rhs ) const
00127             { return ( _ptr > rhs._ptr ); }
00128 
00130         bool operator ! () const               { return ( _ptr==0 ); }
00131 
00136         bool operator == ( const T* ptr ) const { return ( _ptr == ptr ); }
00137 
00142         bool operator != ( const T* ptr ) const { return ( _ptr != ptr ); }
00143 
00145         T*       operator->()       
00146             { EQASSERTINFO( _ptr, typeid(*this).name( )); return _ptr; }
00148         const T* operator->() const
00149             { EQASSERTINFO( _ptr, typeid(*this).name( )); return _ptr; }
00151         T&       operator*()        
00152             { EQASSERTINFO( _ptr, typeid(*this).name( )); return *_ptr; }
00154         const T& operator*() const  
00155             { EQASSERTINFO( _ptr, typeid(*this).name( )); return *_ptr; }
00156 
00158         T*       get()                { return _ptr; }
00160         const T* get() const          { return _ptr; }
00161 
00163         bool isValid() const { return ( _ptr != 0 ); }
00164         
00165     private:
00166         T* _ptr;
00167 
00169         void _ref()   { if(_ptr) _ptr->ref( CO_REFERENCED_PARAM ); }
00170 
00172         void _unref() 
00173         {
00174             if(_ptr)
00175             {
00176 #ifndef NDEBUG
00177                 const bool abondon = (_ptr->getRefCount() == 1);
00178                 _ptr->unref( CO_REFERENCED_PARAM );
00179                 if( abondon ) 
00180                     _ptr = 0;
00181 #else
00182                 _ptr->unref( CO_REFERENCED_PARAM );
00183 #endif
00184             }
00185         }
00186     };
00187 
00189     template< class T >
00190     inline std::ostream& operator << ( std::ostream& os, const RefPtr<T>& rp )
00191     {
00192         const T* p = rp.get();
00193         if( p )
00194         {
00195             os << disableFlush << "RP<" << *p << ">";
00196 #ifdef CO_REFERENCED_DEBUG
00197             os << std::endl;
00198             p->printHolders( os );
00199 #endif
00200             os << enableFlush;
00201         }
00202         else
00203             os << "RP< NULL >";
00204 
00205         return os;
00206     }
00207 
00208     template< class T > inline std::string className( const RefPtr<T>& rp )
00209     { return className( rp.get( )); }
00210 }
00211 
00212 }
00213 #endif //COBASE_REFPTR_H
Generated on Fri Jun 8 2012 15:44:32 for Equalizer 1.2.1 by  doxygen 1.8.0