Crypto++
smartptr.h
1 #ifndef CRYPTOPP_SMARTPTR_H
2 #define CRYPTOPP_SMARTPTR_H
3 
4 #include "config.h"
5 #include <algorithm>
6 
7 NAMESPACE_BEGIN(CryptoPP)
8 
9 template <class T> class simple_ptr
10 {
11 public:
12  simple_ptr(T *p = NULL) : m_p(p) {}
13  ~simple_ptr() {delete m_p; m_p = NULL;} // set m_p to NULL so double destruction (which might occur in Singleton) will be harmless
14  T *m_p;
15 };
16 
17 template <class T> class member_ptr
18 {
19 public:
20  explicit member_ptr(T *p = NULL) : m_p(p) {}
21 
22  ~member_ptr();
23 
24  const T& operator*() const { return *m_p; }
25  T& operator*() { return *m_p; }
26 
27  const T* operator->() const { return m_p; }
28  T* operator->() { return m_p; }
29 
30  const T* get() const { return m_p; }
31  T* get() { return m_p; }
32 
33  T* release()
34  {
35  T *old_p = m_p;
36  m_p = 0;
37  return old_p;
38  }
39 
40  void reset(T *p = 0);
41 
42 protected:
43  member_ptr(const member_ptr<T>& rhs); // copy not allowed
44  void operator=(const member_ptr<T>& rhs); // assignment not allowed
45 
46  T *m_p;
47 };
48 
49 template <class T> member_ptr<T>::~member_ptr() {delete m_p;}
50 template <class T> void member_ptr<T>::reset(T *p) {delete m_p; m_p = p;}
51 
52 // ********************************************************
53 
54 template<class T> class value_ptr : public member_ptr<T>
55 {
56 public:
57  value_ptr(const T &obj) : member_ptr<T>(new T(obj)) {}
58  value_ptr(T *p = NULL) : member_ptr<T>(p) {}
59  value_ptr(const value_ptr<T>& rhs)
60  : member_ptr<T>(rhs.m_p ? new T(*rhs.m_p) : NULL) {}
61 
62  value_ptr<T>& operator=(const value_ptr<T>& rhs);
63  bool operator==(const value_ptr<T>& rhs)
64  {
65  return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p);
66  }
67 };
68 
69 template <class T> value_ptr<T>& value_ptr<T>::operator=(const value_ptr<T>& rhs)
70 {
71  T *old_p = this->m_p;
72  this->m_p = rhs.m_p ? new T(*rhs.m_p) : NULL;
73  delete old_p;
74  return *this;
75 }
76 
77 // ********************************************************
78 
79 template<class T> class clonable_ptr : public member_ptr<T>
80 {
81 public:
82  clonable_ptr(const T &obj) : member_ptr<T>(obj.Clone()) {}
83  clonable_ptr(T *p = NULL) : member_ptr<T>(p) {}
84  clonable_ptr(const clonable_ptr<T>& rhs)
85  : member_ptr<T>(rhs.m_p ? rhs.m_p->Clone() : NULL) {}
86 
87  clonable_ptr<T>& operator=(const clonable_ptr<T>& rhs);
88 };
89 
90 template <class T> clonable_ptr<T>& clonable_ptr<T>::operator=(const clonable_ptr<T>& rhs)
91 {
92  T *old_p = this->m_p;
93  this->m_p = rhs.m_p ? rhs.m_p->Clone() : NULL;
94  delete old_p;
95  return *this;
96 }
97 
98 // ********************************************************
99 
100 template<class T> class counted_ptr
101 {
102 public:
103  explicit counted_ptr(T *p = 0);
104  counted_ptr(const T &r) : m_p(0) {attach(r);}
105  counted_ptr(const counted_ptr<T>& rhs);
106 
107  ~counted_ptr();
108 
109  const T& operator*() const { return *m_p; }
110  T& operator*() { return *m_p; }
111 
112  const T* operator->() const { return m_p; }
113  T* operator->() { return get(); }
114 
115  const T* get() const { return m_p; }
116  T* get();
117 
118  void attach(const T &p);
119 
120  counted_ptr<T> & operator=(const counted_ptr<T>& rhs);
121 
122 private:
123  T *m_p;
124 };
125 
126 template <class T> counted_ptr<T>::counted_ptr(T *p)
127  : m_p(p)
128 {
129  if (m_p)
130  m_p->m_referenceCount = 1;
131 }
132 
133 template <class T> counted_ptr<T>::counted_ptr(const counted_ptr<T>& rhs)
134  : m_p(rhs.m_p)
135 {
136  if (m_p)
137  m_p->m_referenceCount++;
138 }
139 
140 template <class T> counted_ptr<T>::~counted_ptr()
141 {
142  if (m_p && --m_p->m_referenceCount == 0)
143  delete m_p;
144 }
145 
146 template <class T> void counted_ptr<T>::attach(const T &r)
147 {
148  if (m_p && --m_p->m_referenceCount == 0)
149  delete m_p;
150  if (r.m_referenceCount == 0)
151  {
152  m_p = r.clone();
153  m_p->m_referenceCount = 1;
154  }
155  else
156  {
157  m_p = const_cast<T *>(&r);
158  m_p->m_referenceCount++;
159  }
160 }
161 
162 template <class T> T* counted_ptr<T>::get()
163 {
164  if (m_p && m_p->m_referenceCount > 1)
165  {
166  T *temp = m_p->clone();
167  m_p->m_referenceCount--;
168  m_p = temp;
169  m_p->m_referenceCount = 1;
170  }
171  return m_p;
172 }
173 
174 template <class T> counted_ptr<T> & counted_ptr<T>::operator=(const counted_ptr<T>& rhs)
175 {
176  if (m_p != rhs.m_p)
177  {
178  if (m_p && --m_p->m_referenceCount == 0)
179  delete m_p;
180  m_p = rhs.m_p;
181  if (m_p)
182  m_p->m_referenceCount++;
183  }
184  return *this;
185 }
186 
187 // ********************************************************
188 
189 template <class T> class vector_member_ptrs
190 {
191 public:
192  vector_member_ptrs(size_t size=0)
193  : m_size(size), m_ptr(new member_ptr<T>[size]) {}
195  {delete [] this->m_ptr;}
196 
197  member_ptr<T>& operator[](size_t index)
198  {assert(index<this->m_size); return this->m_ptr[index];}
199  const member_ptr<T>& operator[](size_t index) const
200  {assert(index<this->m_size); return this->m_ptr[index];}
201 
202  size_t size() const {return this->m_size;}
203  void resize(size_t newSize)
204  {
205  member_ptr<T> *newPtr = new member_ptr<T>[newSize];
206  for (size_t i=0; i<this->m_size && i<newSize; i++)
207  newPtr[i].reset(this->m_ptr[i].release());
208  delete [] this->m_ptr;
209  this->m_size = newSize;
210  this->m_ptr = newPtr;
211  }
212 
213 private:
214  vector_member_ptrs(const vector_member_ptrs<T> &c); // copy not allowed
215  void operator=(const vector_member_ptrs<T> &x); // assignment not allowed
216 
217  size_t m_size;
218  member_ptr<T> *m_ptr;
219 };
220 
221 NAMESPACE_END
222 
223 #endif