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() : m_p(NULL) {} 00013 ~simple_ptr() {delete m_p;} 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); // copy not allowed 00044 void operator=(const member_ptr<T>& rhs); // assignment not allowed 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(unsigned int 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[](unsigned int index) 00198 {assert(index<this->m_size); return this->m_ptr[index];} 00199 const member_ptr<T>& operator[](unsigned int index) const 00200 {assert(index<this->m_size); return this->m_ptr[index];} 00201 00202 unsigned int size() const {return this->m_size;} 00203 void resize(unsigned int newSize) 00204 { 00205 member_ptr<T> *newPtr = new member_ptr<T>[newSize]; 00206 for (unsigned int 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); // copy not allowed 00215 void operator=(const vector_member_ptrs<T> &x); // assignment not allowed 00216 00217 unsigned int m_size; 00218 member_ptr<T> *m_ptr; 00219 }; 00220 00221 NAMESPACE_END 00222 00223 #endif