Equalizer  1.3.1-git
refPtr.h
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, const RefPtr<T>& rp )
00179     {
00180         const T* p = rp.get();
00181         if( p )
00182         {
00183             os << disableFlush << "RP[" << p->getRefCount() << ":" << *p << "]";
00184 #ifdef LUNCHBOX_REFERENCED_DEBUG
00185             os << std::endl;
00186             p->printHolders( os );
00187 #endif
00188             os << enableFlush;
00189         }
00190         else
00191             os << "RP[ 0:NULL ]";
00192 
00193         return os;
00194     }
00195 
00196     template< class T > inline std::string className( const RefPtr<T>& rp )
00197         { return className( rp.get( )); }
00198 }
00199 
00200 #ifdef LUNCHBOX_USE_BOOST_SERIALIZATION
00201 #  include <boost/serialization/split_free.hpp>
00202 
00203 namespace boost
00204 {
00205 namespace serialization
00206 {
00207 
00208 template< class Archive, class T >
00209 inline void save( Archive& ar, const lunchbox::RefPtr< T >& t,
00210                   const unsigned int /*version*/ )
00211 {
00212     const T* ptr = t.get();
00213     ar << ptr;
00214 }
00215 
00216 template< class Archive, class T >
00217 inline void load( Archive& ar, lunchbox::RefPtr< T >& t,
00218                   const unsigned int /*version*/ )
00219 {
00220     T* obj;
00221     ar >> obj;
00222     t = obj;
00223 }
00224 
00225 template< class Archive, class T >
00226 inline void serialize( Archive& ar, lunchbox::RefPtr< T >& t,
00227                        const unsigned int version )
00228 {
00229     boost::serialization::split_free( ar, t, version );
00230 }
00231 
00232 }
00233 }
00234 
00235 #endif // LUNCHBOX_USE_BOOST_SERIALIZATION
00236 #endif //LUNCHBOX_REFPTR_H
Generated on Tue May 1 2012 15:14:28 for Equalizer 1.3.1-git by  doxygen 1.8.0