smartptr.h

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

Generated on Sat Dec 23 02:07:10 2006 for Crypto++ by  doxygen 1.5.1-p1