00001 /* 00002 * Copyright (C) Sergey P. Derevyago, 2003-2004. 00003 * 00004 * Permission to copy, use, modify, sell and distribute this software is granted 00005 * provided this copyright notice appears in all copies. 00006 * This software is provided "as is" without express or implied warranty, and 00007 * with no claim as to its suitability for any purpose. 00008 * 00009 */ 00010 00015 #ifndef __SH_PTR_HPP__ 00016 #define __SH_PTR_HPP__ 00017 00018 #include "fix_alloc.hpp" 00019 00028 template <class T> 00029 class sh_ptr { 00031 struct Rep { 00033 T* ptr; 00035 size_t refs; 00036 00038 Rep(T* ptr_) : ptr(ptr_), refs(1) {} 00039 00041 ~Rep() { delete ptr; } 00042 00044 void* operator new(size_t) 00045 { 00046 return fixed_alloc<Rep>::alloc(); 00047 } 00048 00050 void operator delete(void* ptr, size_t) 00051 { 00052 fixed_alloc<Rep>::free(ptr); 00053 } 00054 }; 00055 00057 Rep* rep; 00058 00059 public: 00070 explicit sh_ptr(T* ptr=0) 00071 { 00072 try { rep=new Rep(ptr); } 00073 catch (...) { 00074 delete ptr; 00075 throw; 00076 } 00077 } 00078 00083 sh_ptr(const sh_ptr& shp) 00084 { 00085 rep=shp.rep; 00086 rep->refs++; 00087 } 00088 00093 ~sh_ptr() { if (--rep->refs==0) delete rep; } 00094 00100 sh_ptr& operator=(const sh_ptr& shp) 00101 { 00102 shp.rep->refs++; 00103 if (--rep->refs==0) delete rep; 00104 rep=shp.rep; 00105 00106 return *this; 00107 } 00108 00112 void swap(sh_ptr& shp) 00113 { 00114 Rep* tmp=rep; 00115 rep=shp.rep; 00116 shp.rep=tmp; 00117 } 00118 00123 T& operator*() const { return *rep->ptr; } 00124 00129 T* operator->() const { return rep->ptr; } 00130 00134 T* get() const { return rep->ptr; } 00135 00140 void set(T* ptr) { rep->ptr=ptr; } 00141 00145 size_t refs() const { return rep->refs; } 00146 }; 00147 00158 template <class T> 00159 class sh_array { 00161 struct Rep { 00163 T* ptr; 00165 size_t refs; 00166 00168 Rep(T* ptr_) : ptr(ptr_), refs(1) {} 00169 00171 ~Rep() { delete [] ptr; } 00172 00174 void* operator new(size_t) 00175 { 00176 return fixed_alloc<Rep>::alloc(); 00177 } 00178 00180 void operator delete(void* ptr, size_t) 00181 { 00182 fixed_alloc<Rep>::free(ptr); 00183 } 00184 }; 00185 00187 Rep* rep; 00188 00189 public: 00196 explicit sh_array(T* ptr=0) 00197 { 00198 try { rep=new Rep(ptr); } 00199 catch (...) { 00200 delete [] ptr; 00201 throw; 00202 } 00203 } 00204 00209 sh_array(const sh_array& sha) 00210 { 00211 rep=sha.rep; 00212 rep->refs++; 00213 } 00214 00219 ~sh_array() { if (--rep->refs==0) delete rep; } 00220 00226 sh_array& operator=(const sh_array& sha) 00227 { 00228 sha.rep->refs++; 00229 if (--rep->refs==0) delete rep; 00230 rep=sha.rep; 00231 00232 return *this; 00233 } 00234 00238 void swap(sh_array& sha) 00239 { 00240 Rep* tmp=rep; 00241 rep=sha.rep; 00242 sha.rep=tmp; 00243 } 00244 00248 T& operator[](size_t i) const { return rep->ptr[i]; } 00249 00253 T* get() const { return rep->ptr; } 00254 00259 void set(T* ptr) { rep->ptr=ptr; } 00260 00264 size_t refs() const { return rep->refs; } 00265 }; 00266 00267 #endif