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