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