blob: 84113d832f746541f8ec0b9378f27a639d0bc679 [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
29#include <stdlib.h> // for free() decl
30
31#include <cstddef> // for std::ptrdiff_t
32
33#ifdef _WIN32
34namespace std { using ::ptrdiff_t; };
35#endif // _WIN32
36
37namespace webrtc {
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
109template<typename T> inline
110void 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
121template<typename T>
122class 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
134 explicit scoped_array(T* p = NULL) : ptr(p) {}
135
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
158 T* get() const {
159 return ptr;
160 }
161
162 void swap(scoped_array & b) {
163 T* tmp = b.ptr;
164 b.ptr = ptr;
165 ptr = tmp;
166 }
167
168 T* release() {
169 T* tmp = ptr;
170 ptr = NULL;
171 return tmp;
172 }
173
174 T** accept() {
175 if (ptr) {
176 delete [] ptr;
177 ptr = NULL;
178 }
179 return &ptr;
180 }
181};
182
183template<class T> inline
184void 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
191template<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
203 explicit scoped_ptr_malloc(T* p = 0): ptr(p) {}
204
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
226 T* get() const {
227 return ptr;
228 }
229
230 void swap(scoped_ptr_malloc & b) {
231 T* tmp = b.ptr;
232 b.ptr = ptr;
233 ptr = tmp;
234 }
235
236 T* release() {
237 T* tmp = ptr;
238 ptr = 0;
239 return tmp;
240 }
241
242 T** accept() {
243 if (ptr) {
244 FF(static_cast<void*>(ptr));
245 ptr = 0;
246 }
247 return &ptr;
248 }
249};
250
251template<typename T, void (*FF)(void*)> inline
252void swap(scoped_ptr_malloc<T,FF>& a, scoped_ptr_malloc<T,FF>& b) {
253 a.swap(b);
254}
255
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000256} // namespace webrtc
stefan@webrtc.orgc9cff242011-08-29 07:39:02 +0000257
258#endif // #ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_