Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:09

0001 // smartptr.h - originally written and placed in the public domain by Wei Dai

0002 
0003 /// \file smartptr.h

0004 /// \brief Classes for automatic resource management

0005 
0006 #ifndef CRYPTOPP_SMARTPTR_H
0007 #define CRYPTOPP_SMARTPTR_H
0008 
0009 #include "config.h"
0010 #include "stdcpp.h"
0011 
0012 NAMESPACE_BEGIN(CryptoPP)
0013 
0014 /// \brief Manages resources for a single object

0015 /// \tparam T class or type

0016 /// \details \p simple_ptr is used frequently in the library to manage resources and

0017 ///   ensure cleanup under the RAII pattern (Resource Acquisition Is Initialization).

0018 template <class T> class simple_ptr
0019 {
0020 public:
0021     simple_ptr(T *p = NULLPTR) : m_p(p) {}
0022     ~simple_ptr()
0023     {
0024         delete m_p;
0025         m_p = NULLPTR;
0026     }
0027 
0028     T *m_p;
0029 };
0030 
0031 /// \brief Pointer that overloads operator ->

0032 /// \tparam T class or type

0033 /// \details member_ptr is used frequently in the library to avoid the issues related to

0034 ///  std::auto_ptr in C++11 (deprecated) and std::unique_ptr in C++03 (non-existent).

0035 /// \bug <a href="http://github.com/weidai11/cryptopp/issues/48">Issue 48: "Use of auto_ptr

0036 ///  causes dirty compile under C++11"</a>

0037 template <class T> class member_ptr
0038 {
0039 public:
0040     explicit member_ptr(T *p = NULLPTR) : m_p(p) {}
0041 
0042     ~member_ptr();
0043 
0044     const T& operator*() const { return *m_p; }
0045     T& operator*() { return *m_p; }
0046 
0047     const T* operator->() const { return m_p; }
0048     T* operator->() { return m_p; }
0049 
0050     const T* get() const { return m_p; }
0051     T* get() { return m_p; }
0052 
0053     T* release()
0054     {
0055         T *old_p = m_p;
0056         m_p = NULLPTR;
0057         return old_p;
0058     }
0059 
0060     void reset(T *p = NULLPTR);
0061 
0062 protected:
0063     member_ptr(const member_ptr<T>& rhs);       // copy not allowed

0064     void operator=(const member_ptr<T>& rhs);   // assignment not allowed

0065 
0066     T *m_p;
0067 };
0068 
0069 template <class T> member_ptr<T>::~member_ptr() {delete m_p;}
0070 template <class T> void member_ptr<T>::reset(T *p) {delete m_p; m_p = p;}
0071 
0072 // ********************************************************

0073 
0074 /// \brief Value pointer

0075 /// \tparam T class or type

0076 template<class T> class value_ptr : public member_ptr<T>
0077 {
0078 public:
0079     value_ptr(const T &obj) : member_ptr<T>(new T(obj)) {}
0080     value_ptr(T *p = NULLPTR) : member_ptr<T>(p) {}
0081     value_ptr(const value_ptr<T>& rhs)
0082         : member_ptr<T>(rhs.m_p ? new T(*rhs.m_p) : NULLPTR) {}
0083 
0084     value_ptr<T>& operator=(const value_ptr<T>& rhs);
0085     bool operator==(const value_ptr<T>& rhs)
0086     {
0087         return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p);
0088     }
0089 };
0090 
0091 template <class T> value_ptr<T>& value_ptr<T>::operator=(const value_ptr<T>& rhs)
0092 {
0093     T *old_p = this->m_p;
0094     this->m_p = rhs.m_p ? new T(*rhs.m_p) : NULLPTR;
0095     delete old_p;
0096     return *this;
0097 }
0098 
0099 // ********************************************************

0100 
0101 /// \brief A pointer which can be copied and cloned

0102 /// \tparam T class or type

0103 /// \details \p T should adhere to the \p Clonable interface

0104 template<class T> class clonable_ptr : public member_ptr<T>
0105 {
0106 public:
0107     clonable_ptr(const T &obj) : member_ptr<T>(obj.Clone()) {}
0108     clonable_ptr(T *p = NULLPTR) : member_ptr<T>(p) {}
0109     clonable_ptr(const clonable_ptr<T>& rhs)
0110         : member_ptr<T>(rhs.m_p ? rhs.m_p->Clone() : NULLPTR) {}
0111 
0112     clonable_ptr<T>& operator=(const clonable_ptr<T>& rhs);
0113 };
0114 
0115 template <class T> clonable_ptr<T>& clonable_ptr<T>::operator=(const clonable_ptr<T>& rhs)
0116 {
0117     T *old_p = this->m_p;
0118     this->m_p = rhs.m_p ? rhs.m_p->Clone() : NULLPTR;
0119     delete old_p;
0120     return *this;
0121 }
0122 
0123 // ********************************************************

