1/*
2 * Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef KERNEL_UTIL_FIXED_WIDTH_POINTER_H
6#define KERNEL_UTIL_FIXED_WIDTH_POINTER_H
7
8
9#include <SupportDefs.h>
10
11
12/*!
13	\class FixedWidthPointer
14	\brief Pointer class with fixed size (64-bit) storage.
15
16	This class is a pointer-like class that uses a fixed size 64-bit storage.
17	This is used to make kernel_args compatible (i.e. the same size) for both
18	32-bit and 64-bit kernels.
19*/
20template<typename Type>
21class FixedWidthPointer {
22public:
23	Type * Pointer() const
24	{
25		return (Type*)(addr_t)fValue;
26	}
27
28	operator Type*() const
29	{
30		return Pointer();
31	}
32
33	Type& operator*() const
34	{
35		return *Pointer();
36	}
37
38	Type* operator->() const
39	{
40		return Pointer();
41	}
42
43	Type& operator[](size_t i) const
44	{
45		return Pointer()[i];
46	}
47
48	FixedWidthPointer& operator=(const FixedWidthPointer& p)
49	{
50		fValue = p.fValue;
51		return *this;
52	}
53
54	FixedWidthPointer& operator=(Type* p)
55	{
56		fValue = (addr_t)p;
57		return *this;
58	}
59
60	/*!
61		Get the 64-bit pointer value.
62		\return Pointer address.
63	*/
64	uint64 Get() const
65	{
66		return fValue;
67	}
68
69	/*!
70		Set the 64-bit pointer value.
71		\param addr New address for the pointer.
72	*/
73	void SetTo(uint64 addr)
74	{
75		fValue = addr;
76	}
77
78private:
79	uint64 fValue;
80} _PACKED;
81
82
83// Specialization for void pointers, can be converted to another pointer type.
84template<>
85class FixedWidthPointer<void> {
86public:
87	void * Pointer() const
88	{
89		return (void*)(addr_t)fValue;
90	}
91
92	operator void*() const
93	{
94		return Pointer();
95	}
96
97	FixedWidthPointer& operator=(const FixedWidthPointer& p)
98	{
99		fValue = p.fValue;
100		return *this;
101	}
102
103	FixedWidthPointer& operator=(void* p)
104	{
105		fValue = (addr_t)p;
106		return *this;
107	}
108
109	uint64 Get() const
110	{
111		return fValue;
112	}
113
114	void SetTo(uint64 addr)
115	{
116		fValue = addr;
117	}
118
119private:
120	uint64 fValue;
121} _PACKED;
122
123
124template<typename Type>
125inline bool
126operator==(const FixedWidthPointer<Type>& a, const Type* b)
127{
128	return a.Get() == (addr_t)b;
129}
130
131
132template<typename Type>
133inline bool
134operator!=(const FixedWidthPointer<Type>& a, const Type* b)
135{
136	return a.Get() != (addr_t)b;
137}
138
139
140template<typename Type>
141inline bool
142operator==(const FixedWidthPointer<Type>& a, Type* b)
143{
144	return a.Get() == (addr_t)b;
145}
146
147
148template<typename Type>
149inline bool
150operator!=(const FixedWidthPointer<Type>& a, Type* b)
151{
152	return a.Get() != (addr_t)b;
153}
154
155
156#endif	/* KERNEL_UTIL_FIXED_WIDTH_POINTER_H */
157