xref: /haiku/headers/private/fs_shell/fssh_auto_deleter.h (revision 87f4776937505e3014251c9c3434be78ae29d7d0)
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 FSShell {
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 	DestructorReturnType (*Destructor)(Type*)>
134 struct CObjectDelete
135 {
136 	inline void operator()(Type *object)
137 	{
138 		if (object != NULL)
139 			Destructor(object);
140 	}
141 };
142 
143 template<typename Type, typename DestructorReturnType,
144 	DestructorReturnType (*Destructor)(Type*)>
145 struct CObjectDeleter
146 	: AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType, Destructor> >
147 {
148 	typedef AutoDeleter<Type,
149 		CObjectDelete<Type, DestructorReturnType, Destructor> > Base;
150 
151 	CObjectDeleter() : Base()
152 	{
153 	}
154 
155 	CObjectDeleter(Type *object) : Base(object)
156 	{
157 	}
158 };
159 
160 
161 // MethodDeleter
162 
163 template<typename Type, typename DestructorReturnType>
164 struct MethodDelete
165 {
166 	inline void operator()(Type *object)
167 	{
168 		if (fDestructor && object != NULL)
169 			(object->*fDestructor)();
170 	}
171 
172 	template<typename Destructor>
173 	inline void operator=(Destructor destructor)
174 	{
175 		fDestructor = destructor;
176 	}
177 
178 private:
179 	DestructorReturnType (Type::*fDestructor)();
180 };
181 
182 
183 template<typename Type, typename DestructorReturnType = void>
184 struct MethodDeleter
185 	: AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> >
186 {
187 	typedef AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> > Base;
188 
189 	template<typename Destructor>
190 	MethodDeleter(Destructor destructor) : Base()
191 	{
192 		Base::fDelete = destructor;
193 	}
194 
195 	template<typename Destructor>
196 	MethodDeleter(Type *object, Destructor destructor) : Base(object)
197 	{
198 		Base::fDelete = destructor;
199 	}
200 };
201 
202 }	// namespace FSShell
203 
204 using FSShell::ObjectDeleter;
205 using FSShell::ArrayDeleter;
206 using FSShell::MemoryDeleter;
207 using FSShell::CObjectDeleter;
208 using FSShell::MethodDeleter;
209 
210 #endif	// _AUTO_DELETER_H
211