Lunchbox
1.4.0
|
00001 00002 /* Copyright (c) 2005-2012, 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 LUNCHBOX_REFPTR_H 00019 #define LUNCHBOX_REFPTR_H 00020 00021 #include <lunchbox/debug.h> 00022 00023 #include <iostream> 00024 #include <stdlib.h> 00025 00026 namespace lunchbox 00027 { 00033 template< class T > class RefPtr 00034 { 00035 typedef T* RefPtr::*bool_t; 00036 00037 public: 00039 RefPtr() : _ptr( 0 ) {} 00040 00042 RefPtr( T* const ptr ) : _ptr( ptr ) { _ref(); } 00043 00045 RefPtr( const RefPtr& from ) : _ptr( from._ptr ) { _ref(); } 00046 00051 template< class O > RefPtr( RefPtr< O > from ) 00052 : _ptr( from.get( )) { _ref(); } 00053 00055 ~RefPtr() { _unref(); _ptr = 0; } 00056 00058 RefPtr& operator = ( const RefPtr& rhs ) 00059 { 00060 if( _ptr == rhs._ptr ) 00061 return *this; 00062 00063 T* tmp = _ptr; 00064 _ptr = rhs._ptr; 00065 _ref(); 00066 if( tmp ) tmp->unref( this ); 00067 return *this; 00068 } 00069 00071 RefPtr& operator = ( T* ptr ) 00072 { 00073 if( _ptr == ptr ) 00074 return *this; 00075 00076 T* tmp = _ptr; 00077 _ptr = ptr; 00078 _ref(); 00079 if( tmp ) tmp->unref( this ); 00080 return *this; 00081 } 00082 00087 bool operator == ( const RefPtr& rhs ) const 00088 { return ( _ptr == rhs._ptr ); } 00089 00094 bool operator != ( const RefPtr& rhs ) const 00095 { return ( _ptr != rhs._ptr ); } 00096 00101 operator bool_t() const { return _ptr == 0 ? 0 : &RefPtr::_ptr; } 00102 00107 bool operator < ( const RefPtr& rhs ) const 00108 { return ( _ptr < rhs._ptr ); } 00109 00114 bool operator > ( const RefPtr& rhs ) const 00115 { return ( _ptr > rhs._ptr ); } 00116 00118 bool operator ! () const { return ( _ptr==0 ); } 00119 00124 bool operator == ( const T* ptr ) const { return ( _ptr == ptr ); } 00125 00130 bool operator != ( const T* ptr ) const { return ( _ptr != ptr ); } 00131 00133 T* operator->() 00134 { LBASSERTINFO( _ptr, className( this )); return _ptr; } 00136 const T* operator->() const 00137 { LBASSERTINFO( _ptr, className( this )); return _ptr; } 00139 T& operator*() 00140 { LBASSERTINFO( _ptr, className( this )); return *_ptr; } 00142 const T& operator*() const 00143 { LBASSERTINFO( _ptr, className( this )); return *_ptr; } 00144 00146 T* get() { return _ptr; } 00148 const T* get() const { return _ptr; } 00149 00151 bool isValid() const { return ( _ptr != 0 ); } 00152 00153 private: 00154 T* _ptr; 00155 00157 void _ref() { if(_ptr) _ptr->ref( this ); } 00158 00160 void _unref() 00161 { 00162 if(_ptr) 00163 { 00164 #ifndef NDEBUG 00165 const bool abondon = (_ptr->getRefCount() == 1); 00166 _ptr->unref( this ); 00167 if( abondon ) 00168 _ptr = 0; 00169 #else 00170 _ptr->unref( this ); 00171 #endif 00172 } 00173 } 00174 }; 00175 00177 template< class T > 00178 inline std::ostream& operator << ( std::ostream& os, RefPtr< T > rp ) 00179 { 00180 const T* p = rp.get(); 00181 if( !p ) 00182 return os << "RP[ 0:NULL ]"; 00183 00184 os << disableFlush << "RP[" << p->getRefCount() << ":" << *p << "]"; 00185 p->printHolders( os ); 00186 return os << enableFlush; 00187 } 00188 00189 template< class T > inline std::string className( const RefPtr<T>& rp ) 00190 { return className( rp.get( )); } 00191 } 00192 00193 #ifdef LUNCHBOX_USE_BOOST 00194 # include <boost/serialization/split_free.hpp> 00195 00196 namespace boost 00197 { 00198 namespace serialization 00199 { 00200 00201 template< class Archive, class T > 00202 inline void save( Archive& ar, const lunchbox::RefPtr< T >& t, 00203 const unsigned int /*version*/ ) 00204 { 00205 const T* ptr = t.get(); 00206 ar << ptr; 00207 } 00208 00209 template< class Archive, class T > 00210 inline void load( Archive& ar, lunchbox::RefPtr< T >& t, 00211 const unsigned int /*version*/ ) 00212 { 00213 T* obj; 00214 ar >> obj; 00215 t = obj; 00216 } 00217 00218 template< class Archive, class T > 00219 inline void serialize( Archive& ar, lunchbox::RefPtr< T >& t, 00220 const unsigned int version ) 00221 { 00222 boost::serialization::split_free( ar, t, version ); 00223 } 00224 00225 } 00226 } 00227 00228 #endif // LUNCHBOX_USE_BOOST 00229 #endif //LUNCHBOX_REFPTR_H