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