Go to Overview over all GrAL packages.
Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Utility/reference-count.h

Go to the documentation of this file.
00001 #ifndef NMWR_GB_COPY_ON_WRITE_PTR_H
00002 #define NMWR_GB_COPY_ON_WRITE_PTR_H
00003 
00004 // $LICENSE
00005 
00006 
00007 
00008 
00017 #include "Utility/copy-traits.h"
00018 
00019 
00025 class  counted_obj {                      
00026 public:                               
00027   void operator++() { ++count;}
00028   void operator--() {
00029     if (--count == 0) 
00030       delete this; // calls d'tor of derived class (virtual d'tor!)
00031   } 
00032   bool is_shared() const { return (count > 1);}
00033 
00034 protected:
00035   counted_obj() : count(0) {}
00036   virtual ~counted_obj() {} // virtual is essential, see op-- above!
00037 
00038 private:
00039   unsigned  count;
00040 
00041   // Forbidden
00042   counted_obj(counted_obj const&);
00043   counted_obj& operator=(counted_obj const&);
00044 };
00045 
00046 
00047 
00054 template<class T>
00055 class copy_on_write_ptr {
00056 public:
00057   copy_on_write_ptr(T* pt = 0);
00058   copy_on_write_ptr(const copy_on_write_ptr<T>& rhs) 
00059     : counter(rhs.counter) {init();}
00060   copy_on_write_ptr<T>& operator=(const copy_on_write_ptr<T>& rhs);
00061   ~copy_on_write_ptr() { --(*counter); }
00062 
00063   const T* operator->() const  {          return  (counter->T_ptr);}
00064   const T& operator*()  const  {          return *(counter->T_ptr);}
00065 
00066         T& operator*()         { copy();  return *(counter->T_ptr);}       
00067         T* operator->()        { copy();  return  (counter->T_ptr);}
00068 
00069 private:
00070   struct holder: public  counted_obj {
00071     ~holder() { copy_traits<T>::destroy(T_ptr); }
00072     T *T_ptr;
00073   };
00074   
00075   holder *counter;
00076   void init() { ++(*counter);}
00077   void copy();                          
00078 };
00079 
00080 
00081 template<class T>
00082 inline copy_on_write_ptr<T>::copy_on_write_ptr(T* pt)
00083 : counter(new holder)
00084 { 
00085   counter->T_ptr = pt;
00086   init();
00087 }
00088 
00089 template<class T>
00090 inline copy_on_write_ptr<T>& 
00091 copy_on_write_ptr<T>::operator=(const copy_on_write_ptr<T>& rhs)
00092 {
00093   if (counter != rhs.counter) {                   
00094     --(*counter);
00095     counter = rhs.counter;
00096     init();
00097   }
00098   return *this;
00099 }
00100 
00101 template<class T>                             
00102 inline void copy_on_write_ptr<T>::copy()                    
00103 { 
00104   if(counter->is_shared()) {                                            
00105     T * old_T_ptr = counter->T_ptr;           
00106     --(*counter);
00107     counter = new holder;
00108     counter->T_ptr = copy_traits<T>::clone(*old_T_ptr);
00109     ++(*counter);
00110   }
00111 }
00112 
00113 
00114 #endif

Copyright (c) Guntram Berti 1997-2002. See the GrAL Homepage for up-to-date information.

Generated at Tue Feb 26 15:57:02 2002 for Utilities by doxygen 1.2.11-20011104 written by Dimitri van Heesch, © 1997-2000