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