00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #ifndef EXPRESSO_MULTIPTR_HDR
00022 #define EXPRESSO_MULTIPTR_HDR
00023 
00024 namespace esso {
00025 
00026   template<class T>
00027   struct MultiPtr_Block {
00028     inline T *Data() { return data; }
00029       
00030     inline void Attach() { ++counter; }
00031     inline void Detach() { if(--counter==0) delete this; }
00032       
00033     inline MultiPtr_Block(unsigned size0): counter(0), data(0) {
00034       data=new T[size0];
00035     }
00036     inline ~MultiPtr_Block() { delete [] data; }
00037   protected:
00038     unsigned counter;
00039     T *data;
00040   };
00041 
00043 
00044   template<class T>
00045   class MultiPtr {
00046 
00047 
00048 
00049 
00050   private:
00051   public:
00052     friend class MultiPtr<const T>;
00053     inline T * Data() const { return block ? block->Data() : 0; }
00054     inline void clear() {
00055       if(block) {
00056         block->Detach();
00057         block = 0;
00058       }
00059     }
00060     inline MultiPtr & operator =(const MultiPtr &src) {
00061       MultiPtr_Block<T> *tmp=block; 
00062       block=src.block;
00063       if(block)
00064         block->Attach();
00065       if(tmp)
00066         tmp->Detach();
00067       return *this;
00068     }
00069     inline MultiPtr(): block(0) {}
00070     inline MultiPtr(unsigned size0): block(0) { 
00071       if(size0) {
00072         block = new MultiPtr_Block<T>(size0);
00073         block->Attach(); 
00074       }
00075     }
00076     inline MultiPtr(const MultiPtr &src): block(src.block) { 
00077       if(block) block->Attach();
00078     }
00079     inline ~MultiPtr() { if(block) block->Detach(); }
00080   private:
00081     MultiPtr_Block<T> *block;
00082   };
00083 
00084   template<class T>
00085   class MultiPtr<const T> {
00086   public:
00087     inline const T * Data() const { return block ? block->Data(): 0; }
00088     inline void clear() {
00089       if(block) {
00090         block->Detach();
00091         block = 0;
00092       }
00093     }
00094     inline MultiPtr & operator =(const MultiPtr &src) {
00095       MultiPtr_Block<T> *tmp=block; 
00096       block=src.block;
00097       if(block)
00098         block->Attach();
00099       if(tmp)
00100         tmp->Detach();
00101       return *this;
00102     }
00103     inline MultiPtr & operator =(const MultiPtr<T> &src) {
00104       MultiPtr_Block<T> *tmp=block; 
00105       block=src.block;
00106       if(block)
00107         block->Attach();
00108       if(tmp)
00109         tmp->Detach();
00110       return *this;
00111     }
00112     inline MultiPtr(): block(0) {}
00113     inline MultiPtr(unsigned size0): block(0) { 
00114       if(size0) {
00115         block = new MultiPtr_Block<T>(size0);
00116         block->Attach(); 
00117       }
00118     }
00119     inline MultiPtr(const MultiPtr &src): block(src.block) { 
00120       if(block) block->Attach(); 
00121     }
00122     inline MultiPtr(const MultiPtr<T> &src): block(src.block) { 
00123       if(block) block->Attach(); 
00124     }
00125     inline ~MultiPtr() { if(block) block->Detach(); }
00126   private:
00127     MultiPtr_Block<T> *block;
00128   };
00129 
00130 }
00131 #endif