1// Referencable.h
2
3#ifndef USERLAND_FS_REFERENCABLE_H
4#define USERLAND_FS_REFERENCABLE_H
5
6#include <SupportDefs.h>
7
8#include "ObjectTracker.h"
9
10namespace UserlandFSUtil {
11
12// Referencable
13class Referencable ONLY_OBJECT_TRACKABLE_BASE_CLASS {
14public:
15								Referencable(
16									bool deleteWhenUnreferenced = false);
17	virtual						~Referencable();
18
19			void				AddReference();
20			bool				RemoveReference();	// returns true after last
21
22			int32				CountReferences() const;
23
24protected:
25			vint32				fReferenceCount;
26			bool				fDeleteWhenUnreferenced;
27};
28
29// Reference
30template<typename Type>
31class Reference {
32public:
33	Reference()
34		: fObject(NULL)
35	{
36	}
37
38	Reference(Type* object, bool alreadyHasReference = false)
39		: fObject(NULL)
40	{
41		SetTo(object, alreadyHasReference);
42	}
43
44	Reference(const Reference<Type>& other)
45		: fObject(NULL)
46	{
47		SetTo(other.fObject);
48	}
49
50	~Reference()
51	{
52		Unset();
53	}
54
55	void SetTo(Type* object, bool alreadyHasReference = false)
56	{
57		Unset();
58		fObject = object;
59		if (fObject && !alreadyHasReference)
60			fObject->AddReference();
61	}
62
63	void Unset()
64	{
65		if (fObject) {
66			fObject->RemoveReference();
67			fObject = NULL;
68		}
69	}
70
71	Type* Get() const
72	{
73		return fObject;
74	}
75
76	Type* Detach()
77	{
78		Type* object = fObject;
79		fObject = NULL;
80		return object;
81	}
82
83	Type& operator*() const
84	{
85		return *fObject;
86	}
87
88	Type* operator->() const
89	{
90		return fObject;
91	}
92
93	Reference& operator=(const Reference<Type>& other)
94	{
95		SetTo(other.fObject);
96		return *this;
97	}
98
99	bool operator==(const Reference<Type>& other) const
100	{
101		return (fObject == other.fObject);
102	}
103
104	bool operator!=(const Reference<Type>& other) const
105	{
106		return (fObject != other.fObject);
107	}
108
109private:
110	Type*	fObject;
111};
112
113}	// namespace UserlandFSUtil
114
115using UserlandFSUtil::Referencable;
116using UserlandFSUtil::Reference;
117
118#endif	// USERLAND_FS_REFERENCABLE_H
119