LCOV - code coverage report
Current view: top level - ugbase/common/util - smart_pointer.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 8.7 % 208 18
Test Date: 2025-09-21 23:31:46 Functions: 0.1 % 1793 2

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Sebastian Reiter
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #ifndef __SMART_POINTER__
      34              : #define __SMART_POINTER__
      35              : 
      36              : #include <functional>
      37              : #include <cstring>
      38              : #include <boost/pointee.hpp>
      39              : 
      40              : /// \addtogroup ugbase_common_util
      41              : /// \{
      42              : 
      43              : ////////////////////////////////////////////////////////////////////////
      44              : ////////////////////////////////////////////////////////////////////////
      45              : //      Policies
      46              : 
      47              : ////////////////////////////////////////////////////////////////////////
      48              : //      FreeDelete
      49              : template <typename T>
      50              : class FreeDelete
      51              : {
      52              :         public:
      53            1 :                 static void free(const T* data) {if(data) delete data;}
      54              : };
      55              : 
      56              : ////////////////////////////////////////////////////////////////////////
      57              : //      FreeDelete
      58              : template <typename T>
      59              : class FreeArrayDelete
      60              : {
      61              :         public:
      62              :                 static void free(const T* data) {if(data) delete[] data;}
      63              : };
      64              : 
      65              : ////////////////////////////////////////////////////////////////////////
      66              : //      FreeRelease
      67              : template <typename T>
      68              : class FreeRelease
      69              : {
      70              :         public:
      71              :                 static void free(const T* data) {data->Release;}
      72              : };
      73              : 
      74              : 
      75              : ////////////////////////////////////////////////////////////////////////
      76              : //      PREDECLARATIONS
      77              : template <class T, template <class TT> class FreePolicy = FreeDelete> class SmartPtr;
      78              : template <class T, template <class TT> class FreePolicy = FreeDelete> class ConstSmartPtr;
      79              : 
      80              : 
      81              : ////////////////////////////////////////////////////////////////////////
      82              : ///     Used to construct empty smart pointers
      83              : /**     SPNULL provides a global const instance.*/
      84              : class NullSmartPtr{
      85              :         public:
      86              :                 NullSmartPtr()  {}
      87              : };
      88              : 
      89              : ///     The equivalent to NULL for smart pointers
      90              : const NullSmartPtr      SPNULL;
      91              : 
      92              : 
      93              : ////////////////////////////////////////////////////////////////////////
      94              : //      SmartPtr
      95              : /**
      96              :  * A Smart Pointer encapsulates a pointer. With each copy
      97              :  * of the SmartPointer a shared reference count is increased and with
      98              :  * each destructor call to a SmartPointer this shared reference count is
      99              :  * decreased. If the shared reference count reaches 0 free as specified in
     100              :  * the FreePolicy is executed on the pointer.
     101              :  *
     102              :  * The FreePolicy has to feature the method free().
     103              :  *
     104              :  * If a const smart pointer is required, use ConstSmartPtr
     105              :  */
     106              : template <typename T, template <class TT> class FreePolicy>
     107              : class SmartPtr
     108              : {
     109              :         friend class ConstSmartPtr<T, FreePolicy>;
     110              :         friend class SmartPtr<void>;
     111              :         friend class ConstSmartPtr<void>;
     112              : 
     113              :         public:
     114            1 :                 explicit SmartPtr() : m_ptr(0), m_refCount(0)   {}
     115            1 :                 explicit SmartPtr(T* ptr) : m_ptr(ptr), m_refCount(0)   {if(ptr) m_refCount = new int(1);}
     116            0 :                 SmartPtr(NullSmartPtr) : m_ptr(0), m_refCount(0)        {}
     117            0 :                 SmartPtr(const SmartPtr& sp) : m_ptr(sp.m_ptr), m_refCount(sp.m_refCount)
     118              :                 {
     119            0 :                         if(m_refCount) (*m_refCount)++;
     120              :                 }
     121              : 
     122              :         /**     this template method allows to assign smart-pointers that encapsulate
     123              :          *      derivates of T. Make sure that the pointer-type of TSmartPtr is castable
     124              :          *      to T*.*/
     125              :                 template <class TPtr>
     126            0 :                 SmartPtr(const SmartPtr<TPtr, FreePolicy>& sp) :
     127            0 :                         m_ptr(sp.get_nonconst()),
     128            0 :                         m_refCount(sp.refcount_ptr())
     129              :                 {
     130            0 :                         if(m_refCount) (*m_refCount)++;
     131              :                 }
     132              : 
     133            2 :                 ~SmartPtr() {release();}
     134              : 
     135            0 :                 T* operator->()                      {return m_ptr;}
     136            0 :                 const T* operator->() const  {return m_ptr;}
     137              : 
     138            0 :                 T& operator*()                              {return *m_ptr;}
     139            0 :                 const T& operator*() const  {return *m_ptr;}
     140              : 
     141              :                 SmartPtr& operator=(NullSmartPtr) {
     142            0 :                         if(m_ptr)
     143            0 :                                 release();
     144            0 :                         m_ptr = 0;
     145            0 :                         m_refCount = 0;
     146              :                         return *this;
     147              :                 }
     148              : 
     149            1 :                 SmartPtr& operator=(const SmartPtr& sp) {
     150            1 :                         if(m_ptr)
     151            0 :                                 release();
     152            1 :                         m_ptr = sp.m_ptr;
     153            1 :                         m_refCount = sp.m_refCount;
     154            1 :                         if(m_refCount)
     155            1 :                                 (*m_refCount)++;
     156            1 :                         return *this;
     157              :                 }
     158              : 
     159              :                 template <class TIn>
     160            0 :                 SmartPtr<T, FreePolicy>& operator=(const SmartPtr<TIn, FreePolicy>& sp) {
     161            0 :                         if(m_ptr)
     162            0 :                                 release();
     163            0 :                         m_ptr = sp.get_nonconst();
     164            0 :                         m_refCount = sp.refcount_ptr();
     165            0 :                         if(m_refCount)
     166            0 :                                 (*m_refCount)++;
     167            0 :                         return *this;
     168              :                 }
     169              : 
     170              :                 bool operator==(const SmartPtr& sp) const {
     171              :                         return (this->get() == sp.get());
     172              :                 }
     173              : 
     174              :                 bool operator!=(const SmartPtr& sp) const {
     175              :                         return !(this->operator==(sp));
     176              :                 }
     177              : 
     178              :                 bool operator==(NullSmartPtr) const {
     179            0 :                         return m_ptr == 0;
     180              :                 }
     181              : 
     182              :                 bool operator!=(NullSmartPtr) const {
     183            0 :                         return m_ptr != 0;
     184              :                 }
     185              : 
     186              :                 template <class TPtr>
     187              :                 bool operator==(const ConstSmartPtr<TPtr, FreePolicy>& sp) const {
     188              :                         return (this->get() == sp.get());
     189              :                 }
     190              : 
     191              :                 template <class TPtr>
     192              :                 bool operator!=(const ConstSmartPtr<TPtr, FreePolicy>& sp) const {
     193              :                         return !(this->operator==(sp));
     194              :                 }
     195              : 
     196              :         ///     returns encapsulated pointer
     197            0 :                 T* get()                                {return m_ptr;}
     198              : 
     199              :         ///     returns encapsulated pointer
     200            0 :                 const T* get() const    {return m_ptr;}
     201              : 
     202              :         ///     returns refcount
     203              :                 int refcount() const {if(m_refCount) return *m_refCount; return 0;}
     204              : 
     205              :         ///     returns true if the pointer is valid, false if not.
     206            0 :                 inline bool valid() const       {return m_ptr != NULL;}
     207              : 
     208              :                 // pointer compat -- behave like std::shared_ptr<T>
     209              :                 explicit operator bool() const noexcept { return m_ptr != NULL; }
     210              : 
     211              :         ///     returns true if the pointer is invalid, false if not.
     212            0 :                 inline bool invalid() const     {return m_ptr == NULL;}
     213              : 
     214              :         ///     preforms a dynamic cast
     215              :                 template <class TDest>
     216            0 :                 SmartPtr<TDest, FreePolicy> cast_dynamic() const{
     217            0 :                         TDest* p = dynamic_cast<TDest*>(m_ptr);
     218            0 :                         if(p) return SmartPtr<TDest, FreePolicy>(p, m_refCount);
     219              :                         else return SmartPtr<TDest, FreePolicy>(NULL);
     220              :                 }
     221              : 
     222              :         ///     performs a static cast
     223              :                 template <class TDest>
     224              :                 SmartPtr<TDest, FreePolicy> cast_static() const{
     225            0 :                         TDest* p = static_cast<TDest*>(m_ptr);
     226            0 :                         if(p) return SmartPtr<TDest, FreePolicy>(p, m_refCount);
     227              :                         else return SmartPtr<TDest, FreePolicy>(NULL);
     228              :                 }
     229              : 
     230              :         ///     performs a reinterpret cast
     231              :                 template <class TDest>
     232              :                 SmartPtr<TDest, FreePolicy> cast_reinterpret() const{
     233              :                         TDest* p = reinterpret_cast<TDest*>(m_ptr);
     234              :                         if(p) return SmartPtr<TDest, FreePolicy>(p, m_refCount);
     235              :                         else return SmartPtr<TDest, FreePolicy>(NULL);
     236              :                 }
     237              : 
     238              :         ///
     239              :                 template <class TDest>
     240              :                 bool is_of_type() const
     241              :                 {
     242            0 :                         return dynamic_cast<TDest*>(m_ptr) != NULL;
     243              :                 }
     244              : 
     245              :         ///     performs a const cast
     246              :                 ConstSmartPtr<T, FreePolicy> cast_const() const;
     247              : 
     248              :         ///     WARNING: this method is DANGEROUS!
     249              :         /**     You should only use this constructor if you really know what you're doing!
     250              :          *      The following methods are required for SmartPtr<void> and casts */
     251            0 :                 explicit SmartPtr(T* ptr, int* refCount) : m_ptr(ptr), m_refCount(refCount)
     252              :                 {
     253            0 :                         if(m_refCount)
     254            0 :                                 (*m_refCount)++;
     255              :                 }
     256              : 
     257              :         ///     WARNING: this method is DANGEROUS!
     258              :         /**     This method should never be used since it may be removed in future
     259              :          *      versions of the SmartPtr class.
     260              :          *      It is featured in order to allow to implement a template-constructor
     261              :          *      that casts element-pointers of a smart pointer.
     262              :          *      \{*/
     263            0 :                 int* refcount_ptr() const       {return m_refCount;}
     264              : 
     265            0 :                 T* get_nonconst() const {return m_ptr;}
     266              :         /**     \}      */
     267              : 
     268              :         private:
     269              :         ///     decrements the refCount and frees the encapsulated pointer if required.
     270            2 :                 void release() {
     271            2 :                         if(m_refCount)
     272              :                         {
     273            2 :                                 (*m_refCount)--;
     274            2 :                                 if((*m_refCount) < 1)
     275              :                                 {
     276            1 :                                         delete m_refCount;
     277              :                                         //delete m_ptr;
     278            1 :                                         FreePolicy<T>::free(m_ptr);
     279              :                                 }
     280              :                         }
     281            2 :                 }
     282              : 
     283              :         ///     this release method is required by SmartPtr<void>
     284              :         /**     const void is not really correct here, of course...*/
     285            0 :                 static void free_void_ptr(const void* ptr){
     286            0 :                         FreePolicy<T>::free(reinterpret_cast<const T*>(ptr));
     287            0 :                 }
     288              : 
     289              :         private:
     290              :                 T*              m_ptr;
     291              :                 int*    m_refCount;
     292              : };
     293              : 
     294              : template <typename T, template <class TT> class FreePolicy>
     295              : class ConstSmartPtr
     296              : {
     297              :         friend class ConstSmartPtr<void>;
     298              : 
     299              :         public:
     300            0 :                 explicit ConstSmartPtr() : m_ptr(0), m_refCount(0)      {}
     301            0 :                 explicit ConstSmartPtr(const T* ptr) : m_ptr(ptr), m_refCount(0)        {if(ptr) m_refCount = new int(1);}
     302            0 :                 ConstSmartPtr(NullSmartPtr) : m_ptr(0), m_refCount(0)   {}
     303            0 :                 ConstSmartPtr(const ConstSmartPtr& sp) : m_ptr(sp.m_ptr), m_refCount(sp.m_refCount)
     304              :                 {
     305            0 :                         if(m_refCount) (*m_refCount)++;
     306              :                 }
     307              : 
     308              :         /**     this template method allows to assign smart-pointers that encapsulate
     309              :          *      derivates of T. Make sure that the pointer-type of TSmartPtr is castable
     310              :          *      to T*.*/
     311              :                 template <class TPtr>
     312            0 :                 ConstSmartPtr(const SmartPtr<TPtr, FreePolicy>& sp) :
     313            0 :                         m_ptr(sp.get()),
     314            0 :                         m_refCount(sp.refcount_ptr())
     315              :                 {
     316            0 :                         if(m_refCount) (*m_refCount)++;
     317              :                 }
     318              : 
     319              :                 template <class TPtr>
     320            0 :                 ConstSmartPtr(const ConstSmartPtr<TPtr, FreePolicy>& sp) :
     321            0 :                         m_ptr(sp.get()),
     322            0 :                         m_refCount(sp.refcount_ptr())
     323              :                 {
     324            0 :                         if(m_refCount) (*m_refCount)++;
     325              :                 }
     326              : 
     327            0 :                 ~ConstSmartPtr() {release();}
     328              : 
     329            0 :                 const T* operator->() const  {return m_ptr;}
     330              : 
     331            0 :                 const T& operator*() const  {return *m_ptr;}
     332              : 
     333            0 :                 ConstSmartPtr& operator=(const SmartPtr<T, FreePolicy>& sp){
     334            0 :                         if(m_ptr)
     335            0 :                                 release();
     336            0 :                         m_ptr = sp.m_ptr;
     337            0 :                         m_refCount = sp.m_refCount;
     338            0 :                         if(m_refCount)
     339            0 :                                 (*m_refCount)++;
     340            0 :                         return *this;
     341              :                 }
     342              : 
     343              :                 template <class TIn>
     344            0 :                 ConstSmartPtr<T, FreePolicy>& operator=(const SmartPtr<TIn, FreePolicy>& sp){
     345            0 :                         if(m_ptr)
     346            0 :                                 release();
     347            0 :                         m_ptr = sp.get();
     348            0 :                         m_refCount = sp.refcount_ptr();
     349            0 :                         if(m_refCount)
     350            0 :                                 (*m_refCount)++;
     351            0 :                         return *this;
     352              :                 }
     353              : 
     354            0 :                 ConstSmartPtr& operator=(const ConstSmartPtr& sp){
     355            0 :                         if(m_ptr)
     356            0 :                                 release();
     357            0 :                         m_ptr = sp.m_ptr;
     358            0 :                         m_refCount = sp.m_refCount;
     359            0 :                         if(m_refCount)
     360            0 :                                 (*m_refCount)++;
     361            0 :                         return *this;
     362              :                 }
     363              : 
     364              :                 template <class TIn>
     365              :                 ConstSmartPtr<T, FreePolicy>& operator=(const ConstSmartPtr<TIn, FreePolicy>& sp){
     366              :                         if(m_ptr)
     367              :                                 release();
     368              :                         m_ptr = sp.get();
     369              :                         m_refCount = sp.refcount_ptr();
     370              :                         if(m_refCount)
     371              :                                 (*m_refCount)++;
     372              :                         return *this;
     373              :                 }
     374              : 
     375              :                 ConstSmartPtr& operator=(NullSmartPtr){
     376              :                         if(m_ptr)
     377              :                                 release();
     378              :                         m_ptr = 0;
     379              :                         m_refCount = 0;
     380              :                         return *this;
     381              :                 }
     382              : 
     383              :                 bool operator==(const ConstSmartPtr& sp) const{
     384              :                         return (this->get() == sp.get());
     385              :                 }
     386              : 
     387              :                 template <class TPtr>
     388              :                 bool operator==(const SmartPtr<TPtr, FreePolicy>& sp) const{
     389              :                         return (this->get() == sp.get());
     390              :                 }
     391              : 
     392              :                 bool operator==(NullSmartPtr) const{
     393              :                         return m_ptr == 0;
     394              :                 }
     395              : 
     396              :                 bool operator!=(const ConstSmartPtr& sp) const{
     397              :                         return !(this->operator==(sp));
     398              :                 }
     399              : 
     400              :                 template <class TPtr>
     401              :                 bool operator!=(const SmartPtr<TPtr, FreePolicy>& sp) const{
     402              :                         return !(this->operator==(sp));
     403              :                 }
     404              : 
     405              :                 bool operator!=(NullSmartPtr) const{
     406              :                         return m_ptr != NULL;
     407              :                 }
     408              : 
     409            0 :                 const T* get() const    {return m_ptr;}
     410              : 
     411              :                 int refcount() const {if(m_refCount) return *m_refCount; return 0;}
     412              : 
     413              :         ///     returns true if the pointer is valid, false if not.
     414            0 :                 inline bool valid() const       {return m_ptr != NULL;}
     415              : 
     416              :                 // pointer compat -- behave like std::shared_ptr<T>
     417              :                 explicit operator bool() const noexcept { return m_ptr != NULL; }
     418              : 
     419              :         ///     returns true if the pointer is invalid, false if not.
     420            0 :                 inline bool invalid() const     {return m_ptr == NULL;}
     421              : 
     422              :         ///     preforms a dynamic cast
     423              :                 template <class TDest>
     424            0 :                 ConstSmartPtr<TDest, FreePolicy> cast_dynamic() const{
     425            0 :                         const TDest* p = dynamic_cast<const TDest*>(m_ptr);
     426            0 :                         if(p) return ConstSmartPtr<TDest, FreePolicy>(p, m_refCount);
     427              :                         else return ConstSmartPtr<TDest, FreePolicy>(NULL);
     428              :                 }
     429              : 
     430              :         ///     performs a static cast
     431              :                 template <class TDest>
     432              :                 ConstSmartPtr<TDest, FreePolicy> cast_static() const{
     433              :                         const TDest* p = static_cast<const TDest*>(m_ptr);
     434              :                         if(p) return ConstSmartPtr<TDest, FreePolicy>(p, m_refCount);
     435              :                         else return ConstSmartPtr<TDest, FreePolicy>(NULL);
     436              :                 }
     437              : 
     438              :         ///     performs a static cast
     439              :                 template <class TDest>
     440              :                 ConstSmartPtr<TDest, FreePolicy> cast_reinterpret() const{
     441              :                         const TDest* p = reinterpret_cast<const TDest*>(m_ptr);
     442              :                         if(p) return ConstSmartPtr<TDest, FreePolicy>(p, m_refCount);
     443              :                         else return ConstSmartPtr<TDest, FreePolicy>(NULL);
     444              :                 }
     445              : 
     446              :         ///     performs a const cast
     447              :                 SmartPtr<T, FreePolicy> cast_const() const{
     448            0 :                         return SmartPtr<T, FreePolicy>(const_cast<T*>(m_ptr), m_refCount);
     449              :                 }
     450              : 
     451              :         ///
     452              :                 template <class TDest>
     453              :                 bool is_of_type() const
     454              :                 {
     455              :                         return dynamic_cast<TDest*>(m_ptr) != NULL;
     456              :                 }
     457              : 
     458              :         ///     WARNING: this method is DANGEROUS!
     459              :         /**     You should only use this constructor if you really know what you're doing!
     460              :          *      The following methods are required for SmartPtr<void> and casts */
     461            0 :                 explicit ConstSmartPtr(const T* ptr, int* refCount) : m_ptr(ptr), m_refCount(refCount)
     462              :                 {
     463            0 :                         if(m_refCount)
     464            0 :                                 (*m_refCount)++;
     465              :                 }
     466              : 
     467              :         ///     WARNING: this method is dangerous!
     468              :         /**     This method should never be used since it may be removed in future
     469              :          *      versions of the SmartPtr class.
     470              :          *      It is featured in order to allow to implement a template-constructor
     471              :          *      that casts element-pointers of a smart pointer.*/
     472            0 :                 int* refcount_ptr() const {return m_refCount;}
     473              : 
     474              :         private:
     475              :         ///     decrements the refCount and frees the encapsulated pointer if required.
     476            0 :                 void release() {
     477            0 :                         if(m_refCount)
     478              :                         {
     479            0 :                                 (*m_refCount)--;
     480            0 :                                 if((*m_refCount) < 1)
     481              :                                 {
     482            0 :                                         delete m_refCount;
     483              :                                         //delete m_ptr;
     484            0 :                                         FreePolicy<T>::free(m_ptr);
     485              :                                 }
     486              :                         }
     487            0 :                 }
     488              : 
     489              :         //      this release method is required by SmartPtr<void>
     490              :                 static void free_void_ptr(void* ptr){
     491              :                         FreePolicy<T>::free(reinterpret_cast<T*>(ptr));
     492              :                 }
     493              : 
     494              :         private:
     495              :                 const T*        m_ptr;
     496              :                 int*            m_refCount;
     497              : };
     498              : /**     \} */
     499              : 
     500              : 
     501              : ///     performs a const cast
     502              : 
     503              : template <typename T, template <class TT> class FreePolicy>
     504              : inline ConstSmartPtr<T, FreePolicy> SmartPtr<T, FreePolicy>::cast_const() const{
     505              :         return ConstSmartPtr<T, FreePolicy>(*this);
     506              : }
     507              : 
     508              : 
     509              : /**     The SmartPtr<void> is a specialization of the SmartPtr class.
     510              :  * It can only be constructed from an existing SmartPtr or from an
     511              :  * existing SmartPtr<void>. This is crucial to guarantee save
     512              :  * release methods.
     513              :  *
     514              :  * In contrary to the original SmartPtr class, the void specialization
     515              :  * does not feature the -> and * operators. One also can't directly access
     516              :  * the encapsulated pointer.
     517              :  *
     518              :  * If you need a const smart pointer use ConstSmartPtr<void>.
     519              :  *
     520              :  * \todo        add to_smart_ptr_dynamic
     521              :  *
     522              :  */
     523              : template <>
     524              : class SmartPtr<void>
     525              : {
     526              :         friend class ConstSmartPtr<void>;
     527              : 
     528              :         public:
     529            0 :                 explicit SmartPtr() : m_ptr(0), m_refCountPtr(0), m_freeFunc(0) {}
     530              : 
     531              :                 SmartPtr(NullSmartPtr) : m_ptr(0), m_refCountPtr(0), m_freeFunc(0)      {}
     532              : 
     533            0 :                 SmartPtr(const SmartPtr<void>& sp) :
     534            0 :                         m_ptr(sp.m_ptr),
     535            0 :                         m_refCountPtr(sp.m_refCountPtr),
     536            0 :                         m_freeFunc(sp.m_freeFunc)
     537              :                 {
     538            0 :                         if(m_refCountPtr) (*m_refCountPtr)++;
     539              :                 }
     540              : 
     541            0 :                 explicit SmartPtr(void* ptr, void (*freeFunc)(const void*)) :
     542            0 :                         m_ptr(ptr),
     543            0 :                         m_refCountPtr(0),
     544            0 :                         m_freeFunc(freeFunc)
     545              :                 {
     546            0 :                         if(ptr) m_refCountPtr = new int(1);
     547              :                 }
     548              : 
     549              :                 template <class T>
     550            0 :                 SmartPtr(const SmartPtr<T>& sp) :
     551            0 :                         m_ptr((void*)sp.m_ptr),
     552            0 :                         m_refCountPtr(sp.m_refCount),
     553            0 :                         m_freeFunc(&SmartPtr<T>::free_void_ptr)
     554              :                 {
     555            0 :                         if(m_refCountPtr) (*m_refCountPtr)++;
     556              :                 }
     557              : 
     558            0 :                 ~SmartPtr() {release();}
     559              : 
     560            0 :                 SmartPtr<void>& operator=(const SmartPtr<void>& sp)
     561              :                 {
     562            0 :                         if(m_ptr)
     563            0 :                                 release();
     564            0 :                         m_ptr = sp.m_ptr;
     565            0 :                         m_refCountPtr = sp.m_refCountPtr;
     566            0 :                         if(m_refCountPtr)
     567            0 :                                 (*m_refCountPtr)++;
     568            0 :                         m_freeFunc = sp.m_freeFunc;
     569            0 :                         return *this;
     570              :                 }
     571              : 
     572              :                 template <class T>
     573              :                 SmartPtr<void>& operator=(const SmartPtr<T>& sp)
     574              :                 {
     575              :                         if(m_ptr)
     576              :                                 release();
     577              :                         m_ptr = sp.m_ptr;
     578              :                         m_refCountPtr = sp.m_refCount;
     579              :                         if(m_refCountPtr)
     580              :                                 (*m_refCountPtr)++;
     581              :                         m_freeFunc = &SmartPtr<T>::free_void_ptr;
     582              :                         return *this;
     583              :                 }
     584              : 
     585              :                 template <class T>
     586              :                 SmartPtr<void>& operator=(NullSmartPtr)
     587              :                 {
     588              :                         if(m_ptr)
     589              :                                 release();
     590              :                         m_ptr = 0;
     591              :                         m_refCountPtr = 0;
     592              :                         m_freeFunc = 0;
     593              :                         return *this;
     594              :                 }
     595              : 
     596              :         ///     Returns a SmartPtr with the specified type and shared reference counting.
     597              :         /**     USE WITH CARE! ONLY COMPATIBLE TYPES SHOULD BE USED*/
     598              :                 template <class T,  template <class TPtr> class TFreePolicy>
     599              :                 SmartPtr<T, TFreePolicy> cast_reinterpret() const {
     600            0 :                         return SmartPtr<T, TFreePolicy>(reinterpret_cast<T*>(m_ptr), m_refCountPtr);
     601              :                 }
     602              : 
     603              :         ///     sets the void* to a different location correspoding to a cast to a new type T
     604              :         /**     !!! WARNING: THIS METHOD IS DANDGEROUS: DO NOT USE IT UNLESS YOU REALLY
     605              :          *               KNOW WHAT YOU ARE DOING !!!
     606              :          */
     607              :                 template <class T, template <class TPtr> class TFreePolicy>
     608              :                 void set_impl(void* ptr)
     609              :                 {
     610            0 :                         m_ptr = ptr;
     611            0 :                         m_freeFunc = &SmartPtr<T, TFreePolicy>::free_void_ptr;
     612              :                 }
     613              : 
     614              :         ///     returns true if the pointer is valid, false if not.
     615            0 :                 inline bool valid() const {return m_ptr != NULL;}
     616              : 
     617              :                 // pointer compat -- behave like std::shared_ptr<T>
     618              :                 explicit operator bool() const noexcept { return m_ptr != NULL; }
     619              : 
     620              :         ///     returns true if the pointer is invalid, false if not.
     621              :                 inline bool invalid() const     {return m_ptr == NULL;}
     622              : 
     623            0 :                 void invalidate()                               {if(valid())    release(); m_ptr = NULL;}
     624              : 
     625            0 :                 void* get()                             {return m_ptr;}
     626              :                 const void* get() const {return m_ptr;}
     627              : 
     628            0 :                 int refcount() const {if(m_refCountPtr) return *m_refCountPtr; return 0;}
     629              : 
     630              :         private:
     631            0 :                 void release() {
     632            0 :                         if(m_refCountPtr)
     633              :                         {
     634            0 :                                 (*m_refCountPtr)--;
     635            0 :                                 if((*m_refCountPtr) < 1)
     636              :                                 {
     637            0 :                                         delete m_refCountPtr;
     638            0 :                                         m_freeFunc(m_ptr);
     639              :                                 }
     640              :                         }
     641            0 :                 }
     642              : 
     643              :                 void* m_ptr;
     644              :                 int* m_refCountPtr;
     645              :                 void (*m_freeFunc)(const void*);
     646              : };
     647              : 
     648              : template <>
     649              : class ConstSmartPtr<void>
     650              : {
     651              :         public:
     652            0 :                 explicit ConstSmartPtr() : m_ptr(0), m_refCountPtr(0), m_freeFunc(0) {}
     653              : 
     654              :                 explicit ConstSmartPtr(void* ptr, void (*freeFunc)(const void*)) :
     655              :                         m_ptr(ptr),
     656              :                         m_refCountPtr(0),
     657              :                         m_freeFunc(freeFunc)
     658              :                 {
     659              :                         if(ptr) m_refCountPtr = new int(1);
     660              :                 }
     661              : 
     662              :                 ConstSmartPtr(NullSmartPtr) : m_ptr(0), m_refCountPtr(0), m_freeFunc(0) {}
     663              : 
     664              :                 ConstSmartPtr(const SmartPtr<void>& sp) :
     665            0 :                         m_ptr(sp.m_ptr),
     666            0 :                         m_refCountPtr(sp.m_refCountPtr),
     667            0 :                         m_freeFunc(sp.m_freeFunc)
     668              :                 {
     669            0 :                         if(m_refCountPtr) (*m_refCountPtr)++;
     670              :                 }
     671              : 
     672            0 :                 ConstSmartPtr(const ConstSmartPtr<void>& sp) :
     673            0 :                         m_ptr(sp.m_ptr),
     674            0 :                         m_refCountPtr(sp.m_refCountPtr),
     675            0 :                         m_freeFunc(sp.m_freeFunc)
     676              :                 {
     677            0 :                         if(m_refCountPtr) (*m_refCountPtr)++;
     678              :                 }
     679              : 
     680              :                 template <class T, template <class TPtr> class TFreePolicy>
     681              :                 ConstSmartPtr(const SmartPtr<T, TFreePolicy>& sp) :
     682              :                         m_ptr((void*)sp.m_ptr),
     683              :                         m_refCountPtr(sp.m_refCount),
     684              :                         m_freeFunc(&SmartPtr<T, TFreePolicy>::free_void_ptr)
     685              :                 {
     686              :                         if(m_refCountPtr) (*m_refCountPtr)++;
     687              :                 }
     688              : 
     689              :                 template <class T, template <class TPtr> class TFreePolicy>
     690            0 :                 ConstSmartPtr(const ConstSmartPtr<T, TFreePolicy>& sp) :
     691            0 :                         m_ptr((void*)sp.m_ptr),
     692            0 :                         m_refCountPtr(sp.m_refCount),
     693            0 :                         m_freeFunc(&SmartPtr<T, TFreePolicy>::free_void_ptr)
     694              :                 {
     695            0 :                         if(m_refCountPtr) (*m_refCountPtr)++;
     696              :                 }
     697              : 
     698            0 :                 ~ConstSmartPtr() {release();}
     699              : 
     700            0 :                 ConstSmartPtr<void>& operator=(const SmartPtr<void>& sp)
     701              :                 {
     702            0 :                         if(m_ptr)
     703            0 :                                 release();
     704            0 :                         m_ptr = sp.m_ptr;
     705            0 :                         m_refCountPtr = sp.m_refCountPtr;
     706            0 :                         if(m_refCountPtr)
     707            0 :                                 (*m_refCountPtr)++;
     708            0 :                         m_freeFunc = sp.m_freeFunc;
     709            0 :                         return *this;
     710              :                 }
     711              : 
     712            0 :                 ConstSmartPtr<void>& operator=(const ConstSmartPtr<void>& sp)
     713              :                 {
     714            0 :                         if(m_ptr)
     715            0 :                                 release();
     716            0 :                         m_ptr = sp.m_ptr;
     717            0 :                         m_refCountPtr = sp.m_refCountPtr;
     718            0 :                         if(m_refCountPtr)
     719            0 :                                 (*m_refCountPtr)++;
     720            0 :                         m_freeFunc = sp.m_freeFunc;
     721            0 :                         return *this;
     722              :                 }
     723              : 
     724              :                 template <class T, template <class TPtr> class TFreePolicy>
     725              :                 ConstSmartPtr<void>& operator=(const SmartPtr<T, TFreePolicy>& sp)
     726              :                 {
     727              :                         if(m_ptr)
     728              :                                 release();
     729              :                         m_ptr = sp.m_ptr;
     730              :                         m_refCountPtr = sp.m_refCount;
     731              :                         if(m_refCountPtr)
     732              :                                 (*m_refCountPtr)++;
     733              :                         m_freeFunc = &SmartPtr<T, TFreePolicy>::free_void_ptr;
     734              :                         return *this;
     735              :                 }
     736              : 
     737              :                 template <class T, template <class TPtr> class TFreePolicy>
     738              :                 ConstSmartPtr<void>& operator=(const ConstSmartPtr<T, TFreePolicy>& sp)
     739              :                 {
     740              :                         if(m_ptr)
     741              :                                 release();
     742              :                         m_ptr = sp.m_ptr;
     743              :                         m_refCountPtr = sp.m_refCount;
     744              :                         if(m_refCountPtr)
     745              :                                 (*m_refCountPtr)++;
     746              :                         m_freeFunc = &SmartPtr<T, TFreePolicy>::free_void_ptr;
     747              :                         return *this;
     748              :                 }
     749              : 
     750              :                 ConstSmartPtr<void>& operator=(NullSmartPtr)
     751              :                 {
     752              :                         if(m_ptr)
     753              :                                 release();
     754              :                         m_ptr = 0;
     755              :                         m_refCountPtr = 0;
     756              :                         m_freeFunc = 0;
     757              :                         return *this;
     758              :                 }
     759              : 
     760              :         ///     Returns a SmartPtr with the specified type and shared reference counting.
     761              :         /**     USE WITH CARE! ONLY COMPATIBLE TYPES SHOULD BE USED*/
     762              :                 template <class T, template <class TPtr> class TFreePolicy>
     763              :                 ConstSmartPtr<T, TFreePolicy> cast_reinterpret() const{
     764            0 :                         return ConstSmartPtr<T, TFreePolicy>(reinterpret_cast<const T*>(m_ptr), m_refCountPtr);
     765              :                 }
     766              : 
     767              :         ///     sets the void* to a different location correspoding to a cast to a new type T
     768              :         /**     !!! WARNING: THIS METHOD IS DANDGEROUS: DO NOT USE IT UNLESS YOU REALLY
     769              :          *               KNOW WHAT YOU ARE DOING !!!
     770              :          */
     771              :                 template <class T, template <class TPtr> class TFreePolicy>
     772              :                 void set_impl(const void* ptr)
     773              :                 {
     774            0 :                         m_ptr = ptr;
     775            0 :                         m_freeFunc = &SmartPtr<T, TFreePolicy>::free_void_ptr;
     776              :                 }
     777              : 
     778              :         ///     returns true if the pointer is valid, false if not.
     779            0 :                 inline bool valid() const {return m_ptr != NULL;}
     780              : 
     781              :                 // pointer compat -- behave like std::shared_ptr<T>
     782              :                 explicit operator bool() const noexcept { return m_ptr != NULL; }
     783              : 
     784              :         ///     returns true if the pointer is invalid, false if not.
     785              :                 inline bool invalid() const     {return m_ptr == NULL;}
     786              : 
     787            0 :                 void invalidate()                               {if(valid())    release(); m_ptr = NULL;}
     788              : 
     789            0 :                 const void* get() const {return m_ptr;}
     790              : 
     791            0 :                 int refcount() const {if(m_refCountPtr) return *m_refCountPtr; return 0;}
     792              : 
     793              :         private:
     794            0 :                 void release() {
     795            0 :                         if(m_refCountPtr)
     796              :                         {
     797            0 :                                 (*m_refCountPtr)--;
     798            0 :                                 if((*m_refCountPtr) < 1)
     799              :                                 {
     800            0 :                                         delete m_refCountPtr;
     801            0 :                                         m_freeFunc(const_cast<void*>(m_ptr));
     802              :                                 }
     803              :                         }
     804            0 :                 }
     805              : 
     806              :                 const void* m_ptr;
     807              :                 int* m_refCountPtr;
     808              :                 void (*m_freeFunc)(const void*);
     809              : };
     810              : 
     811              : 
     812              : 
     813              : namespace std
     814              : {
     815              :         template <class T, template <class TPtr> class TFreePolicy>
     816              :         struct less<SmartPtr<T, TFreePolicy> >
     817              : #if (__cplusplus < 201103L)
     818              :         : public binary_function<SmartPtr<T, TFreePolicy>, SmartPtr<T, TFreePolicy>, bool>
     819              : #endif
     820              :         {
     821              :                 bool operator()(const SmartPtr<T, TFreePolicy>& lhs,
     822              :                                                 const SmartPtr<T, TFreePolicy>& rhs) const
     823              :                 {
     824              :                         return less<T*>()(lhs.get(), rhs.get());
     825              :                 }
     826              :         };
     827              : }
     828              : 
     829              : 
     830              : ////////////////////////////////////////////////////////////////////////
     831              : //      Creation helper for SmartPtr
     832              : ////////////////////////////////////////////////////////////////////////
     833              : 
     834              : /// returns a SmartPtr for the passed raw pointer
     835              : template <typename T, template <class TT> class FreePolicy>
     836              : SmartPtr<T, FreePolicy> make_sp(T* inst)
     837              : {
     838              :         return SmartPtr<T, FreePolicy>(inst);
     839              : }
     840              : 
     841              : /// returns a SmartPtr for the passed raw pointer
     842              : template <typename T>
     843              : SmartPtr<T> make_sp(T* inst)
     844              : {
     845              :         return SmartPtr<T>(inst);
     846              : }
     847              : 
     848              : namespace boost
     849              : {
     850              :   template <class T>
     851              :   struct pointee<SmartPtr<T> >
     852              :   {
     853              :       typedef T type;
     854              :   };
     855              : 
     856              :   template <class T>
     857              :   struct pointee<ConstSmartPtr<T> >
     858              :   {
     859              :       typedef T type;
     860              :   };
     861              : }
     862              : 
     863              : // end group ugbase_common_util
     864              : /// \}
     865              : 
     866              : #endif
        

Generated by: LCOV version 2.0-1