Heidelberg Educational Numerics Library Version 0.24 (from 9 September 2011)

src/countingptr.hh

Go to the documentation of this file.
00001 // -*- tab-width: 4; indent-tabs-mode: nil -*-
00002 #ifndef HDNUM_COUNTINGPTR_HH
00003 #define HDNUM_COUNTINGPTR_HH
00004 
00005 #include <iostream>
00006 
00013 namespace hdnum {
00014 
00021     class NondeletingMemoryManagementPolicy
00022         {
00023         public:
00024           template<typename T>
00025           static void delete_action (T* p)
00026           {}
00027         };
00028 
00035         class DeletingMemoryManagementPolicy
00036         {
00037         public:
00038           template<typename T>
00039           static void delete_action (T* p)
00040           {
00041                 if (p->reference_counter_zero())
00042                   delete p;
00043           }
00044         };
00045 
00046         template<typename T, typename P=DeletingMemoryManagementPolicy>
00069         class CP
00070         {
00071           T* p;
00072 
00073         public:
00075           CP ()
00076           {
00077                 p = 0;
00078           }
00079 
00081           explicit CP (T* p_)
00082           {
00083                 p = p_;
00084                 if (p!=0)
00085                   p->reference_counter_increment();
00086           }
00087 
00089           CP (const CP<T>& cp)
00090           {
00091                 p = cp.p;
00092                 if (p!=0)
00093                   p->reference_counter_increment();
00094           }
00095 
00097           ~CP ()
00098           {
00099                 if (p!=0)
00100                   {
00101                         p->reference_counter_decrement();
00102                         P::delete_action(p);
00103                   }
00104           }
00105 
00107           CP<T>& operator= (T* p_)
00108           {
00109                 if (p!=p_)
00110                   {
00111                         if (p!=0)
00112                           p->reference_counter_decrement();
00113                         p = p_;
00114                         if (p!=0)
00115                           p->reference_counter_increment();
00116                   }
00117                 return *this;
00118           }
00119 
00121           CP<T>& operator= (const CP<T>& cp)
00122           {
00123                 if (p!=cp.p)
00124                   {
00125                         if (p!=0)
00126                           p->reference_counter_decrement();
00127                         p = cp.p;
00128                         if (p!=0)
00129                           p->reference_counter_increment();
00130                   }
00131                 return *this;           
00132           }
00133 
00135           T* operator-> () const
00136           {
00137                 return p;
00138           }
00139 
00141           T& operator* () const
00142           {
00143                 return *p;
00144           }
00145 
00147           bool operator== (const CP<T>& cp) const
00148           {
00149                 return p==cp.p;
00150           }
00151 
00153           bool operator!= (const CP<T>& cp) const
00154           {
00155                 return p!=cp.p;
00156           }
00157 
00158         };
00159 
00160         class CountableException
00161         {
00162           int counter;
00163         public:
00164           CountableException (int i) : counter(i) {}
00165           int get_counter () const
00166           {
00167                 return counter;
00168           }
00169         };
00170 
00176         class Countable 
00177         {
00178           mutable int counter;
00179 
00180         public:
00181 
00183           Countable () : counter(0) 
00184           {
00185           }
00186 
00188           Countable (const Countable& )
00189           {
00190                 counter = 0;
00191           } 
00192 
00194           Countable& operator= (const Countable& )
00195           {
00196         return *this;
00197           } 
00198 
00200           void reference_counter_increment () const
00201           {
00202                 counter++;
00203           }
00204 
00206           void reference_counter_decrement () const
00207           {
00208                 counter--;
00209           }
00210 
00212           bool reference_counter_zero () const
00213           {
00214                 return counter==0;
00215           }
00216 
00218           int get_reference_counter () const
00219           {
00220                 return counter;
00221           }
00222 
00227           ~Countable ()
00228           {
00229                 if (counter!=0)
00230                   {
00231                         std::cout << counter << " counting pointer(s) point to object at "
00232                                           << this << " while it is deleted" << std::endl;
00233             throw CountableException(counter);
00234                   }
00235           }
00236         };
00237 
00238 } // namespace hdnum
00239 
00240 #endif