1 : // (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
2 : // Copyright (c) 2001, 2002 Peter Dimov
3 : //
4 : // Permission to copy, use, modify, sell and distribute this software
5 : // is granted provided this copyright notice appears in all copies.
6 : // This software is provided "as is" without express or implied
7 : // warranty, and with no claim as to its suitability for any purpose.
8 : //
9 : // See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.
10 : //
11 :
12 : // scoped_ptr mimics a built-in pointer except that it guarantees deletion
13 : // of the object pointed to, either on destruction of the scoped_ptr or via
14 : // an explicit reset(). scoped_ptr is a simple solution for simple needs;
15 : // use shared_ptr or std::auto_ptr if your needs are more complex.
16 :
17 : // *** NOTE ***
18 : // If your scoped_ptr is a class member of class FOO pointing to a
19 : // forward declared type BAR (as shown below), then you MUST use a non-inlined
20 : // version of the destructor. The destructor of a scoped_ptr (called from
21 : // FOO's destructor) must have a complete definition of BAR in order to
22 : // destroy it. Example:
23 : //
24 : // -- foo.h --
25 : // class BAR;
26 : //
27 : // class FOO {
28 : // public:
29 : // FOO();
30 : // ~FOO(); // Required for sources that instantiate class FOO to compile!
31 : //
32 : // private:
33 : // scoped_ptr<BAR> bar_;
34 : // };
35 : //
36 : // -- foo.cc --
37 : // #include "foo.h"
38 : // FOO::~FOO() {} // Empty, but must be non-inlined to FOO's class definition.
39 :
40 : // scoped_ptr_malloc added by Google
41 : // When one of these goes out of scope, instead of doing a delete or
42 : // delete[], it calls free(). scoped_ptr_malloc<char> is likely to see
43 : // much more use than any other specializations.
44 :
45 : // release() added by Google
46 : // Use this to conditionally transfer ownership of a heap-allocated object
47 : // to the caller, usually on method success.
48 :
49 : #ifndef PROCESSOR_SCOPED_PTR_H__
50 : #define PROCESSOR_SCOPED_PTR_H__
51 :
52 : #include <cstddef> // for std::ptrdiff_t
53 : #include <assert.h> // for assert
54 : #include <stdlib.h> // for free() decl
55 :
56 : namespace google_breakpad {
57 :
58 : template <typename T>
59 : class scoped_ptr {
60 : private:
61 :
62 : T* ptr;
63 :
64 : scoped_ptr(scoped_ptr const &);
65 : scoped_ptr & operator=(scoped_ptr const &);
66 :
67 : public:
68 :
69 : typedef T element_type;
70 :
71 1409 : explicit scoped_ptr(T* p = 0): ptr(p) {}
72 :
73 1386 : ~scoped_ptr() {
74 : typedef char type_must_be_complete[sizeof(T)];
75 1386 : delete ptr;
76 1386 : }
77 :
78 1 : void reset(T* p = 0) {
79 : typedef char type_must_be_complete[sizeof(T)];
80 :
81 1 : if (ptr != p) {
82 1 : delete ptr;
83 1 : ptr = p;
84 : }
85 1 : }
86 :
87 : T& operator*() const {
88 : assert(ptr != 0);
89 : return *ptr;
90 : }
91 :
92 0 : T* operator->() const {
93 0 : assert(ptr != 0);
94 0 : return ptr;
95 : }
96 :
97 : bool operator==(T* p) const {
98 : return ptr == p;
99 : }
100 :
101 : bool operator!=(T* p) const {
102 : return ptr != p;
103 : }
104 :
105 1410 : T* get() const {
106 1410 : return ptr;
107 : }
108 :
109 : void swap(scoped_ptr & b) {
110 : T* tmp = b.ptr;
111 : b.ptr = ptr;
112 : ptr = tmp;
113 : }
114 :
115 : T* release() {
116 : T* tmp = ptr;
117 : ptr = 0;
118 : return tmp;
119 : }
120 :
121 : private:
122 :
123 : // no reason to use these: each scoped_ptr should have its own object
124 : template <typename U> bool operator==(scoped_ptr<U> const& p) const;
125 : template <typename U> bool operator!=(scoped_ptr<U> const& p) const;
126 : };
127 :
128 : template<typename T> inline
129 : void swap(scoped_ptr<T>& a, scoped_ptr<T>& b) {
130 : a.swap(b);
131 : }
132 :
133 : template<typename T> inline
134 : bool operator==(T* p, const scoped_ptr<T>& b) {
135 : return p == b.get();
136 : }
137 :
138 : template<typename T> inline
139 : bool operator!=(T* p, const scoped_ptr<T>& b) {
140 : return p != b.get();
141 : }
142 :
143 : // scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
144 : // is guaranteed, either on destruction of the scoped_array or via an explicit
145 : // reset(). Use shared_array or std::vector if your needs are more complex.
146 :
147 : template<typename T>
148 : class scoped_array {
149 : private:
150 :
151 : T* ptr;
152 :
153 : scoped_array(scoped_array const &);
154 : scoped_array & operator=(scoped_array const &);
155 :
156 : public:
157 :
158 : typedef T element_type;
159 :
160 0 : explicit scoped_array(T* p = 0) : ptr(p) {}
161 :
162 0 : ~scoped_array() {
163 : typedef char type_must_be_complete[sizeof(T)];
164 0 : delete[] ptr;
165 0 : }
166 :
167 : void reset(T* p = 0) {
168 : typedef char type_must_be_complete[sizeof(T)];
169 :
170 : if (ptr != p) {
171 : delete [] ptr;
172 : ptr = p;
173 : }
174 : }
175 :
176 : T& operator[](std::ptrdiff_t i) const {
177 : assert(ptr != 0);
178 : assert(i >= 0);
179 : return ptr[i];
180 : }
181 :
182 : bool operator==(T* p) const {
183 : return ptr == p;
184 : }
185 :
186 : bool operator!=(T* p) const {
187 : return ptr != p;
188 : }
189 :
190 0 : T* get() const {
191 0 : return ptr;
192 : }
193 :
194 : void swap(scoped_array & b) {
195 : T* tmp = b.ptr;
196 : b.ptr = ptr;
197 : ptr = tmp;
198 : }
199 :
200 : T* release() {
201 : T* tmp = ptr;
202 : ptr = 0;
203 : return tmp;
204 : }
205 :
206 : private:
207 :
208 : // no reason to use these: each scoped_array should have its own object
209 : template <typename U> bool operator==(scoped_array<U> const& p) const;
210 : template <typename U> bool operator!=(scoped_array<U> const& p) const;
211 : };
212 :
213 : template<class T> inline
214 : void swap(scoped_array<T>& a, scoped_array<T>& b) {
215 : a.swap(b);
216 : }
217 :
218 : template<typename T> inline
219 : bool operator==(T* p, const scoped_array<T>& b) {
220 : return p == b.get();
221 : }
222 :
223 : template<typename T> inline
224 : bool operator!=(T* p, const scoped_array<T>& b) {
225 : return p != b.get();
226 : }
227 :
228 :
229 : // This class wraps the c library function free() in a class that can be
230 : // passed as a template argument to scoped_ptr_malloc below.
231 : class ScopedPtrMallocFree {
232 : public:
233 : inline void operator()(void* x) const {
234 : free(x);
235 : }
236 : };
237 :
238 : // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
239 : // second template argument, the functor used to free the object.
240 :
241 : template<typename T, typename FreeProc = ScopedPtrMallocFree>
242 : class scoped_ptr_malloc {
243 : private:
244 :
245 : T* ptr;
246 :
247 : scoped_ptr_malloc(scoped_ptr_malloc const &);
248 : scoped_ptr_malloc & operator=(scoped_ptr_malloc const &);
249 :
250 : public:
251 :
252 : typedef T element_type;
253 :
254 : explicit scoped_ptr_malloc(T* p = 0): ptr(p) {}
255 :
256 : ~scoped_ptr_malloc() {
257 : typedef char type_must_be_complete[sizeof(T)];
258 : free_((void*) ptr);
259 : }
260 :
261 : void reset(T* p = 0) {
262 : typedef char type_must_be_complete[sizeof(T)];
263 :
264 : if (ptr != p) {
265 : free_((void*) ptr);
266 : ptr = p;
267 : }
268 : }
269 :
270 : T& operator*() const {
271 : assert(ptr != 0);
272 : return *ptr;
273 : }
274 :
275 : T* operator->() const {
276 : assert(ptr != 0);
277 : return ptr;
278 : }
279 :
280 : bool operator==(T* p) const {
281 : return ptr == p;
282 : }
283 :
284 : bool operator!=(T* p) const {
285 : return ptr != p;
286 : }
287 :
288 : T* get() const {
289 : return ptr;
290 : }
291 :
292 : void swap(scoped_ptr_malloc & b) {
293 : T* tmp = b.ptr;
294 : b.ptr = ptr;
295 : ptr = tmp;
296 : }
297 :
298 : T* release() {
299 : T* tmp = ptr;
300 : ptr = 0;
301 : return tmp;
302 : }
303 :
304 : private:
305 :
306 : // no reason to use these: each scoped_ptr_malloc should have its own object
307 : template <typename U, typename GP>
308 : bool operator==(scoped_ptr_malloc<U, GP> const& p) const;
309 : template <typename U, typename GP>
310 : bool operator!=(scoped_ptr_malloc<U, GP> const& p) const;
311 :
312 : static FreeProc const free_;
313 : };
314 :
315 : template<typename T, typename FP>
316 : FP const scoped_ptr_malloc<T,FP>::free_ = FP();
317 :
318 : template<typename T, typename FP> inline
319 : void swap(scoped_ptr_malloc<T,FP>& a, scoped_ptr_malloc<T,FP>& b) {
320 : a.swap(b);
321 : }
322 :
323 : template<typename T, typename FP> inline
324 : bool operator==(T* p, const scoped_ptr_malloc<T,FP>& b) {
325 : return p == b.get();
326 : }
327 :
328 : template<typename T, typename FP> inline
329 : bool operator!=(T* p, const scoped_ptr_malloc<T,FP>& b) {
330 : return p != b.get();
331 : }
332 :
333 : } // namespace google_breakpad
334 :
335 : #endif // PROCESSOR_SCOPED_PTR_H__
|