Equalizer 1.0
|
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