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

# 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 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