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