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