stefan@webrtc.org | c9cff24 | 2011-08-29 07:39:02 +0000 | [diff] [blame] | 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 | |
| 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 | |
| 109 | template<typename T> inline |
| 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 | |
| 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 | |
| 183 | template<class T> inline |
| 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 | |
| 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 | |
| 251 | template<typename T, void (*FF)(void*)> inline |
| 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_ |