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