xref: /haiku/headers/build/private/shared/AutoDeleter.h (revision c90684742e7361651849be4116d0e5de3a817194)
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 /*!	Scope-based automatic deletion of objects/arrays.
9 	ObjectDeleter  - deletes an object
10 	ArrayDeleter   - deletes an array
11 	MemoryDeleter  - free()s malloc()ed memory
12 	CObjectDeleter - calls an arbitrary specified destructor function
13 */
14 
15 #include <stdlib.h>
16 
17 namespace BPrivate {
18 
19 // AutoDeleter
20 
21 template<typename C, typename DeleteFunc>
22 class AutoDeleter {
23 public:
24 	inline AutoDeleter()
25 		: fObject(NULL)
26 	{
27 	}
28 
29 	inline AutoDeleter(C *object)
30 		: fObject(object)
31 	{
32 	}
33 
34 	inline ~AutoDeleter()
35 	{
36 		fDelete(fObject);
37 	}
38 
39 	inline void SetTo(C *object)
40 	{
41 		if (object != fObject) {
42 			fDelete(fObject);
43 			fObject = object;
44 		}
45 	}
46 
47 	inline void Unset()
48 	{
49 		SetTo(NULL);
50 	}
51 
52 	inline void Delete()
53 	{
54 		SetTo(NULL);
55 	}
56 
57 	inline C *Get() const
58 	{
59 		return fObject;
60 	}
61 
62 	inline C *Detach()
63 	{
64 		C *object = fObject;
65 		fObject = NULL;
66 		return object;
67 	}
68 
69 protected:
70 	C			*fObject;
71 	DeleteFunc	fDelete;
72 };
73 
74 
75 // ObjectDeleter
76 
77 template<typename C>
78 struct ObjectDelete
79 {
80 	inline void operator()(C *object)
81 	{
82 		delete object;
83 	}
84 };
85 
86 template<typename C>
87 struct ObjectDeleter : AutoDeleter<C, ObjectDelete<C> >
88 {
89 	ObjectDeleter() : AutoDeleter<C, ObjectDelete<C> >() {}
90 	ObjectDeleter(C *object) : AutoDeleter<C, ObjectDelete<C> >(object) {}
91 };
92 
93 
94 // ArrayDeleter
95 
96 template<typename C>
97 struct ArrayDelete
98 {
99 	inline void operator()(C *array)
100 	{
101 		delete[] array;
102 	}
103 };
104 
105 template<typename C>
106 struct ArrayDeleter : AutoDeleter<C, ArrayDelete<C> >
107 {
108 	ArrayDeleter() : AutoDeleter<C, ArrayDelete<C> >() {}
109 	ArrayDeleter(C *array) : AutoDeleter<C, ArrayDelete<C> >(array) {}
110 };
111 
112 
113 // MemoryDeleter
114 
115 struct MemoryDelete
116 {
117 	inline void operator()(void *memory)
118 	{
119 		free(memory);
120 	}
121 };
122 
123 struct MemoryDeleter : AutoDeleter<void, MemoryDelete >
124 {
125 	MemoryDeleter() : AutoDeleter<void, MemoryDelete >() {}
126 	MemoryDeleter(void *memory) : AutoDeleter<void, MemoryDelete >(memory) {}
127 };
128 
129 
130 // CObjectDeleter
131 
132 template<typename Type, typename DestructorReturnType>
133 struct CObjectDelete
134 {
135 	inline void operator()(Type *object)
136 	{
137 		if (fDestructor != NULL && object != NULL)
138 			fDestructor(object);
139 	}
140 
141 	template<typename Destructor>
142 	inline void operator=(Destructor destructor)
143 	{
144 		fDestructor = destructor;
145 	}
146 
147 private:
148 	DestructorReturnType (*fDestructor)(Type*);
149 };
150 
151 template<typename Type, typename DestructorReturnType = void>
152 struct CObjectDeleter
153 	: AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType> >
154 {
155 	typedef AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType> > Base;
156 
157 	template<typename Destructor>
158 	CObjectDeleter(Destructor destructor) : Base()
159 	{
160 		Base::fDelete = destructor;
161 	}
162 
163 	template<typename Destructor>
164 	CObjectDeleter(Type *object, Destructor destructor) : Base(object)
165 	{
166 		Base::fDelete = destructor;
167 	}
168 };
169 
170 
171 // MethodDeleter
172 
173 template<typename Type, typename DestructorReturnType>
174 struct MethodDelete
175 {
176 	inline void operator()(Type *object)
177 	{
178 		if (fDestructor && object != NULL)
179 			(object->*fDestructor)();
180 	}
181 
182 	template<typename Destructor>
183 	inline void operator=(Destructor destructor)
184 	{
185 		fDestructor = destructor;
186 	}
187 
188 private:
189 	DestructorReturnType (Type::*fDestructor)();
190 };
191 
192 
193 template<typename Type, typename DestructorReturnType = void>
194 struct MethodDeleter
195 	: AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> >
196 {
197 	typedef AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> > Base;
198 
199 	template<typename Destructor>
200 	MethodDeleter(Destructor destructor) : Base()
201 	{
202 		Base::fDelete = destructor;
203 	}
204 
205 	template<typename Destructor>
206 	MethodDeleter(Type *object, Destructor destructor) : Base(object)
207 	{
208 		Base::fDelete = destructor;
209 	}
210 };
211 
212 }	// namespace BPrivate
213 
214 using BPrivate::ObjectDeleter;
215 using BPrivate::ArrayDeleter;
216 using BPrivate::MemoryDeleter;
217 using BPrivate::CObjectDeleter;
218 using BPrivate::MethodDeleter;
219 
220 #endif	// _AUTO_DELETER_H
221