xref: /haiku/headers/os/support/Referenceable.h (revision 0754c319592cd8a523959d85fb06ab23c64a98a6)
1 /*
2  * Copyright 2004-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _REFERENCEABLE_H
6 #define _REFERENCEABLE_H
7 
8 
9 #include <SupportDefs.h>
10 
11 
12 // #pragma mark - BReferenceable
13 
14 
15 class BReferenceable {
16 public:
17 								BReferenceable();
18 	virtual						~BReferenceable();
19 
20 								// acquire and release return
21 								// the previous ref count
22 			int32				AcquireReference();
23 			int32				ReleaseReference();
24 
25 			int32				CountReferences() const
26 									{ return fReferenceCount; }
27 
28 protected:
29 	virtual	void				FirstReferenceAcquired();
30 	virtual	void				LastReferenceReleased();
31 
32 protected:
33 			int32				fReferenceCount;
34 };
35 
36 
37 // #pragma mark - BReference
38 
39 
40 template<typename Type = BReferenceable>
41 class BReference {
42 public:
43 	BReference()
44 		:
45 		fObject(NULL)
46 	{
47 	}
48 
49 	BReference(Type* object, bool alreadyHasReference = false)
50 		:
51 		fObject(NULL)
52 	{
53 		SetTo(object, alreadyHasReference);
54 	}
55 
56 	BReference(const BReference<Type>& other)
57 		:
58 		fObject(NULL)
59 	{
60 		SetTo(other.fObject);
61 	}
62 
63 
64 	template<typename OtherType>
65 	BReference(const BReference<OtherType>& other)
66 		:
67 		fObject(NULL)
68 	{
69 		SetTo(other.Get());
70 	}
71 
72 	~BReference()
73 	{
74 		Unset();
75 	}
76 
77 	void SetTo(Type* object, bool alreadyHasReference = false)
78 	{
79 		if (object != NULL && !alreadyHasReference)
80 			object->AcquireReference();
81 
82 		Unset();
83 
84 		fObject = object;
85 	}
86 
87 	void Unset()
88 	{
89 		if (fObject) {
90 			fObject->ReleaseReference();
91 			fObject = NULL;
92 		}
93 	}
94 
95 	Type* Get() const
96 	{
97 		return fObject;
98 	}
99 
100 	Type* Detach()
101 	{
102 		Type* object = fObject;
103 		fObject = NULL;
104 		return object;
105 	}
106 
107 	Type& operator*() const
108 	{
109 		return *fObject;
110 	}
111 
112 	Type* operator->() const
113 	{
114 		return fObject;
115 	}
116 
117 	operator Type*() const
118 	{
119 		return fObject;
120 	}
121 
122 	BReference& operator=(const BReference<Type>& other)
123 	{
124 		SetTo(other.fObject);
125 		return *this;
126 	}
127 
128 	BReference& operator=(Type* other)
129 	{
130 		SetTo(other);
131 		return *this;
132 	}
133 
134 	template<typename OtherType>
135 	BReference& operator=(const BReference<OtherType>& other)
136 	{
137 		SetTo(other.Get());
138 		return *this;
139 	}
140 
141 	bool operator==(const BReference<Type>& other) const
142 	{
143 		return fObject == other.fObject;
144 	}
145 
146 	bool operator==(const Type* other) const
147 	{
148 		return fObject == other;
149 	}
150 
151 	bool operator!=(const BReference<Type>& other) const
152 	{
153 		return fObject != other.fObject;
154 	}
155 
156 	bool operator!=(const Type* other) const
157 	{
158 		return fObject != other;
159 	}
160 
161 private:
162 	Type*	fObject;
163 };
164 
165 
166 #endif	// _REFERENCEABLE_H
167