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 9 /*! Scope-based automatic deletion of objects/arrays. 10 ObjectDeleter - deletes an object 11 ArrayDeleter - deletes an array 12 MemoryDeleter - free()s malloc()ed memory 13 CObjectDeleter - calls an arbitrary specified destructor function 14 HandleDeleter - use arbitrary handle type and destructor function 15 FileDescriptorCloser - closes a file descriptor, based on HandleDeleter 16 */ 17 18 19 #include <stdlib.h> 20 #include <unistd.h> 21 22 23 namespace BPrivate { 24 25 26 // AutoDeleter 27 28 template<typename C, typename DeleteFunc> 29 class AutoDeleter { 30 public: 31 inline AutoDeleter() 32 : fObject(NULL) 33 { 34 } 35 36 inline AutoDeleter(C *object) 37 : fObject(object) 38 { 39 } 40 41 inline ~AutoDeleter() 42 { 43 DeleteFunc destructor; 44 destructor(fObject); 45 } 46 47 inline void SetTo(C *object) 48 { 49 if (object != fObject) { 50 DeleteFunc destructor; 51 destructor(fObject); 52 fObject = object; 53 } 54 } 55 56 inline void Unset() 57 { 58 SetTo(NULL); 59 } 60 61 inline void Delete() 62 { 63 SetTo(NULL); 64 } 65 66 inline C *Get() const 67 { 68 return fObject; 69 } 70 71 inline C *Detach() 72 { 73 C *object = fObject; 74 fObject = NULL; 75 return object; 76 } 77 78 inline C *operator->() const 79 { 80 return fObject; 81 } 82 83 protected: 84 C *fObject; 85 86 private: 87 AutoDeleter(const AutoDeleter&); 88 AutoDeleter& operator=(const AutoDeleter&); 89 }; 90 91 92 // ObjectDeleter 93 94 template<typename C> 95 struct ObjectDelete 96 { 97 inline void operator()(C *object) 98 { 99 delete object; 100 } 101 }; 102 103 template<typename C> 104 struct ObjectDeleter : AutoDeleter<C, ObjectDelete<C> > 105 { 106 ObjectDeleter() : AutoDeleter<C, ObjectDelete<C> >() {} 107 ObjectDeleter(C *object) : AutoDeleter<C, ObjectDelete<C> >(object) {} 108 }; 109 110 111 // ArrayDeleter 112 113 template<typename C> 114 struct ArrayDelete 115 { 116 inline void operator()(C *array) 117 { 118 delete[] array; 119 } 120 }; 121 122 template<typename C> 123 struct ArrayDeleter : AutoDeleter<C, ArrayDelete<C> > 124 { 125 ArrayDeleter() : AutoDeleter<C, ArrayDelete<C> >() {} 126 ArrayDeleter(C *array) : AutoDeleter<C, ArrayDelete<C> >(array) {} 127 128 inline C& operator[](size_t index) const 129 { 130 return this->Get()[index]; 131 } 132 }; 133 134 135 // MemoryDeleter 136 137 struct MemoryDelete 138 { 139 inline void operator()(void *memory) 140 { 141 free(memory); 142 } 143 }; 144 145 struct MemoryDeleter : AutoDeleter<void, MemoryDelete > 146 { 147 MemoryDeleter() : AutoDeleter<void, MemoryDelete >() {} 148 MemoryDeleter(void *memory) : AutoDeleter<void, MemoryDelete >(memory) {} 149 }; 150 151 152 // CObjectDeleter 153 154 template<typename Type, typename DestructorReturnType, 155 DestructorReturnType (*Destructor)(Type*)> 156 struct CObjectDelete 157 { 158 inline void operator()(Type *object) 159 { 160 if (object != NULL) 161 Destructor(object); 162 } 163 }; 164 165 template<typename Type, typename DestructorReturnType, 166 DestructorReturnType (*Destructor)(Type*)> 167 struct CObjectDeleter 168 : AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType, Destructor> > 169 { 170 typedef AutoDeleter<Type, 171 CObjectDelete<Type, DestructorReturnType, Destructor> > Base; 172 173 CObjectDeleter() : Base() 174 { 175 } 176 177 CObjectDeleter(Type *object) : Base(object) 178 { 179 } 180 }; 181 182 183 // MethodDeleter 184 185 template<typename Type, typename DestructorReturnType, 186 DestructorReturnType (Type::*Destructor)()> 187 struct MethodDelete 188 { 189 inline void operator()(Type *object) 190 { 191 if (object != NULL) 192 (object->*Destructor)(); 193 } 194 }; 195 196 197 template<typename Type, typename DestructorReturnType, 198 DestructorReturnType (Type::*Destructor)()> 199 struct MethodDeleter 200 : AutoDeleter<Type, MethodDelete<Type, DestructorReturnType, Destructor> > 201 { 202 typedef AutoDeleter<Type, 203 MethodDelete<Type, DestructorReturnType, Destructor> > Base; 204 205 MethodDeleter() : Base() 206 { 207 } 208 209 MethodDeleter(Type *object) : Base(object) 210 { 211 } 212 }; 213 214 215 // HandleDeleter 216 217 template<typename C, typename DestructorResult, 218 DestructorResult (*Destructor)(C), C nullValue = -1> 219 class HandleDeleter { 220 public: 221 inline HandleDeleter() 222 : fHandle(nullValue) 223 { 224 } 225 226 inline HandleDeleter(C handle) 227 : fHandle(handle) 228 { 229 } 230 231 inline ~HandleDeleter() 232 { 233 Destructor(fHandle); 234 } 235 236 inline void SetTo(C handle) 237 { 238 if (handle != fHandle) { 239 Destructor(fHandle); 240 fHandle = handle; 241 } 242 } 243 244 inline void Unset() 245 { 246 SetTo(nullValue); 247 } 248 249 inline void Delete() 250 { 251 SetTo(nullValue); 252 } 253 254 inline C Get() const 255 { 256 return fHandle; 257 } 258 259 inline C Detach() 260 { 261 C handle = fHandle; 262 fHandle = nullValue; 263 return handle; 264 } 265 266 protected: 267 C fHandle; 268 269 private: 270 HandleDeleter(const HandleDeleter&); 271 HandleDeleter& operator=(const HandleDeleter&); 272 }; 273 274 275 // FileDescriptorCloser 276 277 typedef HandleDeleter<int, int, close, -1> FileDescriptorCloser; 278 279 280 } // namespace BPrivate 281 282 283 using ::BPrivate::ObjectDeleter; 284 using ::BPrivate::ArrayDeleter; 285 using ::BPrivate::MemoryDeleter; 286 using ::BPrivate::CObjectDeleter; 287 using ::BPrivate::MethodDeleter; 288 using ::BPrivate::HandleDeleter; 289 using ::BPrivate::FileDescriptorCloser; 290 291 292 #endif // _AUTO_DELETER_H 293