Crypto++ 8.1 Free C++ class library of cryptographic schemes

smartptr.h
Go to the documentation of this file.
1 // smartptr.h - originally written and placed in the public domain by Wei Dai
2
3 /// \file smartptr.h
4 /// \brief Classes for automatic resource management
5
6 #ifndef CRYPTOPP_SMARTPTR_H
7 #define CRYPTOPP_SMARTPTR_H
8
9 #include "config.h"
10 #include "stdcpp.h"
11
12 NAMESPACE_BEGIN(CryptoPP)
13
14 /// \brief Manages resources for a single object
15 /// \tparam T class or type
16 /// \details \p simple_ptr is used frequently in the library to manage resources and
17 /// ensure cleanup under the RAII pattern (Resource Acquisition Is Initialization).
18 template <class T> class simple_ptr
19 {
20 public:
21 simple_ptr(T *p = NULLPTR) : m_p(p) {}
22 ~simple_ptr()
23 {
24 delete m_p;
25 m_p = NULLPTR;
26 }
27
28 T *m_p;
29 };
30
31 /// \brief Pointer that overloads operator ->
32 /// \tparam T class or type
33 /// \details member_ptr is used frequently in the library to avoid the issues related to
34 /// std::auto_ptr in C++11 (deprecated) and std::unique_ptr in C++03 (non-existent).
35 /// \bug <a href="http://github.com/weidai11/cryptopp/issues/48">Issue 48: "Use of auto_ptr causes dirty compile under C++11"</a>
36 template <class T> class member_ptr
37 {
38 public:
39 explicit member_ptr(T *p = NULLPTR) : m_p(p) {}
40
41 ~member_ptr();
42
43 const T& operator*() const { return *m_p; }
44 T& operator*() { return *m_p; }
45
46 const T* operator->() const { return m_p; }
47 T* operator->() { return m_p; }
48
49 const T* get() const { return m_p; }
50 T* get() { return m_p; }
51
52 T* release()
53 {
54 T *old_p = m_p;
55 m_p = NULLPTR;
56 return old_p;
57 }
58
59 void reset(T *p = 0);
60
61 protected:
62 member_ptr(const member_ptr<T>& rhs); // copy not allowed
63 void operator=(const member_ptr<T>& rhs); // assignment not allowed
64
65 T *m_p;
66 };
67
68 template <class T> member_ptr<T>::~member_ptr() {delete m_p;}
69 template <class T> void member_ptr<T>::reset(T *p) {delete m_p; m_p = p;}
70
71 // ********************************************************
72
73 /// \brief Value pointer
74 /// \tparam T class or type
75 template<class T> class value_ptr : public member_ptr<T>
76 {
77 public:
78 value_ptr(const T &obj) : member_ptr<T>(new T(obj)) {}
79 value_ptr(T *p = NULLPTR) : member_ptr<T>(p) {}
80 value_ptr(const value_ptr<T>& rhs)
81 : member_ptr<T>(rhs.m_p ? new T(*rhs.m_p) : NULLPTR) {}
82
83 value_ptr<T>& operator=(const value_ptr<T>& rhs);
84 bool operator==(const value_ptr<T>& rhs)
85 {
86 return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p);
87 }
88 };
89
90 template <class T> value_ptr<T>& value_ptr<T>::operator=(const value_ptr<T>& rhs)
91 {
92 T *old_p = this->m_p;
93 this->m_p = rhs.m_p ? new T(*rhs.m_p) : NULLPTR;
94 delete old_p;
95 return *this;
96 }
97
98 // ********************************************************
99
100 /// \brief A pointer which can be copied and cloned
101 /// \tparam T class or type
102 /// \details \p T should adhere to the \p Clonable interface
103 template<class T> class clonable_ptr : public member_ptr<T>
104 {
105 public:
106 clonable_ptr(const T &obj) : member_ptr<T>(obj.Clone()) {}
107 clonable_ptr(T *p = NULLPTR) : member_ptr<T>(p) {}
108 clonable_ptr(const clonable_ptr<T>& rhs)
109 : member_ptr<T>(rhs.m_p ? rhs.m_p->Clone() : NULLPTR) {}
110
111 clonable_ptr<T>& operator=(const clonable_ptr<T>& rhs);
112 };
113
114 template <class T> clonable_ptr<T>& clonable_ptr<T>::operator=(const clonable_ptr<T>& rhs)
115 {
116 T *old_p = this->m_p;
117 this->m_p = rhs.m_p ? rhs.m_p->Clone() : NULLPTR;
118 delete old_p;
119 return *this;
120 }
121
122 // ********************************************************
123
124 /// \brief Reference counted pointer
125 /// \tparam T class or type
126 /// \details users should declare \p m_referenceCount as <tt>std::atomic<unsigned></tt>
127 /// (or similar) under C++ 11
128 template<class T> class counted_ptr
129 {
130 public:
131 explicit counted_ptr(T *p = 0);
132 counted_ptr(const T &r) : m_p(0) {attach(r);}
133 counted_ptr(const counted_ptr<T>& rhs);
134
135 ~counted_ptr();
136
137 const T& operator*() const { return *m_p; }
138 T& operator*() { return *m_p; }
139
140 const T* operator->() const { return m_p; }
141 T* operator->() { return get(); }
142
143 const T* get() const { return m_p; }
144 T* get();
145
146 void attach(const T &p);
147
148 counted_ptr<T> & operator=(const counted_ptr<T>& rhs);
149
150 private:
151 T *m_p;
152 };
153
154 template <class T> counted_ptr<T>::counted_ptr(T *p)
155 : m_p(p)
156 {
157 if (m_p)
158 m_p->m_referenceCount = 1;
159 }
160
161 template <class T> counted_ptr<T>::counted_ptr(const counted_ptr<T>& rhs)
162 : m_p(rhs.m_p)
163 {
164 if (m_p)
165 m_p->m_referenceCount++;
166 }
167
168 template <class T> counted_ptr<T>::~counted_ptr()
169 {
170 if (m_p && --m_p->m_referenceCount == 0)
171 delete m_p;
172 }
173
174 template <class T> void counted_ptr<T>::attach(const T &r)
175 {
176 if (m_p && --m_p->m_referenceCount == 0)
177 delete m_p;
178 if (r.m_referenceCount == 0)
179 {
180 m_p = r.clone();
181 m_p->m_referenceCount = 1;
182 }
183 else
184 {
185 m_p = const_cast<T *>(&r);
186 m_p->m_referenceCount++;
187 }
188 }
189
190 template <class T> T* counted_ptr<T>::get()
191 {
192 if (m_p && m_p->m_referenceCount > 1)
193 {
194 T *temp = m_p->clone();
195 m_p->m_referenceCount--;
196 m_p = temp;
197 m_p->m_referenceCount = 1;
198 }
199 return m_p;
200 }
201
202 template <class T> counted_ptr<T> & counted_ptr<T>::operator=(const counted_ptr<T>& rhs)
203 {
204 if (m_p != rhs.m_p)
205 {
206 if (m_p && --m_p->m_referenceCount == 0)
207 delete m_p;
208 m_p = rhs.m_p;
209 if (m_p)
210 m_p->m_referenceCount++;
211 }
212 return *this;
213 }
214
215 // ********************************************************
216
217 /// \brief Manages resources for an array of objects
218 /// \tparam T class or type
219 template <class T> class vector_member_ptrs
220 {
221 public:
222 /// Construct an arry of \p T
223 /// \param size the size of the array, in elements
224 /// \details If \p T is a Plain Old Dataype (POD), then the array is uninitialized.
225 vector_member_ptrs(size_t size=0)
226 : m_size(size), m_ptr(new member_ptr<T>[size]) {}
227 ~vector_member_ptrs()
228 {delete [] this->m_ptr;}
229
230 member_ptr<T>& operator[](size_t index)
231 {CRYPTOPP_ASSERT(index<this->m_size); return this->m_ptr[index];}
232 const member_ptr<T>& operator[](size_t index) const
233 {CRYPTOPP_ASSERT(index<this->m_size); return this->m_ptr[index];}
234
235 size_t size() const {return this->m_size;}
236 void resize(size_t newSize)
237 {
238 member_ptr<T> *newPtr = new member_ptr<T>[newSize];
239 for (size_t i=0; i<this->m_size && i<newSize; i++)
240 newPtr[i].reset(this->m_ptr[i].release());
241 delete [] this->m_ptr;
242 this->m_size = newSize;
243 this->m_ptr = newPtr;
244 }
245
246 private:
247 vector_member_ptrs(const vector_member_ptrs<T> &c); // copy not allowed
248 void operator=(const vector_member_ptrs<T> &x); // assignment not allowed
249
250 size_t m_size;
251 member_ptr<T> *m_ptr;
252 };
253
254 NAMESPACE_END
255
256 #endif
config.h
Library configuration file.
stdcpp.h
Common C++ header files.
member_ptr
Pointer that overloads operator ->
Definition: smartptr.h:36
counted_ptr
Reference counted pointer.
Definition: smartptr.h:128
simple_ptr
Manages resources for a single object.
Definition: smartptr.h:18
clonable_ptr
A pointer which can be copied and cloned.
Definition: smartptr.h:103
vector_member_ptrs
Manages resources for an array of objects.
Definition: smartptr.h:219
CRYPTOPP_ASSERT
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:69
vector_member_ptrs::vector_member_ptrs
vector_member_ptrs(size_t size=0)
Construct an arry of T.
Definition: smartptr.h:225
value_ptr
Value pointer.
Definition: smartptr.h:75
CryptoPP
Crypto++ library namespace.