1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef BASE_SCOPED_PTR_H 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define BASE_SCOPED_PTR_H 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright (c) 2001, 2002 Peter Dimov 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Permission to copy, use, modify, sell and distribute this software 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// is granted provided this copyright notice appears in all copies. 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This software is provided "as is" without express or implied 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// warranty, and with no claim as to its suitability for any purpose. 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation. 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// scoped_ptr mimics a built-in pointer except that it guarantees deletion 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// of the object pointed to, either on destruction of the scoped_ptr or via 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// an explicit reset(). scoped_ptr is a simple solution for simple needs; 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// use shared_ptr or std::auto_ptr if your needs are more complex. 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// *** NOTE *** 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// If your scoped_ptr is a class member of class FOO pointing to a 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// forward declared type BAR (as shown below), then you MUST use a non-inlined 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// version of the destructor. The destructor of a scoped_ptr (called from 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// FOO's destructor) must have a complete definition of BAR in order to 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// destroy it. Example: 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// -- foo.h -- 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// class BAR; 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// class FOO { 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// public: 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// FOO(); 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ~FOO(); // Required for sources that instantiate class FOO to compile! 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// private: 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// scoped_ptr<BAR> bar_; 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// }; 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// -- foo.cc -- 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// #include "foo.h" 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// FOO::~FOO() {} // Empty, but must be non-inlined to FOO's class definition. 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <cstddef> // for std::ptrdiff_t 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <assert.h> // for assert 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdlib.h> // for free() decl 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <typename T> 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass scoped_ptr { 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* ptr; 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr(scoped_ptr const &); 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr & operator=(scoped_ptr const &); 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef T element_type; 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit scoped_ptr(T* p = 0): ptr(p) {} 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~scoped_ptr() { 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef char type_must_be_complete[sizeof(T)]; 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete ptr; 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void reset(T* p = 0) { 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef char type_must_be_complete[sizeof(T)]; 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ptr != p) { 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete ptr; 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ptr = p; 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T& operator*() const { 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott assert(ptr != 0); 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return *ptr; 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* operator->() const { 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott assert(ptr != 0); 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ptr; 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool operator==(T* p) const { 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ptr == p; 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool operator!=(T* p) const { 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ptr != p; 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* get() const { 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ptr; 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void swap(scoped_ptr & b) { 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* tmp = b.ptr; 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott b.ptr = ptr; 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ptr = tmp; 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* release() { 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* tmp = ptr; 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ptr = 0; 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return tmp; 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // no reason to use these: each scoped_ptr should have its own object 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott template <typename U> bool operator==(scoped_ptr<U> const& p) const; 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott template <typename U> bool operator!=(scoped_ptr<U> const& p) const; 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<typename T> inline 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid swap(scoped_ptr<T>& a, scoped_ptr<T>& b) { 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott a.swap(b); 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<typename T> inline 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool operator==(T* p, const scoped_ptr<T>& b) { 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return p == b.get(); 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<typename T> inline 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool operator!=(T* p, const scoped_ptr<T>& b) { 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return p != b.get(); 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// is guaranteed, either on destruction of the scoped_array or via an explicit 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// reset(). Use shared_array or std::vector if your needs are more complex. 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<typename T> 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass scoped_array { 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* ptr; 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_array(scoped_array const &); 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_array & operator=(scoped_array const &); 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef T element_type; 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit scoped_array(T* p = 0) : ptr(p) {} 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~scoped_array() { 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef char type_must_be_complete[sizeof(T)]; 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete[] ptr; 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void reset(T* p = 0) { 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef char type_must_be_complete[sizeof(T)]; 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ptr != p) { 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete [] ptr; 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ptr = p; 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T& operator[](std::ptrdiff_t i) const { 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott assert(ptr != 0); 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott assert(i >= 0); 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ptr[i]; 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool operator==(T* p) const { 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ptr == p; 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool operator!=(T* p) const { 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ptr != p; 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* get() const { 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ptr; 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void swap(scoped_array & b) { 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* tmp = b.ptr; 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott b.ptr = ptr; 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ptr = tmp; 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* release() { 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* tmp = ptr; 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ptr = 0; 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return tmp; 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // no reason to use these: each scoped_array should have its own object 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott template <typename U> bool operator==(scoped_array<U> const& p) const; 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott template <typename U> bool operator!=(scoped_array<U> const& p) const; 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<class T> inline 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid swap(::scoped_array<T>& a, ::scoped_array<T>& b) { 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott a.swap(b); 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<typename T> inline 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool operator==(T* p, const ::scoped_array<T>& b) { 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return p == b.get(); 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<typename T> inline 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool operator!=(T* p, const ::scoped_array<T>& b) { 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return p != b.get(); 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This class wraps the c library function free() in a class that can be 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// passed as a template argument to scoped_ptr_malloc below. 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ScopedPtrMallocFree { 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott inline void operator()(void* x) const { 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free(x); 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// scoped_ptr_malloc<> is similar to scoped_ptr<>, but it accepts a 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// second template argument, the functor used to free the object. 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<typename T, typename FreeProc = ScopedPtrMallocFree> 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass scoped_ptr_malloc { 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* ptr; 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr_malloc(scoped_ptr_malloc const &); 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr_malloc & operator=(scoped_ptr_malloc const &); 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef T element_type; 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit scoped_ptr_malloc(T* p = 0): ptr(p) {} 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~scoped_ptr_malloc() { 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef char type_must_be_complete[sizeof(T)]; 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free_((void*) ptr); 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void reset(T* p = 0) { 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef char type_must_be_complete[sizeof(T)]; 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ptr != p) { 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott free_((void*) ptr); 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ptr = p; 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T& operator*() const { 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott assert(ptr != 0); 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return *ptr; 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* operator->() const { 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott assert(ptr != 0); 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ptr; 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool operator==(T* p) const { 270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ptr == p; 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool operator!=(T* p) const { 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ptr != p; 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* get() const { 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ptr; 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void swap(scoped_ptr_malloc & b) { 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* tmp = b.ptr; 283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott b.ptr = ptr; 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ptr = tmp; 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* release() { 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* tmp = ptr; 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ptr = 0; 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return tmp; 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // no reason to use these: each scoped_ptr_malloc should have its own object 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott template <typename U, typename GP> 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool operator==(scoped_ptr_malloc<U, GP> const& p) const; 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott template <typename U, typename GP> 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool operator!=(scoped_ptr_malloc<U, GP> const& p) const; 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static FreeProc const free_; 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<typename T, typename FP> 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottFP const scoped_ptr_malloc<T,FP>::free_ = FP(); 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<typename T, typename FP> inline 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid swap(scoped_ptr_malloc<T,FP>& a, scoped_ptr_malloc<T,FP>& b) { 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott a.swap(b); 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<typename T, typename FP> inline 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool operator==(T* p, const scoped_ptr_malloc<T,FP>& b) { 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return p == b.get(); 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<typename T, typename FP> inline 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool operator!=(T* p, const scoped_ptr_malloc<T,FP>& b) { 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return p != b.get(); 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // #ifndef BASE_SCOPED_PTR_H 323