00001
00002
00003
00004
00005
00006
00007 #ifndef CRYPTOPP_SMARTPTR_H
00008 #define CRYPTOPP_SMARTPTR_H
00009
00010 #include "config.h"
00011 #include "stdcpp.h"
00012
00013 NAMESPACE_BEGIN(CryptoPP)
00014
00015
00016
00017
00018
00019
00020 template <class T> class simple_ptr
00021 {
00022 public:
00023 simple_ptr(T *p = NULL) : m_p(p) {}
00024 ~simple_ptr()
00025 {
00026 delete m_p;
00027 *((volatile T**)&m_p) = NULL;
00028 }
00029
00030 T *m_p;
00031 };
00032
00033
00034
00035
00036
00037
00038
00039 template <class T> class member_ptr
00040 {
00041 public:
00042 explicit member_ptr(T *p = NULL) : m_p(p) {}
00043
00044 ~member_ptr();
00045
00046 const T& operator*() const { return *m_p; }
00047 T& operator*() { return *m_p; }
00048
00049 const T* operator->() const { return m_p; }
00050 T* operator->() { return m_p; }
00051
00052 const T* get() const { return m_p; }
00053 T* get() { return m_p; }
00054
00055 T* release()
00056 {
00057 T *old_p = m_p;
00058 *((volatile T**)&m_p) = NULL;
00059 return old_p;
00060 }
00061
00062 void reset(T *p = 0);
00063
00064 protected:
00065 member_ptr(const member_ptr<T>& rhs);
00066 void operator=(const member_ptr<T>& rhs);
00067
00068 T *m_p;
00069 };
00070
00071 template <class T> member_ptr<T>::~member_ptr() {delete m_p;}
00072 template <class T> void member_ptr<T>::reset(T *p) {delete m_p; m_p = p;}
00073
00074
00075
00076
00077
00078
00079 template<class T> class value_ptr : public member_ptr<T>
00080 {
00081 public:
00082 value_ptr(const T &obj) : member_ptr<T>(new T(obj)) {}
00083 value_ptr(T *p = NULL) : member_ptr<T>(p) {}
00084 value_ptr(const value_ptr<T>& rhs)
00085 : member_ptr<T>(rhs.m_p ? new T(*rhs.m_p) : NULL) {}
00086
00087 value_ptr<T>& operator=(const value_ptr<T>& rhs);
00088 bool operator==(const value_ptr<T>& rhs)
00089 {
00090 return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p);
00091 }
00092 };
00093
00094 template <class T> value_ptr<T>& value_ptr<T>::operator=(const value_ptr<T>& rhs)
00095 {
00096 T *old_p = this->m_p;
00097 this->m_p = rhs.m_p ? new T(*rhs.m_p) : NULL;
00098 delete old_p;
00099 return *this;
00100 }
00101
00102
00103
00104
00105
00106
00107
00108 template<class T> class clonable_ptr : public member_ptr<T>
00109 {
00110 public:
00111 clonable_ptr(const T &obj) : member_ptr<T>(obj.Clone()) {}
00112 clonable_ptr(T *p = NULL) : member_ptr<T>(p) {}
00113 clonable_ptr(const clonable_ptr<T>& rhs)
00114 : member_ptr<T>(rhs.m_p ? rhs.m_p->Clone() : NULL) {}
00115
00116 clonable_ptr<T>& operator=(const clonable_ptr<T>& rhs);
00117 };
00118
00119 template <class T> clonable_ptr<T>& clonable_ptr<T>::operator=(const clonable_ptr<T>& rhs)
00120 {
00121 T *old_p = this->m_p;
00122 this->m_p = rhs.m_p ? rhs.m_p->Clone() : NULL;
00123 delete old_p;
00124 return *this;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134 template<class T> class counted_ptr
00135 {
00136 public:
00137 explicit counted_ptr(T *p = 0);
00138 counted_ptr(const T &r) : m_p(0) {attach(r);}
00139 counted_ptr(const counted_ptr<T>& rhs);
00140
00141 ~counted_ptr();
00142
00143 const T& operator*() const { return *m_p; }
00144 T& operator*() { return *m_p; }
00145
00146 const T* operator->() const { return m_p; }
00147 T* operator->() { return get(); }
00148
00149 const T* get() const { return m_p; }
00150 T* get();
00151
00152 void attach(const T &p);
00153
00154 counted_ptr<T> & operator=(const counted_ptr<T>& rhs);
00155
00156 private:
00157 T *m_p;
00158 };
00159
00160 template <class T> counted_ptr<T>::counted_ptr(T *p)
00161 : m_p(p)
00162 {
00163 if (m_p)
00164 m_p->m_referenceCount = 1;
00165 }
00166
00167 template <class T> counted_ptr<T>::counted_ptr(const counted_ptr<T>& rhs)
00168 : m_p(rhs.m_p)
00169 {
00170 if (m_p)
00171 m_p->m_referenceCount++;
00172 }
00173
00174 template <class T> counted_ptr<T>::~counted_ptr()
00175 {
00176 if (m_p && --m_p->m_referenceCount == 0)
00177 delete m_p;
00178 }
00179
00180 template <class T> void counted_ptr<T>::attach(const T &r)
00181 {
00182 if (m_p && --m_p->m_referenceCount == 0)
00183 delete m_p;
00184 if (r.m_referenceCount == 0)
00185 {
00186 m_p = r.clone();
00187 m_p->m_referenceCount = 1;
00188 }
00189 else
00190 {
00191 m_p = const_cast<T *>(&r);
00192 m_p->m_referenceCount++;
00193 }
00194 }
00195
00196 template <class T> T* counted_ptr<T>::get()
00197 {
00198 if (m_p && m_p->m_referenceCount > 1)
00199 {
00200 T *temp = m_p->clone();
00201 m_p->m_referenceCount--;
00202 m_p = temp;
00203 m_p->m_referenceCount = 1;
00204 }
00205 return m_p;
00206 }
00207
00208 template <class T> counted_ptr<T> & counted_ptr<T>::operator=(const counted_ptr<T>& rhs)
00209 {
00210 if (m_p != rhs.m_p)
00211 {
00212 if (m_p && --m_p->m_referenceCount == 0)
00213 delete m_p;
00214 m_p = rhs.m_p;
00215 if (m_p)
00216 m_p->m_referenceCount++;
00217 }
00218 return *this;
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 template <class T> class vector_ptr
00230 {
00231 public:
00232
00233
00234
00235 vector_ptr(size_t size=0)
00236 : m_size(size), m_ptr(new T[m_size]) {}
00237 ~vector_ptr()
00238 {delete [] m_ptr;}
00239
00240 T& operator[](size_t index)
00241 {assert(m_size && index<this->m_size); return this->m_ptr[index];}
00242 const T& operator[](size_t index) const
00243 {assert(m_size && index<this->m_size); return this->m_ptr[index];}
00244
00245 size_t size() const {return this->m_size;}
00246 void resize(size_t newSize)
00247 {
00248 T *newPtr = new T[newSize];
00249 for (size_t i=0; i<this->m_size && i<newSize; i++)
00250 newPtr[i] = m_ptr[i];
00251 delete [] this->m_ptr;
00252 this->m_size = newSize;
00253 this->m_ptr = newPtr;
00254 }
00255
00256 #ifdef __BORLANDC__
00257 operator T *() const
00258 {return (T*)m_ptr;}
00259 #else
00260 operator const void *() const
00261 {return m_ptr;}
00262 operator void *()
00263 {return m_ptr;}
00264
00265 operator const T *() const
00266 {return m_ptr;}
00267 operator T *()
00268 {return m_ptr;}
00269 #endif
00270
00271 private:
00272 vector_ptr(const vector_ptr<T> &c);
00273 void operator=(const vector_ptr<T> &x);
00274
00275 size_t m_size;
00276 T *m_ptr;
00277 };
00278
00279
00280
00281
00282
00283
00284 template <class T> class vector_member_ptrs
00285 {
00286 public:
00287
00288
00289
00290 vector_member_ptrs(size_t size=0)
00291 : m_size(size), m_ptr(new member_ptr<T>[size]) {}
00292 ~vector_member_ptrs()
00293 {delete [] this->m_ptr;}
00294
00295 member_ptr<T>& operator[](size_t index)
00296 {assert(index<this->m_size); return this->m_ptr[index];}
00297 const member_ptr<T>& operator[](size_t index) const
00298 {assert(index<this->m_size); return this->m_ptr[index];}
00299
00300 size_t size() const {return this->m_size;}
00301 void resize(size_t newSize)
00302 {
00303 member_ptr<T> *newPtr = new member_ptr<T>[newSize];
00304 for (size_t i=0; i<this->m_size && i<newSize; i++)
00305 newPtr[i].reset(this->m_ptr[i].release());
00306 delete [] this->m_ptr;
00307 this->m_size = newSize;
00308 this->m_ptr = newPtr;
00309 }
00310
00311 private:
00312 vector_member_ptrs(const vector_member_ptrs<T> &c);
00313 void operator=(const vector_member_ptrs<T> &x);
00314
00315 size_t m_size;
00316 member_ptr<T> *m_ptr;
00317 };
00318
00319 NAMESPACE_END
00320
00321 #endif