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