blob: 5a8364e10b09fc71735d4ec9afe19d6b15d2c67c [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001// (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// scoped_ptr_malloc added in by Google. When one of
18// these goes out of scope, instead of doing a delete or delete[], it
19// calls free(). scoped_ptr_malloc<char> is likely to see much more
20// use than any other specializations.
21
22// release() added in by Google. Use this to conditionally
23// transfer ownership of a heap-allocated object to the caller, usually on
24// method success.
25#ifndef TALK_BASE_SCOPED_PTR_H__
26#define TALK_BASE_SCOPED_PTR_H__
27
28#include <cstddef> // for std::ptrdiff_t
29#include <stdlib.h> // for free() decl
30
31#include "talk/base/common.h" // for ASSERT
32
33#ifdef _WIN32
34namespace std { using ::ptrdiff_t; };
35#endif // _WIN32
36
37namespace talk_base {
38
39template <typename T>
40class scoped_ptr {
41 private:
42
43 T* ptr;
44
45 scoped_ptr(scoped_ptr const &);
46 scoped_ptr & operator=(scoped_ptr const &);
47
48 public:
49
50 typedef T element_type;
51
52 explicit scoped_ptr(T* p = NULL): ptr(p) {}
53
54 ~scoped_ptr() {
55 typedef char type_must_be_complete[sizeof(T)];
56 delete ptr;
57 }
58
59 void reset(T* p = NULL) {
60 typedef char type_must_be_complete[sizeof(T)];
61
62 if (ptr != p) {
63 T* obj = ptr;
64 ptr = p;
65 // Delete last, in case obj destructor indirectly results in ~scoped_ptr
66 delete obj;
67 }
68 }
69
70 T& operator*() const {
71 ASSERT(ptr != NULL);
72 return *ptr;
73 }
74
75 T* operator->() const {
76 ASSERT(ptr != NULL);
77 return ptr;
78 }
79
80 T* get() const {
81 return ptr;
82 }
83
84 void swap(scoped_ptr & b) {
85 T* tmp = b.ptr;
86 b.ptr = ptr;
87 ptr = tmp;
88 }
89
90 T* release() {
91 T* tmp = ptr;
92 ptr = NULL;
93 return tmp;
94 }
95
96 T** accept() {
97 if (ptr) {
98 delete ptr;
99 ptr = NULL;
100 }
101 return &ptr;
102 }
103
104 T** use() {
105 return &ptr;
106 }
107
108 // Allow scoped_ptr<T> to be used in boolean expressions, but not
109 // implicitly convertible to a real bool (which is dangerous).
110 // Borrowed from chromium's scoped_ptr implementation.
111 typedef T* scoped_ptr::*Testable;
112 operator Testable() const { return ptr ? &scoped_ptr::ptr : NULL; }
113
114};
115
116template<typename T> inline
117void swap(scoped_ptr<T>& a, scoped_ptr<T>& b) {
118 a.swap(b);
119}
120
121
122
123
124// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
125// is guaranteed, either on destruction of the scoped_array or via an explicit
126// reset(). Use shared_array or std::vector if your needs are more complex.
127
128template<typename T>
129class scoped_array {
130 private:
131
132 T* ptr;
133
134 scoped_array(scoped_array const &);
135 scoped_array & operator=(scoped_array const &);
136
137 public:
138
139 typedef T element_type;
140
141 explicit scoped_array(T* p = NULL) : ptr(p) {}
142
143 ~scoped_array() {
144 typedef char type_must_be_complete[sizeof(T)];
145 delete[] ptr;
146 }
147
148 void reset(T* p = NULL) {
149 typedef char type_must_be_complete[sizeof(T)];
150
151 if (ptr != p) {
152 T* arr = ptr;
153 ptr = p;
154 // Delete last, in case arr destructor indirectly results in ~scoped_array
155 delete [] arr;
156 }
157 }
158
159 T& operator[](std::ptrdiff_t i) const {
160 ASSERT(ptr != NULL);
161 ASSERT(i >= 0);
162 return ptr[i];
163 }
164
165 T* get() const {
166 return ptr;
167 }
168
169 void swap(scoped_array & b) {
170 T* tmp = b.ptr;
171 b.ptr = ptr;
172 ptr = tmp;
173 }
174
175 T* release() {
176 T* tmp = ptr;
177 ptr = NULL;
178 return tmp;
179 }
180
181 T** accept() {
182 if (ptr) {
183 delete [] ptr;
184 ptr = NULL;
185 }
186 return &ptr;
187 }
188
189 // Allow scoped_array<T> to be used in boolean expressions, but not
190 // implicitly convertible to a real bool (which is dangerous).
191 // Borrowed from chromium's scoped_array implementation.
192 typedef T* scoped_array::*Testable;
193 operator Testable() const { return ptr ? &scoped_array::ptr : NULL; }
194};
195
196template<class T> inline
197void swap(scoped_array<T>& a, scoped_array<T>& b) {
198 a.swap(b);
199}
200
201// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
202// second template argument, the function used to free the object.
203
204template<typename T, void (*FF)(T*) = free> class scoped_ptr_malloc {
205 private:
206
207 T* ptr;
208
209 scoped_ptr_malloc(scoped_ptr_malloc const &);
210 scoped_ptr_malloc & operator=(scoped_ptr_malloc const &);
211
212 public:
213
214 typedef T element_type;
215
216 explicit scoped_ptr_malloc(T* p = 0): ptr(p) {}
217
218 ~scoped_ptr_malloc() {
219 FF(ptr);
220 }
221
222 void reset(T* p = 0) {
223 if (ptr != p) {
224 FF(ptr);
225 ptr = p;
226 }
227 }
228
229 T& operator*() const {
230 ASSERT(ptr != 0);
231 return *ptr;
232 }
233
234 T* operator->() const {
235 ASSERT(ptr != 0);
236 return ptr;
237 }
238
239 T* get() const {
240 return ptr;
241 }
242
243 void swap(scoped_ptr_malloc & b) {
244 T* tmp = b.ptr;
245 b.ptr = ptr;
246 ptr = tmp;
247 }
248
249 T* release() {
250 T* tmp = ptr;
251 ptr = 0;
252 return tmp;
253 }
254
255 T** accept() {
256 if (ptr) {
257 FF(ptr);
258 ptr = 0;
259 }
260 return &ptr;
261 }
262
263 // Allow scoped_ptr_malloc<T> to be used in boolean expressions, but not
264 // implicitly convertible to a real bool (which is dangerous).
265 // Borrowed from chromium's scoped_ptr_malloc implementation.
266 typedef T* scoped_ptr_malloc::*Testable;
267 operator Testable() const { return ptr ? &scoped_ptr_malloc::ptr : NULL; }
268};
269
270template<typename T, void (*FF)(T*)> inline
271void swap(scoped_ptr_malloc<T,FF>& a, scoped_ptr_malloc<T,FF>& b) {
272 a.swap(b);
273}
274
275} // namespace talk_base
276
277#endif // #ifndef TALK_BASE_SCOPED_PTR_H__