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
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
256} // namespace webrtc
257
258#endif  // #ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_
259