LCOV - code coverage report
Current view: top level - lunchbox - refPtr.h (source / functions) Hit Total Coverage
Test: Lunchbox Lines: 31 32 96.9 %
Date: 2016-11-11 05:21:33 Functions: 40 40 100.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2005-2015, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                          Daniel Nachbaur <danielnachbaur@gmail.com>
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or modify it under
       6             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       7             :  * by the Free Software Foundation.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      11             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      12             :  * details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public License
      15             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      16             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  */
      18             : 
      19             : #ifndef LUNCHBOX_REFPTR_H
      20             : #define LUNCHBOX_REFPTR_H
      21             : 
      22             : #include <lunchbox/debug.h>
      23             : 
      24             : #include <iostream>
      25             : #include <stdlib.h>
      26             : 
      27             : namespace lunchbox
      28             : {
      29             : /**
      30             :  * A smart reference pointer, aka boost::intrusive_ptr.
      31             :  *
      32             :  * Relies on the held object to implement ref() and unref()
      33             :  * correctly. Serializable using boost.serialization.
      34             :  *
      35             :  * @deprecated Use boost::intrusive_ptr
      36             :  *
      37             :  * Example: @include tests/refPtr.cpp
      38             :  */
      39             : template< class T > class RefPtr
      40             : {
      41             :     typedef T* RefPtr::*bool_t;
      42             : 
      43             : public:
      44             :     /** Construct a new, empty reference pointer. @version 1.0 */
      45          25 :     RefPtr() : _ptr( 0 ) {}
      46             : 
      47             :     /** Construct a reference pointer from a C pointer. @version 1.0 */
      48             :     // cppcheck-suppress noExplicitConstructor
      49     2000007 :     RefPtr( T* const ptr ) : _ptr( ptr ) { _ref(); }
      50             : 
      51             :     /** Construct a copy of a reference pointer. @version 1.0 */
      52     3000007 :     RefPtr( const RefPtr& from ) : _ptr( from._ptr ) { _ref(); }
      53             : 
      54             :     /**
      55             :      * Construct a copy of a reference pointer of a different type.
      56             :      * @version 1.0
      57             :      */
      58             :     // cppcheck-suppress noExplicitConstructor
      59             :     template< class O > RefPtr( RefPtr< O > from )
      60             :         : _ptr( from.get( )) { _ref(); }
      61             : 
      62             :     /** Destruct this reference pointer. @version 1.0 */
      63     5000039 :     ~RefPtr() { _unref(); _ptr = 0; }
      64             : 
      65             :     /** Assign another RefPtr to this reference pointer. @version 1.0 */
      66     6584811 :     RefPtr& operator = ( const RefPtr& rhs )
      67             :     {
      68     6584811 :         if( _ptr == rhs._ptr )
      69     3269855 :             return *this;
      70             : 
      71     3314956 :         T* tmp = _ptr;
      72     3314956 :         _ptr = rhs._ptr;
      73     3314956 :         _ref();
      74     3144109 :         if( tmp ) tmp->unref( this );
      75     3989706 :         return *this;
      76             :     }
      77             : 
      78             :     /** Assign a C pointer to this reference pointer. @version 1.0 */
      79     3460862 :     RefPtr& operator = ( T* ptr )
      80             :     {
      81     3460862 :         if( _ptr == ptr )
      82           0 :             return *this;
      83             : 
      84     3460862 :         T* tmp = _ptr;
      85     3460862 :         _ptr = ptr;
      86     3460862 :         _ref();
      87     3455840 :         if( tmp ) tmp->unref( this );
      88     3732761 :         return *this;
      89             :     }
      90             : 
      91             :     /**
      92             :      * @return true if both reference pointers hold the same C pointer.
      93             :      * @version 1.0
      94             :      */
      95             :     bool operator == ( const RefPtr& rhs ) const
      96             :     { return ( _ptr == rhs._ptr ); }
      97             : 
      98             :     /**
      99             :      * @return true if both reference pointer hold different C pointer.
     100             :      * @version 1.0
     101             :      */
     102             :     bool operator != ( const RefPtr& rhs ) const
     103             :     { return ( _ptr != rhs._ptr ); }
     104             : 
     105             :     /**
     106             :      * @return true if a pointer is held, false otherwise.
     107             :      * @version 1.1.5
     108             :      */
     109             :     operator bool_t() const { return _ptr == 0 ? 0 : &RefPtr::_ptr; }
     110             : 
     111             :     /** @return true if the RefPtr is empty. @version 1.0 */
     112             :     bool operator ! () const               { return ( _ptr==0 ); }
     113             : 
     114             :     /**
     115             :      * @return true if the left RefPtr is smaller then the right.
     116             :      * @version 1.0
     117             :      */
     118             :     bool operator < ( const RefPtr& rhs ) const { return ( _ptr < rhs._ptr ); }
     119             : 
     120             :     /**
     121             :      * @return true if the right RefPtr is smaller then the left.
     122             :      * @version 1.0
     123             :      */
     124             :     bool operator > ( const RefPtr& rhs ) const { return ( _ptr > rhs._ptr ); }
     125             : 
     126             :     /**
     127             :      * @return true if the reference pointers holds the C pointer.
     128             :      * @version 1.0
     129             :      */
     130             :     bool operator == ( const T* ptr ) const { return ( _ptr == ptr ); }
     131             : 
     132             :     /**
     133             :      * @return true if the reference pointers does not hold the C pointer
     134             :      * @version 1.0
     135             :      */
     136             :     bool operator != ( const T* ptr ) const { return ( _ptr != ptr ); }
     137             : 
     138             :     /** Access the held object. @version 1.0 */
     139          12 :     T*       operator->()
     140          12 :     { LBASSERTINFO( _ptr, className( this )); return _ptr; }
     141             :     /** Access the held object. @version 1.0 */
     142           3 :     const T* operator->() const
     143           3 :     { LBASSERTINFO( _ptr, className( this )); return _ptr; }
     144             :     /** Access the held object. @version 1.0 */
     145             :     T&       operator*()
     146             :     { LBASSERTINFO( _ptr, className( this )); return *_ptr; }
     147             :     /** Access the held object. @version 1.0 */
     148             :     const T& operator*() const
     149             :     { LBASSERTINFO( _ptr, className( this )); return *_ptr; }
     150             : 
     151             :     /** @return the C pointer. @version 1.0 */
     152           7 :     T*       get()                { return _ptr; }
     153             :     /** @return the C pointer. @version 1.0 */
     154           4 :     const T* get() const          { return _ptr; }
     155             : 
     156             :     /** @return true if the RefPtr holds a non-0 pointer. @version 1.0 */
     157             :     bool isValid() const { return ( _ptr != 0 ); }
     158             : 
     159             : private:
     160             :     T* _ptr;
     161             : 
     162             :     /** Artificially reference the held object. */
     163     9449553 :     void _ref()   { if(_ptr) _ptr->ref( this ); }
     164             : 
     165             :     /** Artificially dereference the held object. */
     166     5000039 :     void _unref()
     167             :     {
     168     5000039 :         if(_ptr)
     169             :         {
     170             : #ifdef NDEBUG
     171             :             _ptr->unref( this );
     172             : #else
     173     5000014 :             if( _ptr->unref( this ))
     174     2000007 :                 _ptr = 0;
     175             : #endif
     176             :         }
     177     5000039 :     }
     178             : };
     179             : 
     180             : /** Print the reference pointer to the given output stream. */
     181             : template< class T >
     182             : inline std::ostream& operator << ( std::ostream& os, RefPtr< T > rp )
     183             : {
     184             :     const T* p = rp.get();
     185             :     if( !p )
     186             :         return os << "RP[ 0:NULL ]";
     187             : 
     188             :     os << disableFlush << "RP[" << p->getRefCount() << ":" << *p << "]";
     189             :     p->printHolders( os );
     190             :     return os << enableFlush;
     191             : }
     192             : 
     193             : template< class T > inline std::string className( const RefPtr<T>& rp )
     194             : { return className( rp.get( )); }
     195             : }
     196             : 
     197             : #include <boost/serialization/split_free.hpp>
     198             : 
     199             : namespace boost
     200             : {
     201             : namespace serialization
     202             : {
     203             : 
     204             : template< class Archive, class T >
     205             : inline void save( Archive& ar, const lunchbox::RefPtr< T >& t,
     206             :                   const unsigned int /*version*/ )
     207             : {
     208             :     const T* ptr = t.get();
     209             :     ar << ptr;
     210             : }
     211             : 
     212             : template< class Archive, class T >
     213             : inline void load( Archive& ar, lunchbox::RefPtr< T >& t,
     214             :                   const unsigned int /*version*/ )
     215             : {
     216             :     T* obj = 0;
     217             :     ar >> obj;
     218             :     t = obj;
     219             : }
     220             : 
     221             : template< class Archive, class T >
     222             : inline void serialize( Archive& ar, lunchbox::RefPtr< T >& t,
     223             :                        const unsigned int version )
     224             : {
     225             :     boost::serialization::split_free( ar, t, version );
     226             : }
     227             : 
     228             : }
     229             : }
     230             : 
     231             : #endif //LUNCHBOX_REFPTR_H

Generated by: LCOV version 1.11