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