Lunchbox
1.6.0
|
00001 00002 /* Copyright (c) 2005-2012, Stefan Eilemann <eile@equalizergraphics.com> 00003 * 2012, Daniel Nachbaur <danielnachbaur@gmail.com> 00004 * 00005 * This library is free software; you can redistribute it and/or modify it under 00006 * the terms of the GNU Lesser General Public License version 2.1q as published 00007 * by the Free Software Foundation. 00008 * 00009 * This library is distributed in the hope that it will be useful, but WITHOUT 00010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00011 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00012 * details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public License 00015 * along with this library; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00017 */ 00018 00019 #ifndef LUNCHBOX_REFPTR_H 00020 #define LUNCHBOX_REFPTR_H 00021 00022 #include <lunchbox/debug.h> 00023 00024 #include <iostream> 00025 #include <stdlib.h> 00026 00027 namespace lunchbox 00028 { 00034 template< class T > class RefPtr 00035 { 00036 typedef T* RefPtr::*bool_t; 00037 00038 public: 00040 RefPtr() : _ptr( 0 ) {} 00041 00043 RefPtr( T* const ptr ) : _ptr( ptr ) { _ref(); } 00044 00046 RefPtr( const RefPtr& from ) : _ptr( from._ptr ) { _ref(); } 00047 00052 template< class O > RefPtr( RefPtr< O > from ) 00053 : _ptr( from.get( )) { _ref(); } 00054 00056 ~RefPtr() { _unref(); _ptr = 0; } 00057 00059 RefPtr& operator = ( const RefPtr& rhs ) 00060 { 00061 if( _ptr == rhs._ptr ) 00062 return *this; 00063 00064 T* tmp = _ptr; 00065 _ptr = rhs._ptr; 00066 _ref(); 00067 if( tmp ) tmp->unref( this ); 00068 return *this; 00069 } 00070 00072 RefPtr& operator = ( T* ptr ) 00073 { 00074 if( _ptr == ptr ) 00075 return *this; 00076 00077 T* tmp = _ptr; 00078 _ptr = ptr; 00079 _ref(); 00080 if( tmp ) tmp->unref( this ); 00081 return *this; 00082 } 00083 00088 bool operator == ( const RefPtr& rhs ) const 00089 { return ( _ptr == rhs._ptr ); } 00090 00095 bool operator != ( const RefPtr& rhs ) const 00096 { return ( _ptr != rhs._ptr ); } 00097 00102 operator bool_t() const { return _ptr == 0 ? 0 : &RefPtr::_ptr; } 00103 00108 bool operator < ( const RefPtr& rhs ) const 00109 { return ( _ptr < rhs._ptr ); } 00110 00115 bool operator > ( const RefPtr& rhs ) const 00116 { return ( _ptr > rhs._ptr ); } 00117 00119 bool operator ! () const { return ( _ptr==0 ); } 00120 00125 bool operator == ( const T* ptr ) const { return ( _ptr == ptr ); } 00126 00131 bool operator != ( const T* ptr ) const { return ( _ptr != ptr ); } 00132 00134 T* operator->() 00135 { LBASSERTINFO( _ptr, className( this )); return _ptr; } 00137 const T* operator->() const 00138 { LBASSERTINFO( _ptr, className( this )); return _ptr; } 00140 T& operator*() 00141 { LBASSERTINFO( _ptr, className( this )); return *_ptr; } 00143 const T& operator*() const 00144 { LBASSERTINFO( _ptr, className( this )); return *_ptr; } 00145 00147 T* get() { return _ptr; } 00149 const T* get() const { return _ptr; } 00150 00152 bool isValid() const { return ( _ptr != 0 ); } 00153 00154 private: 00155 T* _ptr; 00156 00158 void _ref() { if(_ptr) _ptr->ref( this ); } 00159 00161 void _unref() 00162 { 00163 if(_ptr) 00164 { 00165 #ifdef NDEBUG 00166 _ptr->unref( this ); 00167 #else 00168 if( _ptr->unref( this )) 00169 _ptr = 0; 00170 #endif 00171 } 00172 } 00173 }; 00174 00176 template< class T > 00177 inline std::ostream& operator << ( std::ostream& os, RefPtr< T > rp ) 00178 { 00179 const T* p = rp.get(); 00180 if( !p ) 00181 return os << "RP[ 0:NULL ]"; 00182 00183 os << disableFlush << "RP[" << p->getRefCount() << ":" << *p << "]"; 00184 p->printHolders( os ); 00185 return os << enableFlush; 00186 } 00187 00188 template< class T > inline std::string className( const RefPtr<T>& rp ) 00189 { return className( rp.get( )); } 00190 } 00191 00192 #ifdef LUNCHBOX_USE_BOOST 00193 # include <boost/serialization/split_free.hpp> 00194 00195 namespace boost 00196 { 00197 namespace serialization 00198 { 00199 00200 template< class Archive, class T > 00201 inline void save( Archive& ar, const lunchbox::RefPtr< T >& t, 00202 const unsigned int /*version*/ ) 00203 { 00204 const T* ptr = t.get(); 00205 ar << ptr; 00206 } 00207 00208 template< class Archive, class T > 00209 inline void load( Archive& ar, lunchbox::RefPtr< T >& t, 00210 const unsigned int /*version*/ ) 00211 { 00212 T* obj; 00213 ar >> obj; 00214 t = obj; 00215 } 00216 00217 template< class Archive, class T > 00218 inline void serialize( Archive& ar, lunchbox::RefPtr< T >& t, 00219 const unsigned int version ) 00220 { 00221 boost::serialization::split_free( ar, t, version ); 00222 } 00223 00224 } 00225 } 00226 00227 #endif // LUNCHBOX_USE_BOOST 00228 #endif //LUNCHBOX_REFPTR_H