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