0124 
0125 /// \brief Reference counted pointer

0126 /// \tparam T class or type

0127 /// \details users should declare \p m_referenceCount as <tt>std::atomic<unsigned></tt>

0128 ///   (or similar) under C++ 11

0129 template<class T> class counted_ptr
0130 {
0131 public:
0132     explicit counted_ptr(T *p = NULLPTR);
0133     counted_ptr(const T &r) : m_p(0) {attach(r);}
0134     counted_ptr(const counted_ptr<T>& rhs);
0135 
0136     ~counted_ptr();
0137 
0138     const T& operator*() const { return *m_p; }
0139     T& operator*() { return *m_p; }
0140 
0141     const T* operator->() const { return m_p; }
0142     T* operator->() { return get(); }
0143 
0144     const T* get() const { return m_p; }
0145     T* get();
0146 
0147     void attach(const T &p);
0148 
0149     counted_ptr<T> & operator=(const counted_ptr<T>& rhs);
0150 
0151 private:
0152     T *m_p;
0153 };
0154 
0155 template <class T> counted_ptr<T>::counted_ptr(T *p)
0156     : m_p(p)
0157 {
0158     if (m_p)
0159         m_p->m_referenceCount = 1;
0160 }
0161 
0162 template <class T> counted_ptr<T>::counted_ptr(const counted_ptr<T>& rhs)
0163     : m_p(rhs.m_p)
0164 {
0165     if (m_p)
0166         m_p->m_referenceCount++;
0167 }
0168 
0169 template <class T> counted_ptr<T>::~counted_ptr()
0170 {
0171     if (m_p && --m_p->m_referenceCount == 0)
0172         delete m_p;
0173 }
0174 
0175 template <class T> void counted_ptr<T>::attach(const T &r)
0176 {
0177     if (m_p && --m_p->m_referenceCount == 0)
0178         delete m_p;
0179     if (r.m_referenceCount == 0)
0180     {
0181         m_p = r.clone();
0182         m_p->m_referenceCount = 1;
0183     }
0184     else
0185     {
0186         m_p = const_cast<T *>(&r);
0187         m_p->m_referenceCount++;
0188     }
0189 }
0190 
0191 template <class T> T* counted_ptr<T>::get()
0192 {
0193     if (m_p && m_p->m_referenceCount > 1)
0194     {
0195         T *temp = m_p->clone();
0196         m_p->m_referenceCount--;
0197         m_p = temp;
0198         m_p->m_referenceCount = 1;
0199     }
0200     return m_p;
0201 }
0202 
0203 template <class T> counted_ptr<T> & counted_ptr<T>::operator=(const counted_ptr<T>& rhs)
0204 {
0205     if (m_p != rhs.m_p)
0206     {
0207         if (m_p && --m_p->m_referenceCount == 0)
0208             delete m_p;
0209         m_p = rhs.m_p;
0210         if (m_p)
0211             m_p->m_referenceCount++;
0212     }
0213     return *this;
0214 }
0215 
0216 // ********************************************************

0217 
0218 /// \brief Manages resources for an array of objects

0219 /// \tparam T class or type

0220 template <class T> class vector_member_ptrs
0221 {
0222 public:
0223     /// Construct an array of \p T

0224     /// \param size the size of the array, in elements

0225     /// \details If \p T is a Plain Old Dataype (POD), then the array is uninitialized.

0226     vector_member_ptrs(size_t size=0)
0227         : m_size(size), m_ptr(new member_ptr<T>[size]) {}
0228     ~vector_member_ptrs()
0229         {delete [] this->m_ptr;}
0230 
0231     member_ptr<T>& operator[](size_t index)
0232         {CRYPTOPP_ASSERT(index<this->m_size); return this->m_ptr[index];}
0233     const member_ptr<T>& operator[](size_t index) const
0234         {CRYPTOPP_ASSERT(index<this->m_size); return this->m_ptr[index];}
0235 
0236     size_t size() const {return this->m_size;}
0237     void resize(size_t newSize)
0238     {
0239         member_ptr<T> *newPtr = new member_ptr<T>[newSize];
0240         for (size_t i=0; i<this->m_size && i<newSize; i++)
0241             newPtr[i].reset(this->m_ptr[i].release());
0242         delete [] this->m_ptr;
0243         this->m_size = newSize;
0244         this->m_ptr = newPtr;
0245     }
0246 
0247 private:
0248     vector_member_ptrs(const vector_member_ptrs<T> &c); // copy not allowed

0249     void operator=(const vector_member_ptrs<T> &x);     // assignment not allowed

0250 
0251     size_t m_size;
0252     member_ptr<T> *m_ptr;
0253 };
0254 
0255 NAMESPACE_END
0256 
0257 #endif