Crypto++

- Main Page
- Namespaces
- Classes
- Files

- File List
- 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 simple_ptr
    00010 {
    00011 public:
    00012     simple_ptr(T *p = NULL) : m_p(p) {}
    00013     ~simple_ptr() {delete m_p; m_p = NULL;}     // set m_p to NULL so double destruction (which might occur in Singleton) will be harmless
    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(size_t 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[](size_t index)
    00198         {assert(index<this->m_size); return this->m_ptr[index];}
    00199     const member_ptr<T>& operator[](size_t index) const
    00200         {assert(index<this->m_size); return this->m_ptr[index];}
    00201
    00202     size_t size() const {return this->m_size;}
    00203     void resize(size_t newSize)
    00204     {
    00205         member_ptr<T> *newPtr = new member_ptr<T>[newSize];
    00206         for (size_t 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     size_t m_size;
    00218     member_ptr<T> *m_ptr;
    00219 };
    00220
    00221 NAMESPACE_END
    00222
    00223 #endif