1/* 2 * Copyright 2001-2007, Ingo Weinhold, bonefish@users.sf.net. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5#ifndef _AUTO_DELETER_H 6#define _AUTO_DELETER_H 7 8/*! Scope-based automatic deletion of objects/arrays. 9 ObjectDeleter - deletes an object 10 ArrayDeleter - deletes an array 11 MemoryDeleter - free()s malloc()ed memory 12 CObjectDeleter - calls an arbitrary specified destructor function 13*/ 14 15#include <stdlib.h> 16 17namespace FSShell { 18 19// AutoDeleter 20 21template<typename C, typename DeleteFunc> 22class AutoDeleter { 23public: 24 inline AutoDeleter() 25 : fObject(NULL) 26 { 27 } 28 29 inline AutoDeleter(C *object) 30 : fObject(object) 31 { 32 } 33 34 inline ~AutoDeleter() 35 { 36 fDelete(fObject); 37 } 38 39 inline void SetTo(C *object) 40 { 41 if (object != fObject) { 42 fDelete(fObject); 43 fObject = object; 44 } 45 } 46 47 inline void Unset() 48 { 49 SetTo(NULL); 50 } 51 52 inline void Delete() 53 { 54 SetTo(NULL); 55 } 56 57 inline C *Get() const 58 { 59 return fObject; 60 } 61 62 inline C *Detach() 63 { 64 C *object = fObject; 65 fObject = NULL; 66 return object; 67 } 68 69protected: 70 C *fObject; 71 DeleteFunc fDelete; 72}; 73 74 75// ObjectDeleter 76 77template<typename C> 78struct ObjectDelete 79{ 80 inline void operator()(C *object) 81 { 82 delete object; 83 } 84}; 85 86template<typename C> 87struct ObjectDeleter : AutoDeleter<C, ObjectDelete<C> > 88{ 89 ObjectDeleter() : AutoDeleter<C, ObjectDelete<C> >() {} 90 ObjectDeleter(C *object) : AutoDeleter<C, ObjectDelete<C> >(object) {} 91}; 92 93 94// ArrayDeleter 95 96template<typename C> 97struct ArrayDelete 98{ 99 inline void operator()(C *array) 100 { 101 delete[] array; 102 } 103}; 104 105template<typename C> 106struct ArrayDeleter : AutoDeleter<C, ArrayDelete<C> > 107{ 108 ArrayDeleter() : AutoDeleter<C, ArrayDelete<C> >() {} 109 ArrayDeleter(C *array) : AutoDeleter<C, ArrayDelete<C> >(array) {} 110}; 111 112 113// MemoryDeleter 114 115struct MemoryDelete 116{ 117 inline void operator()(void *memory) 118 { 119 free(memory); 120 } 121}; 122 123struct MemoryDeleter : AutoDeleter<void, MemoryDelete > 124{ 125 MemoryDeleter() : AutoDeleter<void, MemoryDelete >() {} 126 MemoryDeleter(void *memory) : AutoDeleter<void, MemoryDelete >(memory) {} 127}; 128 129 130// CObjectDeleter 131 132template<typename Type, typename DestructorReturnType, 133 DestructorReturnType (*Destructor)(Type*)> 134struct CObjectDelete 135{ 136 inline void operator()(Type *object) 137 { 138 if (object != NULL) 139 Destructor(object); 140 } 141}; 142 143template<typename Type, typename DestructorReturnType, 144 DestructorReturnType (*Destructor)(Type*)> 145struct CObjectDeleter 146 : AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType, Destructor> > 147{ 148 typedef AutoDeleter<Type, 149 CObjectDelete<Type, DestructorReturnType, Destructor> > Base; 150 151 CObjectDeleter() : Base() 152 { 153 } 154 155 CObjectDeleter(Type *object) : Base(object) 156 { 157 } 158}; 159 160 161// MethodDeleter 162 163template<typename Type, typename DestructorReturnType> 164struct MethodDelete 165{ 166 inline void operator()(Type *object) 167 { 168 if (fDestructor && object != NULL) 169 (object->*fDestructor)(); 170 } 171 172 template<typename Destructor> 173 inline void operator=(Destructor destructor) 174 { 175 fDestructor = destructor; 176 } 177 178private: 179 DestructorReturnType (Type::*fDestructor)(); 180}; 181 182 183template<typename Type, typename DestructorReturnType = void> 184struct MethodDeleter 185 : AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> > 186{ 187 typedef AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> > Base; 188 189 template<typename Destructor> 190 MethodDeleter(Destructor destructor) : Base() 191 { 192 Base::fDelete = destructor; 193 } 194 195 template<typename Destructor> 196 MethodDeleter(Type *object, Destructor destructor) : Base(object) 197 { 198 Base::fDelete = destructor; 199 } 200}; 201 202} // namespace FSShell 203 204using FSShell::ObjectDeleter; 205using FSShell::ArrayDeleter; 206using FSShell::MemoryDeleter; 207using FSShell::CObjectDeleter; 208using FSShell::MethodDeleter; 209 210#endif // _AUTO_DELETER_H 211