A game about forced loneliness, made by TACStudios
1#pragma once
2
3namespace win
4{
5 template<typename T>
6 class ComPtr;
7
8 template<typename T>
9 class ComPtrRef
10 {
11 private:
12 ComPtr<T>& m_ComPtr;
13
14 ComPtrRef(ComPtr<T>& comPtr) :
15 m_ComPtr(comPtr)
16 {
17 }
18
19 friend class ComPtr<T>;
20
21 public:
22 inline operator T**()
23 {
24 return m_ComPtr.ReleaseAndGetAddressOf();
25 }
26
27 inline operator void**()
28 {
29 return reinterpret_cast<void**>(m_ComPtr.ReleaseAndGetAddressOf());
30 }
31
32 inline T* operator*() throw ()
33 {
34 return m_ComPtr;
35 }
36
37 };
38
39 template<typename T>
40 class ComPtr
41 {
42 private:
43 T *ptr;
44
45 public:
46 inline ComPtr(void) : ptr(NULL) {}
47 inline ~ComPtr(void) { this->Free(); }
48
49 ComPtr(T *ptr)
50 {
51 if (NULL != (this->ptr = ptr))
52 {
53 this->ptr->AddRef();
54 }
55 }
56
57 ComPtr(const ComPtr &ptr)
58 {
59 if (NULL != (this->ptr = ptr.ptr))
60 {
61 this->ptr->AddRef();
62 }
63 }
64
65 inline bool operator!() const
66 {
67 return (NULL == this->ptr);
68 }
69
70 inline operator T*() const { return this->ptr; }
71
72 inline T *operator->() const
73 {
74 //_assert(NULL != this->ptr);
75 return this->ptr;
76 }
77
78 inline T &operator*()
79 {
80 //_assert(NULL != this->ptr);
81 return *this->ptr;
82 }
83
84 inline ComPtrRef<T> operator&()
85 {
86 return ComPtrRef<T>(*this);
87 }
88
89 const ComPtr &operator=(T *ptr)
90 {
91 if (this->ptr != ptr)
92 {
93 this->Free();
94
95 if (NULL != (this->ptr = ptr))
96 {
97 this->ptr->AddRef();
98 }
99 }
100
101 return *this;
102 }
103
104 const ComPtr &operator=(const ComPtr &ptr)
105 {
106 if (this->ptr != ptr.ptr)
107 {
108 this->Free();
109
110 if (NULL != (this->ptr = ptr.ptr))
111 {
112 this->ptr->AddRef();
113 }
114 }
115
116 return *this;
117 }
118
119 void Free(void)
120 {
121 if (NULL != this->ptr)
122 {
123 this->ptr->Release();
124 this->ptr = NULL;
125 }
126 }
127
128 inline T** ReleaseAndGetAddressOf()
129 {
130 Free();
131 return &ptr;
132 }
133
134 template<typename U>
135 inline HRESULT As(ComPtrRef<U> p) const throw ()
136 {
137 return ptr->QueryInterface(__uuidof(U), p);
138 }
139
140 inline bool operator==(std::nullptr_t) const
141 {
142 return this->ptr == nullptr;
143 }
144
145 template<typename U>
146 inline bool operator==(U* other)
147 {
148 if (ptr == nullptr || other == nullptr)
149 return ptr == other;
150
151 ComPtr<IUnknown> meUnknown;
152 ComPtr<IUnknown> otherUnknown;
153
154 if (FAILED(this->ptr->QueryInterface(__uuidof(IUnknown), &meUnknown)))
155 return false;
156
157 if (FAILED(other->QueryInterface(__uuidof(IUnknown), &otherUnknown)))
158 return false;
159
160 return static_cast<IUnknown*>(meUnknown) == static_cast<IUnknown*>(otherUnknown);
161 }
162
163 template<typename U>
164 inline bool operator==(ComPtr<U>& other)
165 {
166 return *this == static_cast<U*>(other);
167 }
168
169 inline bool operator!=(std::nullptr_t) const
170 {
171 return this->ptr != nullptr;
172 }
173
174 template<typename U>
175 inline bool operator!=(U* other)
176 {
177 return !(*this == other);
178 }
179
180 template<typename U>
181 inline bool operator!=(ComPtr<U>& other)
182 {
183 return *this != static_cast<U*>(other);
184 }
185 };
186}