00001 #ifndef CRYPTOPP_SMARTPTR_H
00002 #define CRYPTOPP_SMARTPTR_H
00003
00004 #include "config.h"
00005 #include <algorithm>
00006
00007 NAMESPACE_BEGIN(CryptoPP)
00008
00009 template <class T> class simple_ptr
00010 {
00011 public:
00012 simple_ptr(T *p = NULL) : m_p(p) {}
00013 ~simple_ptr() {delete m_p; m_p = NULL;}
00014 T *m_p;
00015 };
00016
00017 template <class T> class member_ptr
00018 {
00019 public:
00020 explicit member_ptr(T *p = NULL) : m_p(p) {}
00021
00022 ~member_ptr();
00023
00024 const T& operator*() const { return *m_p; }
00025 T& operator*() { return *m_p; }
00026
00027 const T* operator->() const { return m_p; }
00028 T* operator->() { return m_p; }
00029
00030 const T* get() const { return m_p; }
00031 T* get() { return m_p; }
00032
00033 T* release()
00034 {
00035 T *old_p = m_p;
00036 m_p = 0;
00037 return old_p;
00038 }
00039
00040 void reset(T *p = 0);
00041
00042 protected:
00043 member_ptr(const member_ptr<T>& rhs);
00044 void operator=(const member_ptr<T>& rhs);
00045
00046 T *m_p;
00047 };
00048
00049 template <class T> member_ptr<T>::~member_ptr() {delete m_p;}
00050 template <class T> void member_ptr<T>::reset(T *p) {delete m_p; m_p = p;}
00051
00052
00053
00054 template<class T> class value_ptr : public member_ptr<T>
00055 {
00056 public:
00057 value_ptr(const T &obj) : member_ptr<T>(new T(obj)) {}
00058 value_ptr(T *p = NULL) : member_ptr<T>(p) {}
00059 value_ptr(const value_ptr<T>& rhs)
00060 : member_ptr<T>(rhs.m_p ? new T(*rhs.m_p) : NULL) {}
00061
00062 value_ptr<T>& operator=(const value_ptr<T>& rhs);
00063 bool operator==(const value_ptr<T>& rhs)
00064 {
00065 return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p);
00066 }
00067 };
00068
00069 template <class T> value_ptr<T>& value_ptr<T>::operator=(const value_ptr<T>& rhs)
00070 {
00071 T *old_p = this->m_p;
00072 this->m_p = rhs.m_p ? new T(*rhs.m_p) : NULL;
00073 delete old_p;
00074 return *this;
00075 }
00076
00077
00078
00079 template<class T> class clonable_ptr : public member_ptr<T>
00080 {
00081 public:
00082 clonable_ptr(const T &obj) : member_ptr<T>(obj.Clone()) {}
00083 clonable_ptr(T *p = NULL) : member_ptr<T>(p) {}
00084 clonable_ptr(const clonable_ptr<T>& rhs)
00085 : member_ptr<T>(rhs.m_p ? rhs.m_p->Clone() : NULL) {}
00086
00087 clonable_ptr<T>& operator=(const clonable_ptr<T>& rhs);
00088 };
00089
00090 template <class T> clonable_ptr<T>& clonable_ptr<T>::operator=(const clonable_ptr<T>& rhs)
00091 {
00092 T *old_p = this->m_p;
00093 this->m_p = rhs.m_p ? rhs.m_p->Clone() : NULL;
00094 delete old_p;
00095 return *this;
00096 }
00097
00098
00099
00100 template<class T> class counted_ptr
00101 {
00102 public:
00103 explicit counted_ptr(T *p = 0);
00104 counted_ptr(const T &r) : m_p(0) {attach(r);}
00105 counted_ptr(const counted_ptr<T>& rhs);
00106
00107 ~counted_ptr();
00108
00109 const T& operator*() const { return *m_p; }
00110 T& operator*() { return *m_p; }
00111
00112 const T* operator->() const { return m_p; }
00113 T* operator->() { return get(); }
00114
00115 const T* get() const { return m_p; }
00116 T* get();
00117
00118 void attach(const T &p);
00119
00120 counted_ptr<T> & operator=(const counted_ptr<T>& rhs);
00121
00122 private:
00123 T *m_p;
00124 };
00125
00126 template <class T> counted_ptr<T>::counted_ptr(T *p)
00127 : m_p(p)
00128 {
00129 if (m_p)
00130 m_p->m_referenceCount = 1;
00131 }
00132
00133 template <class T> counted_ptr<T>::counted_ptr(const counted_ptr<T>& rhs)
00134 : m_p(rhs.m_p)
00135 {
00136 if (m_p)
00137 m_p->m_referenceCount++;
00138 }
00139
00140 template <class T> counted_ptr<T>::~counted_ptr()
00141 {
00142 if (m_p && --m_p->m_referenceCount == 0)
00143 delete m_p;
00144 }
00145
00146 template <class T> void counted_ptr<T>::attach(const T &r)
00147 {
00148 if (m_p && --m_p->m_referenceCount == 0)
00149 delete m_p;
00150 if (r.m_referenceCount == 0)
00151 {
00152 m_p = r.clone();
00153 m_p->m_referenceCount = 1;
00154 }
00155 else
00156 {
00157 m_p = const_cast<T *>(&r);
00158 m_p->m_referenceCount++;
00159 }
00160 }
00161
00162 template <class T> T* counted_ptr<T>::get()
00163 {
00164 if (m_p && m_p->m_referenceCount > 1)
00165 {
00166 T *temp = m_p->clone();
00167 m_p->m_referenceCount--;
00168 m_p = temp;
00169 m_p->m_referenceCount = 1;
00170 }
00171 return m_p;
00172 }
00173
00174 template <class T> counted_ptr<T> & counted_ptr<T>::operator=(const counted_ptr<T>& rhs)
00175 {
00176 if (m_p != rhs.m_p)
00177 {
00178 if (m_p && --m_p->m_referenceCount == 0)
00179 delete m_p;
00180 m_p = rhs.m_p;
00181 if (m_p)
00182 m_p->m_referenceCount++;
00183 }
00184 return *this;
00185 }
00186
00187
00188
00189 template <class T> class vector_member_ptrs
00190 {
00191 public:
00192 vector_member_ptrs(size_t size=0)
00193 : m_size(size), m_ptr(new member_ptr<T>[size]) {}
00194 ~vector_member_ptrs()
00195 {delete [] this->m_ptr;}
00196
00197 member_ptr<T>& operator[](size_t index)
00198 {assert(index<this->m_size); return this->m_ptr[index];}
00199 const member_ptr<T>& operator[](size_t index) const
00200 {assert(index<this->m_size); return this->m_ptr[index];}
00201
00202 size_t size() const {return this->m_size;}
00203 void resize(size_t newSize)
00204 {
00205 member_ptr<T> *newPtr = new member_ptr<T>[newSize];
00206 for (size_t i=0; i<this->m_size && i<newSize; i++)
00207 newPtr[i].reset(this->m_ptr[i].release());
00208 delete [] this->m_ptr;
00209 this->m_size = newSize;
00210 this->m_ptr = newPtr;
00211 }
00212
00213 private:
00214 vector_member_ptrs(const vector_member_ptrs<T> &c);
00215 void operator=(const vector_member_ptrs<T> &x);
00216
00217 size_t m_size;
00218 member_ptr<T> *m_ptr;
00219 };
00220
00221 NAMESPACE_END
00222
00223 #endif