Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

smartptr.h

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);           // copy not allowed
00036         void operator=(const member_ptr<T>& rhs);       // assignment not allowed
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);     // copy not allowed
00207         void operator=(const vector_member_ptrs<T> &x);         // assignment not allowed
00208 
00209         unsigned int _size;
00210         member_ptr<T> *ptr;
00211 };
00212 
00213 NAMESPACE_END
00214 
00215 #endif

Generated on Sun Mar 14 20:44:29 2004 for Crypto++ by doxygen 1.3.6-20040222