xref: /haiku/headers/private/shared/AutoDeleter.h (revision aecba91311ee8f598dc9c69c17e9bb499a0a43e6)
12851dbadSAxel Dörfler /*
22851dbadSAxel Dörfler  * Copyright 2001-2007, Ingo Weinhold, bonefish@users.sf.net. All rights reserved.
32851dbadSAxel Dörfler  * Distributed under the terms of the MIT License.
42851dbadSAxel Dörfler  */
5ce8cfdb8SIngo Weinhold #ifndef _AUTO_DELETER_H
6ce8cfdb8SIngo Weinhold #define _AUTO_DELETER_H
7ce8cfdb8SIngo Weinhold 
8d91215d3SAxel Dörfler 
92851dbadSAxel Dörfler /*!	Scope-based automatic deletion of objects/arrays.
102851dbadSAxel Dörfler 	ObjectDeleter  - deletes an object
112851dbadSAxel Dörfler 	ArrayDeleter   - deletes an array
122851dbadSAxel Dörfler 	MemoryDeleter  - free()s malloc()ed memory
1334cbfd39SIngo Weinhold 	CObjectDeleter - calls an arbitrary specified destructor function
14cb7ce9a3SAxel Dörfler 	FileDescriptorCloser - closes a file descriptor
152851dbadSAxel Dörfler */
162851dbadSAxel Dörfler 
17d91215d3SAxel Dörfler 
18ce8cfdb8SIngo Weinhold #include <stdlib.h>
19d91215d3SAxel Dörfler #include <unistd.h>
20d91215d3SAxel Dörfler 
21ce8cfdb8SIngo Weinhold 
22ce8cfdb8SIngo Weinhold namespace BPrivate {
23ce8cfdb8SIngo Weinhold 
24d91215d3SAxel Dörfler 
25ce8cfdb8SIngo Weinhold // AutoDeleter
26ce8cfdb8SIngo Weinhold 
27f277fb63SIngo Weinhold template<typename C, typename DeleteFunc>
28ce8cfdb8SIngo Weinhold class AutoDeleter {
29ce8cfdb8SIngo Weinhold public:
30ce8cfdb8SIngo Weinhold 	inline AutoDeleter()
31ce8cfdb8SIngo Weinhold 		: fObject(NULL)
32ce8cfdb8SIngo Weinhold 	{
33ce8cfdb8SIngo Weinhold 	}
34ce8cfdb8SIngo Weinhold 
35ce8cfdb8SIngo Weinhold 	inline AutoDeleter(C *object)
36ce8cfdb8SIngo Weinhold 		: fObject(object)
37ce8cfdb8SIngo Weinhold 	{
38ce8cfdb8SIngo Weinhold 	}
39ce8cfdb8SIngo Weinhold 
40ce8cfdb8SIngo Weinhold 	inline ~AutoDeleter()
41ce8cfdb8SIngo Weinhold 	{
42ce8cfdb8SIngo Weinhold 		fDelete(fObject);
43ce8cfdb8SIngo Weinhold 	}
44ce8cfdb8SIngo Weinhold 
45ce8cfdb8SIngo Weinhold 	inline void SetTo(C *object)
46ce8cfdb8SIngo Weinhold 	{
47f277fb63SIngo Weinhold 		if (object != fObject) {
48ce8cfdb8SIngo Weinhold 			fDelete(fObject);
49ce8cfdb8SIngo Weinhold 			fObject = object;
50ce8cfdb8SIngo Weinhold 		}
51f277fb63SIngo Weinhold 	}
52f277fb63SIngo Weinhold 
53f277fb63SIngo Weinhold 	inline void Unset()
54f277fb63SIngo Weinhold 	{
55f277fb63SIngo Weinhold 		SetTo(NULL);
56f277fb63SIngo Weinhold 	}
57f277fb63SIngo Weinhold 
58f277fb63SIngo Weinhold 	inline void Delete()
59f277fb63SIngo Weinhold 	{
60f277fb63SIngo Weinhold 		SetTo(NULL);
61f277fb63SIngo Weinhold 	}
62ce8cfdb8SIngo Weinhold 
635519ed57SIngo Weinhold 	inline C *Get() const
645519ed57SIngo Weinhold 	{
655519ed57SIngo Weinhold 		return fObject;
665519ed57SIngo Weinhold 	}
675519ed57SIngo Weinhold 
68ce8cfdb8SIngo Weinhold 	inline C *Detach()
69ce8cfdb8SIngo Weinhold 	{
70ce8cfdb8SIngo Weinhold 		C *object = fObject;
71ce8cfdb8SIngo Weinhold 		fObject = NULL;
72ce8cfdb8SIngo Weinhold 		return object;
73ce8cfdb8SIngo Weinhold 	}
74ce8cfdb8SIngo Weinhold 
75b97e1292SOliver Tappe 	inline C *operator->() const
76b97e1292SOliver Tappe 	{
77b97e1292SOliver Tappe 		return fObject;
78b97e1292SOliver Tappe 	}
79b97e1292SOliver Tappe 
8034cbfd39SIngo Weinhold protected:
81ce8cfdb8SIngo Weinhold 	C			*fObject;
82f277fb63SIngo Weinhold 	DeleteFunc	fDelete;
83ec43e4f4SX512 
84ec43e4f4SX512 private:
85ec43e4f4SX512 	AutoDeleter(const AutoDeleter&);
86ec43e4f4SX512 	AutoDeleter& operator=(const AutoDeleter&);
87ce8cfdb8SIngo Weinhold };
88ce8cfdb8SIngo Weinhold 
89ce8cfdb8SIngo Weinhold 
90ce8cfdb8SIngo Weinhold // ObjectDeleter
91ce8cfdb8SIngo Weinhold 
92ce8cfdb8SIngo Weinhold template<typename C>
93ce8cfdb8SIngo Weinhold struct ObjectDelete
94ce8cfdb8SIngo Weinhold {
95ce8cfdb8SIngo Weinhold 	inline void operator()(C *object)
96ce8cfdb8SIngo Weinhold 	{
97ce8cfdb8SIngo Weinhold 		delete object;
98ce8cfdb8SIngo Weinhold 	}
99ce8cfdb8SIngo Weinhold };
100ce8cfdb8SIngo Weinhold 
101ce8cfdb8SIngo Weinhold template<typename C>
102ce8cfdb8SIngo Weinhold struct ObjectDeleter : AutoDeleter<C, ObjectDelete<C> >
103ce8cfdb8SIngo Weinhold {
104ce8cfdb8SIngo Weinhold 	ObjectDeleter() : AutoDeleter<C, ObjectDelete<C> >() {}
105ce8cfdb8SIngo Weinhold 	ObjectDeleter(C *object) : AutoDeleter<C, ObjectDelete<C> >(object) {}
106ce8cfdb8SIngo Weinhold };
107ce8cfdb8SIngo Weinhold 
108ce8cfdb8SIngo Weinhold 
109ce8cfdb8SIngo Weinhold // ArrayDeleter
110ce8cfdb8SIngo Weinhold 
111ce8cfdb8SIngo Weinhold template<typename C>
112ce8cfdb8SIngo Weinhold struct ArrayDelete
113ce8cfdb8SIngo Weinhold {
114ce8cfdb8SIngo Weinhold 	inline void operator()(C *array)
115ce8cfdb8SIngo Weinhold 	{
116ce8cfdb8SIngo Weinhold 		delete[] array;
117ce8cfdb8SIngo Weinhold 	}
118ce8cfdb8SIngo Weinhold };
119ce8cfdb8SIngo Weinhold 
120ce8cfdb8SIngo Weinhold template<typename C>
121ce8cfdb8SIngo Weinhold struct ArrayDeleter : AutoDeleter<C, ArrayDelete<C> >
122ce8cfdb8SIngo Weinhold {
123ce8cfdb8SIngo Weinhold 	ArrayDeleter() : AutoDeleter<C, ArrayDelete<C> >() {}
124ce8cfdb8SIngo Weinhold 	ArrayDeleter(C *array) : AutoDeleter<C, ArrayDelete<C> >(array) {}
1258301c498SX512 
1268301c498SX512 	inline C& operator[](size_t index) const
1278301c498SX512 	{
1288301c498SX512 		return this->Get()[index];
1298301c498SX512 	}
130ce8cfdb8SIngo Weinhold };
131ce8cfdb8SIngo Weinhold 
132ce8cfdb8SIngo Weinhold 
133ce8cfdb8SIngo Weinhold // MemoryDeleter
134ce8cfdb8SIngo Weinhold 
135ce8cfdb8SIngo Weinhold struct MemoryDelete
136ce8cfdb8SIngo Weinhold {
137ce8cfdb8SIngo Weinhold 	inline void operator()(void *memory)
138ce8cfdb8SIngo Weinhold 	{
139ce8cfdb8SIngo Weinhold 		free(memory);
140ce8cfdb8SIngo Weinhold 	}
141ce8cfdb8SIngo Weinhold };
142ce8cfdb8SIngo Weinhold 
143ce8cfdb8SIngo Weinhold struct MemoryDeleter : AutoDeleter<void, MemoryDelete >
144ce8cfdb8SIngo Weinhold {
145ce8cfdb8SIngo Weinhold 	MemoryDeleter() : AutoDeleter<void, MemoryDelete >() {}
146ce8cfdb8SIngo Weinhold 	MemoryDeleter(void *memory) : AutoDeleter<void, MemoryDelete >(memory) {}
147ce8cfdb8SIngo Weinhold };
148ce8cfdb8SIngo Weinhold 
14934cbfd39SIngo Weinhold 
15034cbfd39SIngo Weinhold // CObjectDeleter
15134cbfd39SIngo Weinhold 
1527d775e79SX512 template<typename Type, typename DestructorReturnType,
1537d775e79SX512 	DestructorReturnType (*Destructor)(Type*)>
15434cbfd39SIngo Weinhold struct CObjectDelete
15534cbfd39SIngo Weinhold {
15634cbfd39SIngo Weinhold 	inline void operator()(Type *object)
15734cbfd39SIngo Weinhold 	{
1587d775e79SX512 		if (object != NULL)
1597d775e79SX512 			Destructor(object);
16034cbfd39SIngo Weinhold 	}
16134cbfd39SIngo Weinhold };
16234cbfd39SIngo Weinhold 
1637d775e79SX512 template<typename Type, typename DestructorReturnType,
1647d775e79SX512 	DestructorReturnType (*Destructor)(Type*)>
16534cbfd39SIngo Weinhold struct CObjectDeleter
1667d775e79SX512 	: AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType, Destructor> >
16734cbfd39SIngo Weinhold {
1687d775e79SX512 	typedef AutoDeleter<Type,
1697d775e79SX512 		CObjectDelete<Type, DestructorReturnType, Destructor> > Base;
17034cbfd39SIngo Weinhold 
1717d775e79SX512 	CObjectDeleter() : Base()
17234cbfd39SIngo Weinhold 	{
17334cbfd39SIngo Weinhold 	}
17434cbfd39SIngo Weinhold 
1757d775e79SX512 	CObjectDeleter(Type *object) : Base(object)
17634cbfd39SIngo Weinhold 	{
17734cbfd39SIngo Weinhold 	}
17834cbfd39SIngo Weinhold };
17934cbfd39SIngo Weinhold 
180e378ab1cSIngo Weinhold 
181e378ab1cSIngo Weinhold // MethodDeleter
182e378ab1cSIngo Weinhold 
183*aecba913SX512 template<typename Type, typename DestructorReturnType,
184*aecba913SX512 	DestructorReturnType (Type::*Destructor)()>
185e378ab1cSIngo Weinhold struct MethodDelete
186e378ab1cSIngo Weinhold {
187e378ab1cSIngo Weinhold 	inline void operator()(Type *object)
188e378ab1cSIngo Weinhold 	{
189*aecba913SX512 		if (object != NULL)
190*aecba913SX512 			(object->*Destructor)();
191e378ab1cSIngo Weinhold 	}
192e378ab1cSIngo Weinhold };
193e378ab1cSIngo Weinhold 
194e378ab1cSIngo Weinhold 
195*aecba913SX512 template<typename Type, typename DestructorReturnType,
196*aecba913SX512 	DestructorReturnType (Type::*Destructor)()>
197e378ab1cSIngo Weinhold struct MethodDeleter
198*aecba913SX512 	: AutoDeleter<Type, MethodDelete<Type, DestructorReturnType, Destructor> >
199e378ab1cSIngo Weinhold {
200*aecba913SX512 	typedef AutoDeleter<Type,
201*aecba913SX512 		MethodDelete<Type, DestructorReturnType, Destructor> > Base;
202e378ab1cSIngo Weinhold 
203*aecba913SX512 	MethodDeleter() : Base()
204e378ab1cSIngo Weinhold 	{
205e378ab1cSIngo Weinhold 	}
206e378ab1cSIngo Weinhold 
207*aecba913SX512 	MethodDeleter(Type *object) : Base(object)
208e378ab1cSIngo Weinhold 	{
209e378ab1cSIngo Weinhold 	}
210e378ab1cSIngo Weinhold };
211e378ab1cSIngo Weinhold 
212d91215d3SAxel Dörfler 
213cb7ce9a3SAxel Dörfler // FileDescriptorCloser
214d91215d3SAxel Dörfler 
215cb7ce9a3SAxel Dörfler struct FileDescriptorCloser {
2165b486787SIngo Weinhold 	inline FileDescriptorCloser()
2175b486787SIngo Weinhold 		:
2185b486787SIngo Weinhold 		fDescriptor(-1)
2195b486787SIngo Weinhold 	{
2205b486787SIngo Weinhold 	}
2215b486787SIngo Weinhold 
222cb7ce9a3SAxel Dörfler 	inline FileDescriptorCloser(int descriptor)
223d91215d3SAxel Dörfler 		:
224d91215d3SAxel Dörfler 		fDescriptor(descriptor)
225d91215d3SAxel Dörfler 	{
226d91215d3SAxel Dörfler 	}
227d91215d3SAxel Dörfler 
228cb7ce9a3SAxel Dörfler 	inline ~FileDescriptorCloser()
229d91215d3SAxel Dörfler 	{
2305b486787SIngo Weinhold 		SetTo(-1);
231d91215d3SAxel Dörfler 	}
232d91215d3SAxel Dörfler 
2335b486787SIngo Weinhold 	inline void SetTo(int descriptor)
234d91215d3SAxel Dörfler 	{
2355b486787SIngo Weinhold 		if (fDescriptor >= 0)
2365b486787SIngo Weinhold 			close(fDescriptor);
2375b486787SIngo Weinhold 
2385b486787SIngo Weinhold 		fDescriptor = descriptor;
2395b486787SIngo Weinhold 	}
2405b486787SIngo Weinhold 
2415b486787SIngo Weinhold 	inline void Unset()
2425b486787SIngo Weinhold 	{
2435b486787SIngo Weinhold 		SetTo(-1);
2445b486787SIngo Weinhold 	}
2455b486787SIngo Weinhold 
246b29db8ebSX512 	inline int Get()
247b29db8ebSX512 	{
248b29db8ebSX512 		return fDescriptor;
249b29db8ebSX512 	}
250b29db8ebSX512 
2515b486787SIngo Weinhold 	inline int Detach()
2525b486787SIngo Weinhold 	{
2535b486787SIngo Weinhold 		int descriptor = fDescriptor;
254d91215d3SAxel Dörfler 		fDescriptor = -1;
2555b486787SIngo Weinhold 		return descriptor;
256d91215d3SAxel Dörfler 	}
257d91215d3SAxel Dörfler 
258d91215d3SAxel Dörfler private:
259d91215d3SAxel Dörfler 	int	fDescriptor;
260d91215d3SAxel Dörfler };
261d91215d3SAxel Dörfler 
262d91215d3SAxel Dörfler 
263ce8cfdb8SIngo Weinhold }	// namespace BPrivate
264ce8cfdb8SIngo Weinhold 
265d91215d3SAxel Dörfler 
26618f5cd17SIngo Weinhold using ::BPrivate::ObjectDeleter;
26718f5cd17SIngo Weinhold using ::BPrivate::ArrayDeleter;
26818f5cd17SIngo Weinhold using ::BPrivate::MemoryDeleter;
26918f5cd17SIngo Weinhold using ::BPrivate::CObjectDeleter;
27018f5cd17SIngo Weinhold using ::BPrivate::MethodDeleter;
27118f5cd17SIngo Weinhold using ::BPrivate::FileDescriptorCloser;
272d91215d3SAxel Dörfler 
273ce8cfdb8SIngo Weinhold 
274ce8cfdb8SIngo Weinhold #endif	// _AUTO_DELETER_H
275