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 // 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 WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_
26 #define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_
27
28 #include <assert.h> // for assert
29 #include <stdlib.h> // for free() decl
30
31 #include <cstddef> // for std::ptrdiff_t
32
33 #ifdef _WIN32
34 namespace std { using ::ptrdiff_t; };
35 #endif // _WIN32
36
37 namespace webrtc {
38
39 template <typename T>
40 class 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
ptr(p)52 explicit scoped_ptr(T* p = NULL): ptr(p) {}
53
~scoped_ptr()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
get()80 T* get() const {
81 return ptr;
82 }
83
swap(scoped_ptr & b)84 void swap(scoped_ptr & b) {
85 T* tmp = b.ptr;
86 b.ptr = ptr;
87 ptr = tmp;
88 }
89
release()90 T* release() {
91 T* tmp = ptr;
92 ptr = NULL;
93 return tmp;
94 }
95
accept()96 T** accept() {
97 if (ptr) {
98 delete ptr;
99 ptr = NULL;
100 }
101 return &ptr;
102 }
103
use()104 T** use() {
105 return &ptr;
106 }
107 };
108
109 template<typename T> inline
swap(scoped_ptr<T> & a,scoped_ptr<T> & b)110 void swap(scoped_ptr<T>& a, scoped_ptr<T>& b) {
111 a.swap(b);
112 }
113
114
115
116
117 // scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
118 // is guaranteed, either on destruction of the scoped_array or via an explicit
119 // reset(). Use shared_array or std::vector if your needs are more complex.
120
121 template<typename T>
122 class scoped_array {
123 private:
124
125 T* ptr;
126
127 scoped_array(scoped_array const &);
128 scoped_array & operator=(scoped_array const &);
129
130 public:
131
132 typedef T element_type;
133
ptr(p)134 explicit scoped_array(T* p = NULL) : ptr(p) {}
135
~scoped_array()136 ~scoped_array() {
137 typedef char type_must_be_complete[sizeof(T)];
138 delete[] ptr;
139 }
140
141 void reset(T* p = NULL) {
142 typedef char type_must_be_complete[sizeof(T)];
143
144 if (ptr != p) {
145 T* arr = ptr;
146 ptr = p;
147 // Delete last, in case arr destructor indirectly results in ~scoped_array
148 delete [] arr;
149 }
150 }
151
152 T& operator[](std::ptrdiff_t i) const {
153 assert(ptr != NULL);
154 assert(i >= 0);
155 return ptr[i];
156 }
157
get()158 T* get() const {
159 return ptr;
160 }
161
swap(scoped_array & b)162 void swap(scoped_array & b) {
163 T* tmp = b.ptr;
164 b.ptr = ptr;
165 ptr = tmp;
166 }
167
release()168 T* release() {
169 T* tmp = ptr;
170 ptr = NULL;
171 return tmp;
172 }
173
accept()174 T** accept() {
175 if (ptr) {
176 delete [] ptr;
177 ptr = NULL;
178 }
179 return &ptr;
180 }
181 };
182
183 template<class T> inline
swap(scoped_array<T> & a,scoped_array<T> & b)184 void swap(scoped_array<T>& a, scoped_array<T>& b) {
185 a.swap(b);
186 }
187
188 // scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a
189 // second template argument, the function used to free the object.
190
191 template<typename T, void (*FF)(void*) = free> class scoped_ptr_malloc {
192 private:
193
194 T* ptr;
195
196 scoped_ptr_malloc(scoped_ptr_malloc const &);
197 scoped_ptr_malloc & operator=(scoped_ptr_malloc const &);
198
199 public:
200
201 typedef T element_type;
202
ptr(p)203 explicit scoped_ptr_malloc(T* p = 0): ptr(p) {}
204
~scoped_ptr_malloc()205 ~scoped_ptr_malloc() {
206 FF(static_cast<void*>(ptr));
207 }
208
209 void reset(T* p = 0) {
210 if (ptr != p) {
211 FF(static_cast<void*>(ptr));
212 ptr = p;
213 }
214 }
215
216 T& operator*() const {
217 assert(ptr != 0);
218 return *ptr;
219 }
220
221 T* operator->() const {
222 assert(ptr != 0);
223 return ptr;
224 }
225
get()226 T* get() const {
227 return ptr;
228 }
229
swap(scoped_ptr_malloc & b)230 void swap(scoped_ptr_malloc & b) {
231 T* tmp = b.ptr;
232 b.ptr = ptr;
233 ptr = tmp;
234 }
235
release()236 T* release() {
237 T* tmp = ptr;
238 ptr = 0;
239 return tmp;
240 }
241
accept()242 T** accept() {
243 if (ptr) {
244 FF(static_cast<void*>(ptr));
245 ptr = 0;
246 }
247 return &ptr;
248 }
249 };
250
251 template<typename T, void (*FF)(void*)> inline
swap(scoped_ptr_malloc<T,FF> & a,scoped_ptr_malloc<T,FF> & b)252 void swap(scoped_ptr_malloc<T,FF>& a, scoped_ptr_malloc<T,FF>& b) {
253 a.swap(b);
254 }
255
256 } // namespace webrtc
257
258 #endif // #ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_
259