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 FSShell { 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 DestructorReturnType (*Destructor)(Type*)> 134 struct CObjectDelete 135 { 136 inline void operator()(Type *object) 137 { 138 if (object != NULL) 139 Destructor(object); 140 } 141 }; 142 143 template<typename Type, typename DestructorReturnType, 144 DestructorReturnType (*Destructor)(Type*)> 145 struct CObjectDeleter 146 : AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType, Destructor> > 147 { 148 typedef AutoDeleter<Type, 149 CObjectDelete<Type, DestructorReturnType, Destructor> > Base; 150 151 CObjectDeleter() : Base() 152 { 153 } 154 155 CObjectDeleter(Type *object) : Base(object) 156 { 157 } 158 }; 159 160 161 // MethodDeleter 162 163 template<typename Type, typename DestructorReturnType> 164 struct MethodDelete 165 { 166 inline void operator()(Type *object) 167 { 168 if (fDestructor && object != NULL) 169 (object->*fDestructor)(); 170 } 171 172 template<typename Destructor> 173 inline void operator=(Destructor destructor) 174 { 175 fDestructor = destructor; 176 } 177 178 private: 179 DestructorReturnType (Type::*fDestructor)(); 180 }; 181 182 183 template<typename Type, typename DestructorReturnType = void> 184 struct MethodDeleter 185 : AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> > 186 { 187 typedef AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> > Base; 188 189 template<typename Destructor> 190 MethodDeleter(Destructor destructor) : Base() 191 { 192 Base::fDelete = destructor; 193 } 194 195 template<typename Destructor> 196 MethodDeleter(Type *object, Destructor destructor) : Base(object) 197 { 198 Base::fDelete = destructor; 199 } 200 }; 201 202 } // namespace FSShell 203 204 using FSShell::ObjectDeleter; 205 using FSShell::ArrayDeleter; 206 using FSShell::MemoryDeleter; 207 using FSShell::CObjectDeleter; 208 using FSShell::MethodDeleter; 209 210 #endif // _AUTO_DELETER_H 211