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