acme
Foundational cross-platform layer of the ca2 framework
Loading...
Searching...
No Matches
comptr.h
1#pragma once
2
3
4#include "acme/_operating_system.h"
5
6
7template <class T> void SafeRelease(T ** ppT)
8{
9 if (*ppT)
10 {
11 (*ppT)->Release();
12 *ppT = NULL;
13 }
14}
15
16template < typename TYPE >
17class comptr
18{
19public:
20
21
22 using BASE_TYPE = TYPE;
23
24
25 TYPE * m_p;
26
27 comptr()
28 {
29 m_p = nullptr;
30
31 }
32
33
34 explicit comptr(std::nullptr_t)
35 {
36
37 m_p = nullptr;
38
39 }
40
41 comptr(const comptr & ptr)
42 {
43 if (ptr.m_p != nullptr)
44 {
45 ptr.m_p->AddRef();
46 }
47 m_p = ptr.m_p;
48
49 }
50
51 comptr(::transfer_t , TYPE * p)
52 {
53 m_p = p;
54
55 }
56
57 comptr(TYPE * p)
58 {
59 if (p != nullptr)
60 {
61 p->AddRef();
62 }
63 m_p = p;
64 }
65
66
67
68
69
70
71 ~comptr()
72 {
73
74 release();
75
76 }
77
78 HRESULT CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter = nullptr, ::u32 dwClsContext = CLSCTX_ALL)
79 {
80
81 release();
82
83 return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(TYPE), (void **)&m_p);
84
85 }
86
87 template < class IFACE >
88 HRESULT as(comptr < IFACE > & iface) const
89 {
90
91 if (m_p == nullptr)
92 {
93
94 return E_FAIL;
95
96 }
97
98 return m_p->QueryInterface(__uuidof(IFACE), (void **) & iface);
99
100 }
101
102 template < class IFACE >
103 comptr < IFACE > as() const
104 {
105
106 comptr < IFACE > pointer;
107
108 this->as(pointer);
109
110 return pointer;
111
112 }
113
114
115
116 TYPE * operator ->()
117 {
118
119 return (TYPE *)m_p;
120
121 }
122
123 TYPE * operator ->() const
124 {
125
126 return (TYPE *)m_p;
127
128 }
129
130 operator bool() const
131 {
132
133 return ::is_set(m_p);
134
135 }
136
137 bool operator !() const
138 {
139
140 return !this->operator bool();
141
142 }
143
144 TYPE * detach()
145 {
146
147 TYPE * p = operator ->();
148
149 m_p = nullptr;
150
151 return p;
152
153 }
154
155 // Returns a pointer to this pointer suitable for IID_PPV_ARGS.
156 TYPE*const* pp() const
157 {
158 return &m_p;
159 }
160
161
162 TYPE ** operator & ()
163 {
164 release();
165 return &(TYPE * &)m_p;
166
167 }
168
169
170 operator TYPE * ()
171 {
172
173 return (TYPE *)m_p;
174
175 }
176
177 comptr & operator = (TYPE * p)
178 {
179
180 if (m_p != p)
181 {
182
183 if (p != nullptr)
184 {
185
186 p->AddRef();
187
188
189 }
190
191 if (m_p != nullptr)
192 {
193
194 m_p->Release();
195
196 }
197
198 m_p = p;
199
200 }
201
202 return *this;
203
204 }
205
206
207 comptr & operator = (const comptr & ptr)
208 {
209
210 if (&ptr != this)
211 {
212
213 if (ptr.m_p != nullptr)
214 {
215
216 ptr.m_p->AddRef();
217
218
219 }
220
221 if (m_p != nullptr)
222 {
223
224 m_p->Release();
225
226 }
227
228 m_p = ptr.m_p;
229
230 }
231
232 return *this;
233
234 }
235
236
237 ULONG release()
238 {
239
240 ULONG ul = 0;
241
242 try
243 {
244
245 if (m_p != nullptr)
246 {
247
248 ul = m_p->Release();
249
250 }
251
252 }
253 catch (...)
254 {
255
256
257 }
258
259 m_p = nullptr;
260
261
262 return ul;
263
264 }
265
266
267 bool is_null() const
268 {
269
270 return m_p == nullptr;
271
272 }
273
274
275 bool is_set() const
276 {
277
278 return !is_null();
279
280 }
281
282
283};
284
285
286#define __interface_of(comptr) __uuidof(decltype(*comptr.m_p)), (void **) &comptr.m_p
287#define __unknown_of(comptr) __uuidof(decltype(*comptr.m_p)), reinterpret_cast < IUnknown ** > (&comptr.m_p)
288
289
290template < typename TYPE >
291inline bool is_null(const comptr < TYPE > & p)
292{
293
294 return ::is_null(p.m_p);
295
296}
297
Definition ptr.h:18
Definition _structures.h:6