Crypto++ 8.2
Free C&
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
12NAMESPACE_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).
18template <class T> class simple_ptr
19{
20public:
21 simple_ptr(T *p = NULLPTR) : m_p(p) {}
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>
36template <class T> class member_ptr
37{
38public:
39 explicit member_ptr(T *p = NULLPTR) : m_p(p) {}
40
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
61protected:
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
68template <class T> member_ptr<T>::~member_ptr() {delete m_p;}
69template <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
75template<class T> class value_ptr : public member_ptr<T>
76{
77public:
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
90template <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
103template<class T> class clonable_ptr : public member_ptr<T>
104{
105public:
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
114template <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
128template<class T> class counted_ptr
129{
130public:
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
150private:
151 T *m_p;
152};
153
154template <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
161template <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
168template <class T> counted_ptr<T>::~counted_ptr()
169{
170 if (m_p && --m_p->m_referenceCount == 0)
171 delete m_p;
172}
173
174template <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
190template <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
202template <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
219template <class T> class vector_member_ptrs
220{
221public:
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]) {}
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
246private:
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
254NAMESPACE_END
255
256#endif
A pointer which can be copied and cloned.
Definition: smartptr.h:104
Reference counted pointer.
Definition: smartptr.h:129
Pointer that overloads operator ->
Definition: smartptr.h:37
Manages resources for a single object.
Definition: smartptr.h:19
Value pointer.
Definition: smartptr.h:76
Manages resources for an array of objects.
Definition: smartptr.h:220
vector_member_ptrs(size_t size=0)
Construct an arry of T.
Definition: smartptr.h:225
Library configuration file.
Crypto++ library namespace.
Common C++ header files.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:69