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