LCOV - code coverage report
Current view: top level - include/crpropa - Referenced.h (source / functions) Coverage Total Hit
Test: coverage.info.cleaned Lines: 73.2 % 56 41
Test Date: 2026-06-18 09:49:19 Functions: 52.6 % 19 10

            Line data    Source code
       1              : #ifndef CRPROPA_REFERENCED_H
       2              : #define CRPROPA_REFERENCED_H
       3              : 
       4              : #include <cstddef>
       5              : 
       6              : #ifdef DEBUG
       7              : #include <iostream>
       8              : #include <typeinfo>
       9              : #endif
      10              : 
      11              : namespace crpropa {
      12              : /**
      13              :  * \addtogroup Core
      14              :  * @{
      15              :  */
      16              : 
      17              : /**
      18              :  @class Referenced
      19              :  @brief Base class for reference counting
      20              : 
      21              :  A form of memory management is needed to prevent memory leaks when using MPC in Python via SWIG.
      22              :  This base class enables reference counting.
      23              :  Every reference increases the reference counter, every dereference decreases it.
      24              :  When the counter is decreased to 0, the object is deleted.
      25              :  Candidate, Module, MagneticField and Source inherit from this class
      26              :  */
      27              : class Referenced {
      28              : public:
      29              : 
      30      3373373 :         inline Referenced() :
      31      3373352 :                         _referenceCount(0) {
      32              :         }
      33              : 
      34            0 :         inline Referenced(const Referenced&) :
      35            0 :                         _referenceCount(0) {
      36              :         }
      37              : 
      38              :         inline Referenced& operator =(const Referenced&) {
      39              :                 return *this;
      40              :         }
      41              : 
      42              :         inline size_t addReference() const {
      43              :                 int newRef;
      44              : #if defined(OPENMP_3_1)
      45              :                 #pragma omp atomic capture
      46              :                 {newRef = _referenceCount++;}
      47              : #elif defined(__GNUC__)
      48     10922282 :                 newRef = __sync_add_and_fetch(&_referenceCount, 1);
      49              : #else
      50              :                 #pragma omp critical(newRef)
      51              :                 {newRef = _referenceCount++;}
      52              : #endif
      53      7551177 :                 return newRef;
      54              :         }
      55              : 
      56     10923612 :         inline size_t removeReference() const {
      57              : #ifdef DEBUG
      58              :                 if (_referenceCount == 0)
      59              :                         std::cerr
      60              :                                         << "WARNING: Remove reference from Object with NO references: "
      61              :                                         << typeid(*this).name() << std::endl;
      62              : #endif
      63              :                 int newRef;
      64              : #if defined(OPENMP_3_1)
      65              :                 #pragma omp atomic capture
      66              :                 {newRef = _referenceCount--;}
      67              : #elif defined(__GNUC__)
      68     10923612 :                 newRef = __sync_sub_and_fetch(&_referenceCount, 1);
      69              : #else
      70              :                 #pragma omp critical(newRef)
      71              :                 {newRef = _referenceCount--;}
      72              : #endif
      73              : 
      74     10923612 :                 if (newRef == 0) {
      75      3371342 :                         delete this;
      76              :                 }
      77     10923612 :                 return newRef;
      78              :         }
      79              : 
      80              :         int removeReferenceNoDelete() const {
      81            0 :                 return --_referenceCount;
      82              :         }
      83              : 
      84              :         inline size_t getReferenceCount() const {
      85            0 :                 return _referenceCount;
      86              :         }
      87              : 
      88              : protected:
      89              : 
      90            0 :         virtual inline ~Referenced() {
      91              : #ifdef DEBUG
      92              :                 if (_referenceCount)
      93              :                         std::cerr << "WARNING: Deleting Object with references: "
      94              :                                         << typeid(*this).name() << std::endl;
      95              : #endif
      96            0 :         }
      97              : 
      98              :         mutable size_t _referenceCount;
      99              : };
     100              : 
     101              : inline void intrusive_ptr_add_ref(Referenced* p) {
     102              :         p->addReference();
     103              : }
     104              : inline void intrusive_ptr_release(Referenced* p) {
     105            0 :         p->removeReference();
     106              : }
     107              : 
     108              : /**
     109              :  @class ref_ptr
     110              :  @brief Referenced pointer
     111              :  */
     112              : template<class T>
     113              : class ref_ptr {
     114              : public:
     115              :         typedef T element_type;
     116              : 
     117          174 :         ref_ptr() :
     118          174 :                         _ptr(0) {
     119              :         }
     120      3332219 :         ref_ptr(T* ptr) :
     121      3334260 :                         _ptr(ptr) {
     122         3307 :                 if (_ptr)
     123              :                         _ptr->addReference();
     124              :         }
     125      7546539 :         ref_ptr(const ref_ptr& rp) :
     126      7546425 :                         _ptr(rp._ptr) {
     127      7546474 :                 if (_ptr)
     128              :                         _ptr->addReference();
     129            2 :         }
     130            4 :         template<class Other> ref_ptr(const ref_ptr<Other>& rp) :
     131            4 :                         _ptr(rp._ptr) {
     132              :                 if (_ptr)
     133              :                         _ptr->addReference();
     134              :         }
     135              : 
     136              :         ~ref_ptr() {
     137      7551001 :                 if (_ptr)
     138     10879914 :                         _ptr->removeReference();
     139              :                 _ptr = 0;
     140     10879832 :         }
     141              : 
     142              :         ref_ptr& operator =(const ref_ptr& rp) {
     143          221 :                 assign(rp);
     144            0 :                 return *this;
     145              :         }
     146              : 
     147              :         template<class Other> ref_ptr& operator =(const ref_ptr<Other>& rp) {
     148              :                 assign(rp);
     149              :                 return *this;
     150              :         }
     151              : 
     152           78 :         inline ref_ptr& operator =(T* ptr) {
     153           78 :                 if (_ptr == ptr)
     154              :                         return *this;
     155              :                 T* tmp_ptr = _ptr;
     156           78 :                 _ptr = ptr;
     157           78 :                 if (_ptr)
     158              :                         _ptr->addReference();
     159           78 :                 if (tmp_ptr)
     160           68 :                         tmp_ptr->removeReference();
     161              :                 return *this;
     162              :         }
     163              : 
     164              :         operator T*() const {
     165       481154 :                 return _ptr;
     166              :         }
     167              : 
     168              :         T& operator*() const {
     169         6617 :                 return *_ptr;
     170              :         }
     171              :         T* operator->() const {
     172      6153353 :                 return _ptr;
     173              :         }
     174              :         T* get() const {
     175           37 :                 return _ptr;
     176              :         }
     177              : 
     178              :         bool operator!() const {
     179            0 :                 return _ptr == 0;
     180              :         } // not required
     181              :         bool valid() const {
     182      5881544 :                 return _ptr != 0;
     183              :         }
     184              : 
     185              :         T* release() {
     186            0 :                 T* tmp = _ptr;
     187            0 :                 if (_ptr)
     188              :                         _ptr->removeReferenceNoDelete();
     189            0 :                 _ptr = 0;
     190              :                 return tmp;
     191              :         }
     192              : 
     193              :         void swap(ref_ptr& rp) {
     194            0 :                 T* tmp = _ptr;
     195            0 :                 _ptr = rp._ptr;
     196            0 :                 rp._ptr = tmp;
     197              :         }
     198              : 
     199              : private:
     200              : 
     201         1322 :         template<class Other> void assign(const ref_ptr<Other>& rp) {
     202         1322 :                 if (_ptr == rp._ptr)
     203              :                         return;
     204              :                 T* tmp_ptr = _ptr;
     205         1318 :                 _ptr = rp._ptr;
     206         1318 :                 if (_ptr)
     207              :                         _ptr->addReference();
     208         1318 :                 if (tmp_ptr)
     209           91 :                         tmp_ptr->removeReference();
     210              :         }
     211              : 
     212              :         template<class Other> friend class ref_ptr;
     213              : 
     214              :         T* _ptr;
     215              : };
     216              : 
     217              : template<class T> inline
     218              : void swap(ref_ptr<T>& rp1, ref_ptr<T>& rp2) {
     219              :         rp1.swap(rp2);
     220              : }
     221              : 
     222              : template<class T> inline T* get_pointer(const ref_ptr<T>& rp) {
     223              :         return rp.get();
     224              : }
     225              : 
     226              : template<class T, class Y> inline ref_ptr<T> static_pointer_cast(
     227              :                 const ref_ptr<Y>& rp) {
     228              :         return static_cast<T*>(rp.get());
     229              : }
     230              : 
     231              : template<class T, class Y> inline ref_ptr<T> dynamic_pointer_cast(
     232              :                 const ref_ptr<Y>& rp) {
     233              :         return dynamic_cast<T*>(rp.get());
     234              : }
     235              : 
     236              : template<class T, class Y> inline ref_ptr<T> const_pointer_cast(
     237              :                 const ref_ptr<Y>& rp) {
     238              :         return const_cast<T*>(rp.get());
     239              : }
     240              : 
     241              : /** @}*/
     242              : } // namespace crpropa
     243              : 
     244              : #endif // CRPROPA_REFERENCED_H
        

Generated by: LCOV version 2.0-1