LCOV - code coverage report
Current view: top level - lunchbox - refPtr.h (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 41 42 97.6 %
Date: 2014-08-05 Functions: 39 39 100.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2005-2014, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *               2012-2013, 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          26 :     RefPtr()                     : _ptr( 0 )         {}
      46             : 
      47             :     /** Construct a reference pointer from a C pointer. @version 1.0 */
      48           4 :     RefPtr( T* const ptr )       : _ptr( ptr )       { _ref(); }
      49             : 
      50             :     /** Construct a copy of a reference pointer. @version 1.0 */
      51           5 :     RefPtr( const RefPtr& from ) : _ptr( from._ptr ) { _ref(); }
      52             : 
      53             :     /**
      54             :      * Construct a copy of a reference pointer of a different type.
      55             :      * @version 1.0
      56             :      */
      57             :     template< class O > RefPtr( RefPtr< O > from )
      58             :         : _ptr( from.get( )) { _ref(); }
      59             : 
      60             :     /** Destruct this reference pointer. @version 1.0 */
      61          34 :     ~RefPtr() { _unref(); _ptr = 0; }
      62             : 
      63             :     /** Assign another RefPtr to this reference pointer. @version 1.0 */
      64     6609656 :     RefPtr& operator = ( const RefPtr& rhs )
      65             :     {
      66     6609656 :         if( _ptr == rhs._ptr )
      67     3502295 :             return *this;
      68             : 
      69     3107361 :         T* tmp = _ptr;
      70     3107361 :         _ptr = rhs._ptr;
      71     3107361 :         _ref();
      72     3059460 :         if( tmp ) tmp->unref( this );
      73     3655720 :         return *this;
      74             :     }
      75             : 
      76             :     /** Assign a C pointer to this reference pointer. @version 1.0 */
      77     3315371 :     RefPtr& operator = ( T* ptr )
      78             :     {
      79     3315371 :         if( _ptr == ptr )
      80           0 :             return *this;
      81             : 
      82     3315371 :         T* tmp = _ptr;
      83     3315371 :         _ptr = ptr;
      84     3315371 :         _ref();
      85     3222568 :         if( tmp ) tmp->unref( this );
      86     3167196 :         return *this;
      87             :     }
      88             : 
      89             :     /**
      90             :      * @return true if both reference pointers hold the same C pointer.
      91             :      * @version 1.0
      92             :      */
      93             :     bool operator == ( const RefPtr& rhs ) const
      94             :     { return ( _ptr == rhs._ptr ); }
      95             : 
      96             :     /**
      97             :      * @return true if both reference pointer hold different C pointer.
      98             :      * @version 1.0
      99             :      */
     100             :     bool operator != ( const RefPtr& rhs ) const
     101             :     { return ( _ptr != rhs._ptr ); }
     102             : 
     103             :     /**
     104             :      * @return true if a pointer is held, false otherwise.
     105             :      * @version 1.1.5
     106             :      */
     107             :     operator bool_t() const { return _ptr == 0 ? 0 : &RefPtr::_ptr; }
     108             : 
     109             :     /** @return true if the RefPtr is empty. @version 1.0 */
     110             :     bool operator ! () const               { return ( _ptr==0 ); }
     111             : 
     112             :     /**
     113             :      * @return true if the left RefPtr is smaller then the right.
     114             :      * @version 1.0
     115             :      */
     116             :     bool operator < ( const RefPtr& rhs ) const { return ( _ptr < rhs._ptr ); }
     117             : 
     118             :     /**
     119             :      * @return true if the right RefPtr is smaller then the left.
     120             :      * @version 1.0
     121             :      */
     122             :     bool operator > ( const RefPtr& rhs ) const { return ( _ptr > rhs._ptr ); }
     123             : 
     124             :     /**
     125             :      * @return true if the reference pointers holds the C pointer.
     126             :      * @version 1.0
     127             :      */
     128             :     bool operator == ( const T* ptr ) const { return ( _ptr == ptr ); }
     129             : 
     130             :     /**
     131             :      * @return true if the reference pointers does not hold the C pointer
     132             :      * @version 1.0
     133             :      */
     134             :     bool operator != ( const T* ptr ) const { return ( _ptr != ptr ); }
     135             : 
     136             :     /** Access the held object. @version 1.0 */
     137          13 :     T*       operator->()
     138          13 :     { LBASSERTINFO( _ptr, className( this )); return _ptr; }
     139             :     /** Access the held object. @version 1.0 */
     140             :     const T* operator->() const
     141             :     { LBASSERTINFO( _ptr, className( this )); return _ptr; }
     142             :     /** Access the held object. @version 1.0 */
     143             :     T&       operator*()
     144             :     { LBASSERTINFO( _ptr, className( this )); return *_ptr; }
     145             :     /** Access the held object. @version 1.0 */
     146             :     const T& operator*() const
     147             :     { LBASSERTINFO( _ptr, className( this )); return *_ptr; }
     148             : 
     149             :     /** @return the C pointer. @version 1.0 */
     150           4 :     T*       get()                { return _ptr; }
     151             :     /** @return the C pointer. @version 1.0 */
     152           5 :     const T* get() const          { return _ptr; }
     153             : 
     154             :     /** @return true if the RefPtr holds a non-0 pointer. @version 1.0 */
     155             :     bool isValid() const { return ( _ptr != 0 ); }
     156             : 
     157             : private:
     158             :     T* _ptr;
     159             : 
     160             :     /** Artificially reference the held object. */
     161     4516252 :     void _ref()   { if(_ptr) _ptr->ref( this ); }
     162             : 
     163             :     /** Artificially dereference the held object. */
     164          34 :     void _unref()
     165             :     {
     166          34 :         if(_ptr)
     167             :         {
     168             : #ifdef NDEBUG
     169             :             _ptr->unref( this );
     170             : #else
     171          10 :             if( _ptr->unref( this ))
     172           5 :                 _ptr = 0;
     173             : #endif
     174             :         }
     175          34 :     }
     176             : };// LB_DEPRECATED;
     177             : 
     178             : /** Print the reference pointer to the given output stream. */
     179             : template< class T >
     180             : inline std::ostream& operator << ( std::ostream& os, RefPtr< T > rp )
     181             : {
     182             :     const T* p = rp.get();
     183             :     if( !p )
     184             :         return os << "RP[ 0:NULL ]";
     185             : 
     186             :     os << disableFlush << "RP[" << p->getRefCount() << ":" << *p << "]";
     187             :     p->printHolders( os );
     188             :     return os << enableFlush;
     189             : }
     190             : 
     191             : template< class T > inline std::string className( const RefPtr<T>& rp )
     192             : { return className( rp.get( )); }
     193             : }
     194             : 
     195             : #include <boost/serialization/split_free.hpp>
     196             : 
     197             : namespace boost
     198             : {
     199             : namespace serialization
     200             : {
     201             : 
     202             : template< class Archive, class T >
     203           1 : inline void save( Archive& ar, const lunchbox::RefPtr< T >& t,
     204             :                   const unsigned int /*version*/ )
     205             : {
     206           1 :     const T* ptr = t.get();
     207           1 :     ar << ptr;
     208           1 : }
     209             : 
     210             : template< class Archive, class T >
     211           1 : inline void load( Archive& ar, lunchbox::RefPtr< T >& t,
     212             :                   const unsigned int /*version*/ )
     213             : {
     214           1 :     T* obj = 0;
     215           1 :     ar >> obj;
     216           1 :     t = obj;
     217           1 : }
     218             : 
     219             : template< class Archive, class T >
     220           2 : inline void serialize( Archive& ar, lunchbox::RefPtr< T >& t,
     221             :                        const unsigned int version )
     222             : {
     223           2 :     boost::serialization::split_free( ar, t, version );
     224           2 : }
     225             : 
     226             : }
     227             : }
     228             : 
     229             : #endif //LUNCHBOX_REFPTR_H

Generated by: LCOV version 1.10