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