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