File indexing completed on 2025-01-18 09:55:09
0001
0002
0003
0004
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
0015
0016
0017
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
0032
0033
0034
0035
0036
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);
0064 void operator=(const member_ptr<T>& rhs);
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
0075
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
0102
0103
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
0126
0127
0128
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
0219
0220 template <class T> class vector_member_ptrs
0221 {
0222 public:
0223
0224
0225
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);
0249 void operator=(const vector_member_ptrs<T> &x);
0250
0251 size_t m_size;
0252 member_ptr<T> *m_ptr;
0253 };
0254
0255 NAMESPACE_END
0256
0257 #endif