1c55a96383497a772a307b346368133960b02ad03Eric Laurent// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. 2c55a96383497a772a307b346368133960b02ad03Eric Laurent// Copyright (c) 2001, 2002 Peter Dimov 3c55a96383497a772a307b346368133960b02ad03Eric Laurent// 4c55a96383497a772a307b346368133960b02ad03Eric Laurent// Permission to copy, use, modify, sell and distribute this software 5c55a96383497a772a307b346368133960b02ad03Eric Laurent// is granted provided this copyright notice appears in all copies. 6c55a96383497a772a307b346368133960b02ad03Eric Laurent// This software is provided "as is" without express or implied 7c55a96383497a772a307b346368133960b02ad03Eric Laurent// warranty, and with no claim as to its suitability for any purpose. 8c55a96383497a772a307b346368133960b02ad03Eric Laurent// 9c55a96383497a772a307b346368133960b02ad03Eric Laurent// See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation. 10c55a96383497a772a307b346368133960b02ad03Eric Laurent// 11c55a96383497a772a307b346368133960b02ad03Eric Laurent 12c55a96383497a772a307b346368133960b02ad03Eric Laurent// scoped_ptr mimics a built-in pointer except that it guarantees deletion 13c55a96383497a772a307b346368133960b02ad03Eric Laurent// of the object pointed to, either on destruction of the scoped_ptr or via 14c55a96383497a772a307b346368133960b02ad03Eric Laurent// an explicit reset(). scoped_ptr is a simple solution for simple needs; 15c55a96383497a772a307b346368133960b02ad03Eric Laurent// use shared_ptr or std::auto_ptr if your needs are more complex. 16c55a96383497a772a307b346368133960b02ad03Eric Laurent 17c55a96383497a772a307b346368133960b02ad03Eric Laurent// scoped_ptr_malloc added in by Google. When one of 18c55a96383497a772a307b346368133960b02ad03Eric Laurent// these goes out of scope, instead of doing a delete or delete[], it 19c55a96383497a772a307b346368133960b02ad03Eric Laurent// calls free(). scoped_ptr_malloc<char> is likely to see much more 20c55a96383497a772a307b346368133960b02ad03Eric Laurent// use than any other specializations. 21c55a96383497a772a307b346368133960b02ad03Eric Laurent 22c55a96383497a772a307b346368133960b02ad03Eric Laurent// release() added in by Google. Use this to conditionally 23c55a96383497a772a307b346368133960b02ad03Eric Laurent// transfer ownership of a heap-allocated object to the caller, usually on 24c55a96383497a772a307b346368133960b02ad03Eric Laurent// method success. 25c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_ 26c55a96383497a772a307b346368133960b02ad03Eric Laurent#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_ 27c55a96383497a772a307b346368133960b02ad03Eric Laurent 28c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <assert.h> // for assert 29c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <stdlib.h> // for free() decl 30c55a96383497a772a307b346368133960b02ad03Eric Laurent 31c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <cstddef> // for std::ptrdiff_t 32c55a96383497a772a307b346368133960b02ad03Eric Laurent 33c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef _WIN32 34c55a96383497a772a307b346368133960b02ad03Eric Laurentnamespace std { using ::ptrdiff_t; }; 35c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif // _WIN32 36c55a96383497a772a307b346368133960b02ad03Eric Laurent 37c55a96383497a772a307b346368133960b02ad03Eric Laurentnamespace webrtc { 38c55a96383497a772a307b346368133960b02ad03Eric Laurent 39c55a96383497a772a307b346368133960b02ad03Eric Laurenttemplate <typename T> 40c55a96383497a772a307b346368133960b02ad03Eric Laurentclass scoped_ptr { 41c55a96383497a772a307b346368133960b02ad03Eric Laurent private: 42c55a96383497a772a307b346368133960b02ad03Eric Laurent 43c55a96383497a772a307b346368133960b02ad03Eric Laurent T* ptr; 44c55a96383497a772a307b346368133960b02ad03Eric Laurent 45c55a96383497a772a307b346368133960b02ad03Eric Laurent scoped_ptr(scoped_ptr const &); 46c55a96383497a772a307b346368133960b02ad03Eric Laurent scoped_ptr & operator=(scoped_ptr const &); 47c55a96383497a772a307b346368133960b02ad03Eric Laurent 48c55a96383497a772a307b346368133960b02ad03Eric Laurent public: 49c55a96383497a772a307b346368133960b02ad03Eric Laurent 50c55a96383497a772a307b346368133960b02ad03Eric Laurent typedef T element_type; 51c55a96383497a772a307b346368133960b02ad03Eric Laurent 52c55a96383497a772a307b346368133960b02ad03Eric Laurent explicit scoped_ptr(T* p = NULL): ptr(p) {} 53c55a96383497a772a307b346368133960b02ad03Eric Laurent 54c55a96383497a772a307b346368133960b02ad03Eric Laurent ~scoped_ptr() { 55c55a96383497a772a307b346368133960b02ad03Eric Laurent typedef char type_must_be_complete[sizeof(T)]; 56c55a96383497a772a307b346368133960b02ad03Eric Laurent delete ptr; 57c55a96383497a772a307b346368133960b02ad03Eric Laurent } 58c55a96383497a772a307b346368133960b02ad03Eric Laurent 59c55a96383497a772a307b346368133960b02ad03Eric Laurent void reset(T* p = NULL) { 60c55a96383497a772a307b346368133960b02ad03Eric Laurent typedef char type_must_be_complete[sizeof(T)]; 61c55a96383497a772a307b346368133960b02ad03Eric Laurent 62c55a96383497a772a307b346368133960b02ad03Eric Laurent if (ptr != p) { 63c55a96383497a772a307b346368133960b02ad03Eric Laurent T* obj = ptr; 64c55a96383497a772a307b346368133960b02ad03Eric Laurent ptr = p; 65c55a96383497a772a307b346368133960b02ad03Eric Laurent // Delete last, in case obj destructor indirectly results in ~scoped_ptr 66c55a96383497a772a307b346368133960b02ad03Eric Laurent delete obj; 67c55a96383497a772a307b346368133960b02ad03Eric Laurent } 68c55a96383497a772a307b346368133960b02ad03Eric Laurent } 69c55a96383497a772a307b346368133960b02ad03Eric Laurent 70c55a96383497a772a307b346368133960b02ad03Eric Laurent T& operator*() const { 71c55a96383497a772a307b346368133960b02ad03Eric Laurent assert(ptr != NULL); 72c55a96383497a772a307b346368133960b02ad03Eric Laurent return *ptr; 73c55a96383497a772a307b346368133960b02ad03Eric Laurent } 74c55a96383497a772a307b346368133960b02ad03Eric Laurent 75c55a96383497a772a307b346368133960b02ad03Eric Laurent T* operator->() const { 76c55a96383497a772a307b346368133960b02ad03Eric Laurent assert(ptr != NULL); 77c55a96383497a772a307b346368133960b02ad03Eric Laurent return ptr; 78c55a96383497a772a307b346368133960b02ad03Eric Laurent } 79c55a96383497a772a307b346368133960b02ad03Eric Laurent 80c55a96383497a772a307b346368133960b02ad03Eric Laurent T* get() const { 81c55a96383497a772a307b346368133960b02ad03Eric Laurent return ptr; 82c55a96383497a772a307b346368133960b02ad03Eric Laurent } 83c55a96383497a772a307b346368133960b02ad03Eric Laurent 84c55a96383497a772a307b346368133960b02ad03Eric Laurent void swap(scoped_ptr & b) { 85c55a96383497a772a307b346368133960b02ad03Eric Laurent T* tmp = b.ptr; 86c55a96383497a772a307b346368133960b02ad03Eric Laurent b.ptr = ptr; 87c55a96383497a772a307b346368133960b02ad03Eric Laurent ptr = tmp; 88c55a96383497a772a307b346368133960b02ad03Eric Laurent } 89c55a96383497a772a307b346368133960b02ad03Eric Laurent 90c55a96383497a772a307b346368133960b02ad03Eric Laurent T* release() { 91c55a96383497a772a307b346368133960b02ad03Eric Laurent T* tmp = ptr; 92c55a96383497a772a307b346368133960b02ad03Eric Laurent ptr = NULL; 93c55a96383497a772a307b346368133960b02ad03Eric Laurent return tmp; 94c55a96383497a772a307b346368133960b02ad03Eric Laurent } 95c55a96383497a772a307b346368133960b02ad03Eric Laurent 96c55a96383497a772a307b346368133960b02ad03Eric Laurent T** accept() { 97c55a96383497a772a307b346368133960b02ad03Eric Laurent if (ptr) { 98c55a96383497a772a307b346368133960b02ad03Eric Laurent delete ptr; 99c55a96383497a772a307b346368133960b02ad03Eric Laurent ptr = NULL; 100c55a96383497a772a307b346368133960b02ad03Eric Laurent } 101c55a96383497a772a307b346368133960b02ad03Eric Laurent return &ptr; 102c55a96383497a772a307b346368133960b02ad03Eric Laurent } 103c55a96383497a772a307b346368133960b02ad03Eric Laurent 104c55a96383497a772a307b346368133960b02ad03Eric Laurent T** use() { 105c55a96383497a772a307b346368133960b02ad03Eric Laurent return &ptr; 106c55a96383497a772a307b346368133960b02ad03Eric Laurent } 107c55a96383497a772a307b346368133960b02ad03Eric Laurent}; 108c55a96383497a772a307b346368133960b02ad03Eric Laurent 109c55a96383497a772a307b346368133960b02ad03Eric Laurenttemplate<typename T> inline 110c55a96383497a772a307b346368133960b02ad03Eric Laurentvoid swap(scoped_ptr<T>& a, scoped_ptr<T>& b) { 111c55a96383497a772a307b346368133960b02ad03Eric Laurent a.swap(b); 112c55a96383497a772a307b346368133960b02ad03Eric Laurent} 113c55a96383497a772a307b346368133960b02ad03Eric Laurent 114c55a96383497a772a307b346368133960b02ad03Eric Laurent 115c55a96383497a772a307b346368133960b02ad03Eric Laurent 116c55a96383497a772a307b346368133960b02ad03Eric Laurent 117c55a96383497a772a307b346368133960b02ad03Eric Laurent// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to 118c55a96383497a772a307b346368133960b02ad03Eric Laurent// is guaranteed, either on destruction of the scoped_array or via an explicit 119c55a96383497a772a307b346368133960b02ad03Eric Laurent// reset(). Use shared_array or std::vector if your needs are more complex. 120c55a96383497a772a307b346368133960b02ad03Eric Laurent 121c55a96383497a772a307b346368133960b02ad03Eric Laurenttemplate<typename T> 122c55a96383497a772a307b346368133960b02ad03Eric Laurentclass scoped_array { 123c55a96383497a772a307b346368133960b02ad03Eric Laurent private: 124c55a96383497a772a307b346368133960b02ad03Eric Laurent 125c55a96383497a772a307b346368133960b02ad03Eric Laurent T* ptr; 126c55a96383497a772a307b346368133960b02ad03Eric Laurent 127c55a96383497a772a307b346368133960b02ad03Eric Laurent scoped_array(scoped_array const &); 128c55a96383497a772a307b346368133960b02ad03Eric Laurent scoped_array & operator=(scoped_array const &); 129c55a96383497a772a307b346368133960b02ad03Eric Laurent 130c55a96383497a772a307b346368133960b02ad03Eric Laurent public: 131c55a96383497a772a307b346368133960b02ad03Eric Laurent 132c55a96383497a772a307b346368133960b02ad03Eric Laurent typedef T element_type; 133c55a96383497a772a307b346368133960b02ad03Eric Laurent 134c55a96383497a772a307b346368133960b02ad03Eric Laurent explicit scoped_array(T* p = NULL) : ptr(p) {} 135c55a96383497a772a307b346368133960b02ad03Eric Laurent 136c55a96383497a772a307b346368133960b02ad03Eric Laurent ~scoped_array() { 137c55a96383497a772a307b346368133960b02ad03Eric Laurent typedef char type_must_be_complete[sizeof(T)]; 138c55a96383497a772a307b346368133960b02ad03Eric Laurent delete[] ptr; 139c55a96383497a772a307b346368133960b02ad03Eric Laurent } 140c55a96383497a772a307b346368133960b02ad03Eric Laurent 141c55a96383497a772a307b346368133960b02ad03Eric Laurent void reset(T* p = NULL) { 142c55a96383497a772a307b346368133960b02ad03Eric Laurent typedef char type_must_be_complete[sizeof(T)]; 143c55a96383497a772a307b346368133960b02ad03Eric Laurent 144c55a96383497a772a307b346368133960b02ad03Eric Laurent if (ptr != p) { 145c55a96383497a772a307b346368133960b02ad03Eric Laurent T* arr = ptr; 146c55a96383497a772a307b346368133960b02ad03Eric Laurent ptr = p; 147c55a96383497a772a307b346368133960b02ad03Eric Laurent // Delete last, in case arr destructor indirectly results in ~scoped_array 148c55a96383497a772a307b346368133960b02ad03Eric Laurent delete [] arr; 149c55a96383497a772a307b346368133960b02ad03Eric Laurent } 150c55a96383497a772a307b346368133960b02ad03Eric Laurent } 151c55a96383497a772a307b346368133960b02ad03Eric Laurent 152c55a96383497a772a307b346368133960b02ad03Eric Laurent T& operator[](std::ptrdiff_t i) const { 153c55a96383497a772a307b346368133960b02ad03Eric Laurent assert(ptr != NULL); 154c55a96383497a772a307b346368133960b02ad03Eric Laurent assert(i >= 0); 155c55a96383497a772a307b346368133960b02ad03Eric Laurent return ptr[i]; 156c55a96383497a772a307b346368133960b02ad03Eric Laurent } 157c55a96383497a772a307b346368133960b02ad03Eric Laurent 158c55a96383497a772a307b346368133960b02ad03Eric Laurent T* get() const { 159c55a96383497a772a307b346368133960b02ad03Eric Laurent return ptr; 160c55a96383497a772a307b346368133960b02ad03Eric Laurent } 161c55a96383497a772a307b346368133960b02ad03Eric Laurent 162c55a96383497a772a307b346368133960b02ad03Eric Laurent void swap(scoped_array & b) { 163c55a96383497a772a307b346368133960b02ad03Eric Laurent T* tmp = b.ptr; 164c55a96383497a772a307b346368133960b02ad03Eric Laurent b.ptr = ptr; 165c55a96383497a772a307b346368133960b02ad03Eric Laurent ptr = tmp; 166c55a96383497a772a307b346368133960b02ad03Eric Laurent } 167c55a96383497a772a307b346368133960b02ad03Eric Laurent 168c55a96383497a772a307b346368133960b02ad03Eric Laurent T* release() { 169c55a96383497a772a307b346368133960b02ad03Eric Laurent T* tmp = ptr; 170c55a96383497a772a307b346368133960b02ad03Eric Laurent ptr = NULL; 171c55a96383497a772a307b346368133960b02ad03Eric Laurent return tmp; 172c55a96383497a772a307b346368133960b02ad03Eric Laurent } 173c55a96383497a772a307b346368133960b02ad03Eric Laurent 174c55a96383497a772a307b346368133960b02ad03Eric Laurent T** accept() { 175c55a96383497a772a307b346368133960b02ad03Eric Laurent if (ptr) { 176c55a96383497a772a307b346368133960b02ad03Eric Laurent delete [] ptr; 177c55a96383497a772a307b346368133960b02ad03Eric Laurent ptr = NULL; 178c55a96383497a772a307b346368133960b02ad03Eric Laurent } 179c55a96383497a772a307b346368133960b02ad03Eric Laurent return &ptr; 180c55a96383497a772a307b346368133960b02ad03Eric Laurent } 181c55a96383497a772a307b346368133960b02ad03Eric Laurent}; 182c55a96383497a772a307b346368133960b02ad03Eric Laurent 183c55a96383497a772a307b346368133960b02ad03Eric Laurenttemplate<class T> inline 184c55a96383497a772a307b346368133960b02ad03Eric Laurentvoid swap(scoped_array<T>& a, scoped_array<T>& b) { 185c55a96383497a772a307b346368133960b02ad03Eric Laurent a.swap(b); 186c55a96383497a772a307b346368133960b02ad03Eric Laurent} 187c55a96383497a772a307b346368133960b02ad03Eric Laurent 188c55a96383497a772a307b346368133960b02ad03Eric Laurent// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a 189c55a96383497a772a307b346368133960b02ad03Eric Laurent// second template argument, the function used to free the object. 190c55a96383497a772a307b346368133960b02ad03Eric Laurent 191c55a96383497a772a307b346368133960b02ad03Eric Laurenttemplate<typename T, void (*FF)(void*) = free> class scoped_ptr_malloc { 192c55a96383497a772a307b346368133960b02ad03Eric Laurent private: 193c55a96383497a772a307b346368133960b02ad03Eric Laurent 194c55a96383497a772a307b346368133960b02ad03Eric Laurent T* ptr; 195c55a96383497a772a307b346368133960b02ad03Eric Laurent 196c55a96383497a772a307b346368133960b02ad03Eric Laurent scoped_ptr_malloc(scoped_ptr_malloc const &); 197c55a96383497a772a307b346368133960b02ad03Eric Laurent scoped_ptr_malloc & operator=(scoped_ptr_malloc const &); 198c55a96383497a772a307b346368133960b02ad03Eric Laurent 199c55a96383497a772a307b346368133960b02ad03Eric Laurent public: 200c55a96383497a772a307b346368133960b02ad03Eric Laurent 201c55a96383497a772a307b346368133960b02ad03Eric Laurent typedef T element_type; 202c55a96383497a772a307b346368133960b02ad03Eric Laurent 203c55a96383497a772a307b346368133960b02ad03Eric Laurent explicit scoped_ptr_malloc(T* p = 0): ptr(p) {} 204c55a96383497a772a307b346368133960b02ad03Eric Laurent 205c55a96383497a772a307b346368133960b02ad03Eric Laurent ~scoped_ptr_malloc() { 206c55a96383497a772a307b346368133960b02ad03Eric Laurent FF(static_cast<void*>(ptr)); 207c55a96383497a772a307b346368133960b02ad03Eric Laurent } 208c55a96383497a772a307b346368133960b02ad03Eric Laurent 209c55a96383497a772a307b346368133960b02ad03Eric Laurent void reset(T* p = 0) { 210c55a96383497a772a307b346368133960b02ad03Eric Laurent if (ptr != p) { 211c55a96383497a772a307b346368133960b02ad03Eric Laurent FF(static_cast<void*>(ptr)); 212c55a96383497a772a307b346368133960b02ad03Eric Laurent ptr = p; 213c55a96383497a772a307b346368133960b02ad03Eric Laurent } 214c55a96383497a772a307b346368133960b02ad03Eric Laurent } 215c55a96383497a772a307b346368133960b02ad03Eric Laurent 216c55a96383497a772a307b346368133960b02ad03Eric Laurent T& operator*() const { 217c55a96383497a772a307b346368133960b02ad03Eric Laurent assert(ptr != 0); 218c55a96383497a772a307b346368133960b02ad03Eric Laurent return *ptr; 219c55a96383497a772a307b346368133960b02ad03Eric Laurent } 220c55a96383497a772a307b346368133960b02ad03Eric Laurent 221c55a96383497a772a307b346368133960b02ad03Eric Laurent T* operator->() const { 222c55a96383497a772a307b346368133960b02ad03Eric Laurent assert(ptr != 0); 223c55a96383497a772a307b346368133960b02ad03Eric Laurent return ptr; 224c55a96383497a772a307b346368133960b02ad03Eric Laurent } 225c55a96383497a772a307b346368133960b02ad03Eric Laurent 226c55a96383497a772a307b346368133960b02ad03Eric Laurent T* get() const { 227c55a96383497a772a307b346368133960b02ad03Eric Laurent return ptr; 228c55a96383497a772a307b346368133960b02ad03Eric Laurent } 229c55a96383497a772a307b346368133960b02ad03Eric Laurent 230c55a96383497a772a307b346368133960b02ad03Eric Laurent void swap(scoped_ptr_malloc & b) { 231c55a96383497a772a307b346368133960b02ad03Eric Laurent T* tmp = b.ptr; 232c55a96383497a772a307b346368133960b02ad03Eric Laurent b.ptr = ptr; 233c55a96383497a772a307b346368133960b02ad03Eric Laurent ptr = tmp; 234c55a96383497a772a307b346368133960b02ad03Eric Laurent } 235c55a96383497a772a307b346368133960b02ad03Eric Laurent 236c55a96383497a772a307b346368133960b02ad03Eric Laurent T* release() { 237c55a96383497a772a307b346368133960b02ad03Eric Laurent T* tmp = ptr; 238c55a96383497a772a307b346368133960b02ad03Eric Laurent ptr = 0; 239c55a96383497a772a307b346368133960b02ad03Eric Laurent return tmp; 240c55a96383497a772a307b346368133960b02ad03Eric Laurent } 241c55a96383497a772a307b346368133960b02ad03Eric Laurent 242c55a96383497a772a307b346368133960b02ad03Eric Laurent T** accept() { 243c55a96383497a772a307b346368133960b02ad03Eric Laurent if (ptr) { 244c55a96383497a772a307b346368133960b02ad03Eric Laurent FF(static_cast<void*>(ptr)); 245c55a96383497a772a307b346368133960b02ad03Eric Laurent ptr = 0; 246c55a96383497a772a307b346368133960b02ad03Eric Laurent } 247c55a96383497a772a307b346368133960b02ad03Eric Laurent return &ptr; 248c55a96383497a772a307b346368133960b02ad03Eric Laurent } 249c55a96383497a772a307b346368133960b02ad03Eric Laurent}; 250c55a96383497a772a307b346368133960b02ad03Eric Laurent 251c55a96383497a772a307b346368133960b02ad03Eric Laurenttemplate<typename T, void (*FF)(void*)> inline 252c55a96383497a772a307b346368133960b02ad03Eric Laurentvoid swap(scoped_ptr_malloc<T,FF>& a, scoped_ptr_malloc<T,FF>& b) { 253c55a96383497a772a307b346368133960b02ad03Eric Laurent a.swap(b); 254c55a96383497a772a307b346368133960b02ad03Eric Laurent} 255c55a96383497a772a307b346368133960b02ad03Eric Laurent 256c55a96383497a772a307b346368133960b02ad03Eric Laurent} // namespace webrtc 257c55a96383497a772a307b346368133960b02ad03Eric Laurent 258c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif // #ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_SCOPED_PTR_H_ 259