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 17 namespace BPrivate { 18 19 // AutoDeleter 20 21 template<typename C, typename DeleteFunc> 22 class AutoDeleter { 23 public: 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 69 protected: 70 C *fObject; 71 DeleteFunc fDelete; 72 }; 73 74 75 // ObjectDeleter 76 77 template<typename C> 78 struct ObjectDelete 79 { 80 inline void operator()(C *object) 81 { 82 delete object; 83 } 84 }; 85 86 template<typename C> 87 struct 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 96 template<typename C> 97 struct ArrayDelete 98 { 99 inline void operator()(C *array) 100 { 101 delete[] array; 102 } 103 }; 104 105 template<typename C> 106 struct 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 115 struct MemoryDelete 116 { 117 inline void operator()(void *memory) 118 { 119 free(memory); 120 } 121 }; 122 123 struct MemoryDeleter : AutoDeleter<void, MemoryDelete > 124 { 125 MemoryDeleter() : AutoDeleter<void, MemoryDelete >() {} 126 MemoryDeleter(void *memory) : AutoDeleter<void, MemoryDelete >(memory) {} 127 }; 128 129 130 // CObjectDeleter 131 132 template<typename Type, typename DestructorReturnType> 133 struct CObjectDelete 134 { 135 inline void operator()(Type *object) 136 { 137 if (fDestructor != NULL && object != NULL) 138 fDestructor(object); 139 } 140 141 template<typename Destructor> 142 inline void operator=(Destructor destructor) 143 { 144 fDestructor = destructor; 145 } 146 147 private: 148 DestructorReturnType (*fDestructor)(Type*); 149 }; 150 151 template<typename Type, typename DestructorReturnType = void> 152 struct CObjectDeleter 153 : AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType> > 154 { 155 typedef AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType> > Base; 156 157 template<typename Destructor> 158 CObjectDeleter(Destructor destructor) : Base() 159 { 160 Base::fDelete = destructor; 161 } 162 163 template<typename Destructor> 164 CObjectDeleter(Type *object, Destructor destructor) : Base(object) 165 { 166 Base::fDelete = destructor; 167 } 168 }; 169 170 171 // MethodDeleter 172 173 template<typename Type, typename DestructorReturnType> 174 struct MethodDelete 175 { 176 inline void operator()(Type *object) 177 { 178 if (fDestructor && object != NULL) 179 (object->*fDestructor)(); 180 } 181 182 template<typename Destructor> 183 inline void operator=(Destructor destructor) 184 { 185 fDestructor = destructor; 186 } 187 188 private: 189 DestructorReturnType (Type::*fDestructor)(); 190 }; 191 192 193 template<typename Type, typename DestructorReturnType = void> 194 struct MethodDeleter 195 : AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> > 196 { 197 typedef AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> > Base; 198 199 template<typename Destructor> 200 MethodDeleter(Destructor destructor) : Base() 201 { 202 Base::fDelete = destructor; 203 } 204 205 template<typename Destructor> 206 MethodDeleter(Type *object, Destructor destructor) : Base(object) 207 { 208 Base::fDelete = destructor; 209 } 210 }; 211 212 } // namespace BPrivate 213 214 using BPrivate::ObjectDeleter; 215 using BPrivate::ArrayDeleter; 216 using BPrivate::MemoryDeleter; 217 using BPrivate::CObjectDeleter; 218 using BPrivate::MethodDeleter; 219 220 #endif // _AUTO_DELETER_H 221