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