LCOV - code coverage report
Current view: top level - lunchbox - refPtr.h (source / functions) Hit Total Coverage
Test: Lunchbox Lines: 48 52 92.3 %
Date: 2018-10-03 05:33:11 Functions: 40 43 93.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>
      40             : class RefPtr
      41             : {
      42             :     typedef T* RefPtr::*bool_t;
      43             : 
      44             : public:
      45             :     /** Construct a new, empty reference pointer. @version 1.0 */
      46          25 :     RefPtr()
      47          25 :         : _ptr(0)
      48             :     {
      49          25 :     }
      50             : 
      51             :     /** Construct a reference pointer from a C pointer. @version 1.0 */
      52             :     // cppcheck-suppress noExplicitConstructor
      53     2000007 :     RefPtr(T* const ptr)
      54     2000007 :         : _ptr(ptr)
      55             :     {
      56     2000007 :         _ref();
      57     2000007 :     }
      58             : 
      59             :     /** Construct a copy of a reference pointer. @version 1.0 */
      60     3000007 :     RefPtr(const RefPtr& from)
      61     3000007 :         : _ptr(from._ptr)
      62             :     {
      63     3000007 :         _ref();
      64     3000007 :     }
      65             : 
      66             :     /**
      67             :      * Construct a copy of a reference pointer of a different type.
      68             :      * @version 1.0
      69             :      */
      70             :     // cppcheck-suppress noExplicitConstructor
      71             :     template <class O>
      72             :     RefPtr(RefPtr<O> from)
      73             :         : _ptr(from.get())
      74             :     {
      75             :         _ref();
      76             :     }
      77             : 
      78             :     /** Destruct this reference pointer. @version 1.0 */
      79     5000039 :     ~RefPtr()
      80             :     {
      81     5000039 :         _unref();
      82     5000039 :         _ptr = 0;
      83     5000039 :     }
      84             : 
      85             :     /** Assign another RefPtr to this reference pointer. @version 1.0 */
      86     6647494 :     RefPtr& operator=(const RefPtr& rhs)
      87             :     {
      88     6647494 :         if (_ptr == rhs._ptr)
      89     3138848 :             return *this;
      90             : 
      91     3508646 :         T* tmp = _ptr;
      92     3508646 :         _ptr = rhs._ptr;
      93     3508646 :         _ref();
      94     3562459 :         if (tmp)
      95           0 :             tmp->unref(this);
      96     3651250 :         return *this;
      97             :     }
      98             : 
      99             :     /** Assign a C pointer to this reference pointer. @version 1.0 */
     100     3376586 :     RefPtr& operator=(T* ptr)
     101             :     {
     102     3376586 :         if (_ptr == ptr)
     103           0 :             return *this;
     104             : 
     105     3376586 :         T* tmp = _ptr;
     106     3376586 :         _ptr = ptr;
     107     3376586 :         _ref();
     108     3712421 :         if (tmp)
     109     3784396 :             tmp->unref(this);
     110     3384577 :         return *this;
     111             :     }
     112             : 
     113             :     /**
     114             :      * @return true if both reference pointers hold the same C pointer.
     115             :      * @version 1.0
     116             :      */
     117             :     bool operator==(const RefPtr& rhs) const { return (_ptr == rhs._ptr); }
     118             :     /**
     119             :      * @return true if both reference pointer hold different C pointer.
     120             :      * @version 1.0
     121             :      */
     122             :     bool operator!=(const RefPtr& rhs) const { return (_ptr != rhs._ptr); }
     123             :     /**
     124             :      * @return true if a pointer is held, false otherwise.
     125             :      * @version 1.1.5
     126             :      */
     127             :     operator bool_t() const { return _ptr == 0 ? 0 : &RefPtr::_ptr; }
     128             :     /** @return true if the RefPtr is empty. @version 1.0 */
     129             :     bool operator!() const { return (_ptr == 0); }
     130             :     /**
     131             :      * @return true if the left RefPtr is smaller then the right.
     132             :      * @version 1.0
     133             :      */
     134             :     bool operator<(const RefPtr& rhs) const { return (_ptr < rhs._ptr); }
     135             :     /**
     136             :      * @return true if the right RefPtr is smaller then the left.
     137             :      * @version 1.0
     138             :      */
     139             :     bool operator>(const RefPtr& rhs) const { return (_ptr > rhs._ptr); }
     140             :     /**
     141             :      * @return true if the reference pointers holds the C pointer.
     142             :      * @version 1.0
     143             :      */
     144             :     bool operator==(const T* ptr) const { return (_ptr == ptr); }
     145             :     /**
     146             :      * @return true if the reference pointers does not hold the C pointer
     147             :      * @version 1.0
     148             :      */
     149             :     bool operator!=(const T* ptr) const { return (_ptr != ptr); }
     150             :     /** Access the held object. @version 1.0 */
     151          12 :     T* operator->()
     152             :     {
     153          12 :         LBASSERTINFO(_ptr, className(this));
     154          12 :         return _ptr;
     155             :     }
     156             :     /** Access the held object. @version 1.0 */
     157           3 :     const T* operator->() const
     158             :     {
     159           3 :         LBASSERTINFO(_ptr, className(this));
     160           3 :         return _ptr;
     161             :     }
     162             :     /** Access the held object. @version 1.0 */
     163             :     T& operator*()
     164             :     {
     165             :         LBASSERTINFO(_ptr, className(this));
     166             :         return *_ptr;
     167             :     }
     168             :     /** Access the held object. @version 1.0 */
     169             :     const T& operator*() const
     170             :     {
     171             :         LBASSERTINFO(_ptr, className(this));
     172             :         return *_ptr;
     173             :     }
     174             : 
     175             :     /** @return the C pointer. @version 1.0 */
     176           7 :     T* get() { return _ptr; }
     177             :     /** @return the C pointer. @version 1.0 */
     178           4 :     const T* get() const { return _ptr; }
     179             :     /** @return true if the RefPtr holds a non-0 pointer. @version 1.0 */
     180             :     bool isValid() const { return (_ptr != 0); }
     181             : private:
     182             :     T* _ptr;
     183             : 
     184             :     /** Artificially reference the held object. */
     185    10137812 :     void _ref()
     186             :     {
     187    10137812 :         if (_ptr)
     188     8997941 :             _ptr->ref(this);
     189    10227801 :     }
     190             : 
     191             :     /** Artificially dereference the held object. */
     192     5000039 :     void _unref()
     193             :     {
     194     5000039 :         if (_ptr)
     195             :         {
     196             : #ifdef NDEBUG
     197             :             _ptr->unref(this);
     198             : #else
     199     5000014 :             if (_ptr->unref(this))
     200     2000007 :                 _ptr = 0;
     201             : #endif
     202             :         }
     203     5000039 :     }
     204             : };
     205             : 
     206             : /** Print the reference pointer to the given output stream. */
     207             : template <class T>
     208             : inline std::ostream& operator<<(std::ostream& os, RefPtr<T> rp)
     209             : {
     210             :     const T* p = rp.get();
     211             :     if (!p)
     212             :         return os << "RP[ 0:NULL ]";
     213             : 
     214             :     os << disableFlush << "RP[" << p->getRefCount() << ":" << *p << "]";
     215             :     p->printHolders(os);
     216             :     return os << enableFlush;
     217             : }
     218             : 
     219             : template <class T>
     220           0 : inline std::string className(const RefPtr<T>& rp)
     221             : {
     222           0 :     return className(rp.get());
     223             : }
     224             : }
     225             : 
     226             : #include <boost/serialization/split_free.hpp>
     227             : 
     228             : namespace boost
     229             : {
     230             : namespace serialization
     231             : {
     232             : template <class Archive, class T>
     233             : inline void save(Archive& ar, const lunchbox::RefPtr<T>& t,
     234             :                  const unsigned int /*version*/)
     235             : {
     236             :     const T* ptr = t.get();
     237             :     ar << ptr;
     238             : }
     239             : 
     240             : template <class Archive, class T>
     241             : inline void load(Archive& ar, lunchbox::RefPtr<T>& t,
     242             :                  const unsigned int /*version*/)
     243             : {
     244             :     T* obj = 0;
     245             :     ar >> obj;
     246             :     t = obj;
     247             : }
     248             : 
     249             : template <class Archive, class T>
     250             : inline void serialize(Archive& ar, lunchbox::RefPtr<T>& t,
     251             :                       const unsigned int version)
     252             : {
     253             :     boost::serialization::split_free(ar, t, version);
     254             : }
     255             : }
     256             : }
     257             : 
     258             : #endif // LUNCHBOX_REFPTR_H

Generated by: LCOV version 1.11