1 | /**
|
---|
2 | * This file has no copyright assigned and is placed in the Public Domain.
|
---|
3 | * This file is part of the mingw-w64 runtime package.
|
---|
4 | * No warranty is given; refer to the file DISCLAIMER.PD within this package.
|
---|
5 | */
|
---|
6 |
|
---|
7 | #ifndef _WRL_CLIENT_H_
|
---|
8 | #define _WRL_CLIENT_H_
|
---|
9 |
|
---|
10 | #include <stddef.h>
|
---|
11 | #include <unknwn.h>
|
---|
12 | /* #include <weakreference.h> */
|
---|
13 | #include <roapi.h>
|
---|
14 |
|
---|
15 | /* #include <wrl/def.h> */
|
---|
16 | #include <wrl/internal.h>
|
---|
17 |
|
---|
18 | namespace Microsoft {
|
---|
19 | namespace WRL {
|
---|
20 | namespace Details {
|
---|
21 | template <typename T> class ComPtrRefBase {
|
---|
22 | protected:
|
---|
23 | T* ptr_;
|
---|
24 |
|
---|
25 | public:
|
---|
26 | typedef typename T::InterfaceType InterfaceType;
|
---|
27 |
|
---|
28 | #ifndef __WRL_CLASSIC_COM__
|
---|
29 | operator IInspectable**() const throw() {
|
---|
30 | static_assert(__is_base_of(IInspectable, InterfaceType), "Invalid cast");
|
---|
31 | return reinterpret_cast<IInspectable**>(ptr_->ReleaseAndGetAddressOf());
|
---|
32 | }
|
---|
33 | #endif
|
---|
34 |
|
---|
35 | operator IUnknown**() const throw() {
|
---|
36 | static_assert(__is_base_of(IUnknown, InterfaceType), "Invalid cast");
|
---|
37 | return reinterpret_cast<IUnknown**>(ptr_->ReleaseAndGetAddressOf());
|
---|
38 | }
|
---|
39 | };
|
---|
40 |
|
---|
41 | template <typename T> class ComPtrRef : public Details::ComPtrRefBase<T> {
|
---|
42 | public:
|
---|
43 | ComPtrRef(T *ptr) throw() {
|
---|
44 | ComPtrRefBase<T>::ptr_ = ptr;
|
---|
45 | }
|
---|
46 |
|
---|
47 | operator void**() const throw() {
|
---|
48 | return reinterpret_cast<void**>(ComPtrRefBase<T>::ptr_->ReleaseAndGetAddressOf());
|
---|
49 | }
|
---|
50 |
|
---|
51 | operator T*() throw() {
|
---|
52 | *ComPtrRefBase<T>::ptr_ = nullptr;
|
---|
53 | return ComPtrRefBase<T>::ptr_;
|
---|
54 | }
|
---|
55 |
|
---|
56 | operator typename ComPtrRefBase<T>::InterfaceType**() throw() {
|
---|
57 | return ComPtrRefBase<T>::ptr_->ReleaseAndGetAddressOf();
|
---|
58 | }
|
---|
59 |
|
---|
60 | typename ComPtrRefBase<T>::InterfaceType *operator*() throw() {
|
---|
61 | return ComPtrRefBase<T>::ptr_->Get();
|
---|
62 | }
|
---|
63 |
|
---|
64 | typename ComPtrRefBase<T>::InterfaceType *const *GetAddressOf() const throw() {
|
---|
65 | return ComPtrRefBase<T>::ptr_->GetAddressOf();
|
---|
66 | }
|
---|
67 |
|
---|
68 | typename ComPtrRefBase<T>::InterfaceType **ReleaseAndGetAddressOf() throw() {
|
---|
69 | return ComPtrRefBase<T>::ptr_->ReleaseAndGetAddressOf();
|
---|
70 | }
|
---|
71 | };
|
---|
72 |
|
---|
73 | }
|
---|
74 |
|
---|
75 | template<typename T> class ComPtr {
|
---|
76 | public:
|
---|
77 | typedef T InterfaceType;
|
---|
78 |
|
---|
79 | ComPtr() throw() : ptr_(nullptr) {}
|
---|
80 | ComPtr(decltype(nullptr)) throw() : ptr_(nullptr) {}
|
---|
81 |
|
---|
82 | template<class U> ComPtr(U *other) throw() : ptr_(other) {
|
---|
83 | InternalAddRef();
|
---|
84 | }
|
---|
85 |
|
---|
86 | ComPtr(const ComPtr &other) throw() : ptr_(other.ptr_) {
|
---|
87 | InternalAddRef();
|
---|
88 | }
|
---|
89 |
|
---|
90 | template<class U>
|
---|
91 | ComPtr(const ComPtr<U> &other) throw() : ptr_(other.Get()) {
|
---|
92 | InternalAddRef();
|
---|
93 | }
|
---|
94 |
|
---|
95 | ComPtr(ComPtr &&other) throw() : ptr_(nullptr) {
|
---|
96 | if(this != reinterpret_cast<ComPtr*>(&reinterpret_cast<unsigned char&>(other)))
|
---|
97 | Swap(other);
|
---|
98 | }
|
---|
99 |
|
---|
100 | template<class U>
|
---|
101 | ComPtr(ComPtr<U>&& other) throw() : ptr_(other.Detach()) {}
|
---|
102 |
|
---|
103 | ~ComPtr() throw() {
|
---|
104 | InternalRelease();
|
---|
105 | }
|
---|
106 |
|
---|
107 | ComPtr &operator=(decltype(nullptr)) throw() {
|
---|
108 | InternalRelease();
|
---|
109 | return *this;
|
---|
110 | }
|
---|
111 |
|
---|
112 | ComPtr &operator=(InterfaceType *other) throw() {
|
---|
113 | if (ptr_ != other) {
|
---|
114 | InternalRelease();
|
---|
115 | ptr_ = other;
|
---|
116 | InternalAddRef();
|
---|
117 | }
|
---|
118 | return *this;
|
---|
119 | }
|
---|
120 |
|
---|
121 | template<typename U>
|
---|
122 | ComPtr &operator=(U *other) throw() {
|
---|
123 | if (ptr_ != other) {
|
---|
124 | InternalRelease();
|
---|
125 | ptr_ = other;
|
---|
126 | InternalAddRef();
|
---|
127 | }
|
---|
128 | return *this;
|
---|
129 | }
|
---|
130 |
|
---|
131 | ComPtr& operator=(const ComPtr &other) throw() {
|
---|
132 | if (ptr_ != other.ptr_)
|
---|
133 | ComPtr(other).Swap(*this);
|
---|
134 | return *this;
|
---|
135 | }
|
---|
136 |
|
---|
137 | template<class U>
|
---|
138 | ComPtr &operator=(const ComPtr<U> &other) throw() {
|
---|
139 | ComPtr(other).Swap(*this);
|
---|
140 | return *this;
|
---|
141 | }
|
---|
142 |
|
---|
143 | ComPtr& operator=(ComPtr &&other) throw() {
|
---|
144 | ComPtr(other).Swap(*this);
|
---|
145 | return *this;
|
---|
146 | }
|
---|
147 |
|
---|
148 | template<class U>
|
---|
149 | ComPtr& operator=(ComPtr<U> &&other) throw() {
|
---|
150 | ComPtr(other).Swap(*this);
|
---|
151 | return *this;
|
---|
152 | }
|
---|
153 |
|
---|
154 | void Swap(ComPtr &&r) throw() {
|
---|
155 | InterfaceType *tmp = ptr_;
|
---|
156 | ptr_ = r.ptr_;
|
---|
157 | r.ptr_ = tmp;
|
---|
158 | }
|
---|
159 |
|
---|
160 | void Swap(ComPtr &r) throw() {
|
---|
161 | InterfaceType *tmp = ptr_;
|
---|
162 | ptr_ = r.ptr_;
|
---|
163 | r.ptr_ = tmp;
|
---|
164 | }
|
---|
165 |
|
---|
166 | operator Details::BoolType() const throw() {
|
---|
167 | return Get() != nullptr ? &Details::BoolStruct::Member : nullptr;
|
---|
168 | }
|
---|
169 |
|
---|
170 | InterfaceType *Get() const throw() {
|
---|
171 | return ptr_;
|
---|
172 | }
|
---|
173 |
|
---|
174 | InterfaceType *operator->() const throw() {
|
---|
175 | return ptr_;
|
---|
176 | }
|
---|
177 |
|
---|
178 | Details::ComPtrRef<ComPtr<T>> operator&() throw() {
|
---|
179 | return Details::ComPtrRef<ComPtr<T>>(this);
|
---|
180 | }
|
---|
181 |
|
---|
182 | const Details::ComPtrRef<const ComPtr<T>> operator&() const throw() {
|
---|
183 | return Details::ComPtrRef<const ComPtr<T>>(this);
|
---|
184 | }
|
---|
185 |
|
---|
186 | InterfaceType *const *GetAddressOf() const throw() {
|
---|
187 | return &ptr_;
|
---|
188 | }
|
---|
189 |
|
---|
190 | InterfaceType **GetAddressOf() throw() {
|
---|
191 | return &ptr_;
|
---|
192 | }
|
---|
193 |
|
---|
194 | InterfaceType **ReleaseAndGetAddressOf() throw() {
|
---|
195 | InternalRelease();
|
---|
196 | return &ptr_;
|
---|
197 | }
|
---|
198 |
|
---|
199 | InterfaceType *Detach() throw() {
|
---|
200 | T* ptr = ptr_;
|
---|
201 | ptr_ = nullptr;
|
---|
202 | return ptr;
|
---|
203 | }
|
---|
204 |
|
---|
205 | void Attach(InterfaceType *other) throw() {
|
---|
206 | if (ptr_ != other) {
|
---|
207 | InternalRelease();
|
---|
208 | ptr_ = other;
|
---|
209 | InternalAddRef();
|
---|
210 | }
|
---|
211 | }
|
---|
212 |
|
---|
213 | unsigned long Reset() {
|
---|
214 | return InternalRelease();
|
---|
215 | }
|
---|
216 |
|
---|
217 | HRESULT CopyTo(InterfaceType **ptr) const throw() {
|
---|
218 | InternalAddRef();
|
---|
219 | *ptr = ptr_;
|
---|
220 | return S_OK;
|
---|
221 | }
|
---|
222 |
|
---|
223 | HRESULT CopyTo(REFIID riid, void **ptr) const throw() {
|
---|
224 | return ptr_->QueryInterface(riid, ptr);
|
---|
225 | }
|
---|
226 |
|
---|
227 | template<typename U>
|
---|
228 | HRESULT CopyTo(U **ptr) const throw() {
|
---|
229 | return ptr_->QueryInterface(__uuidof(U), reinterpret_cast<void**>(ptr));
|
---|
230 | }
|
---|
231 |
|
---|
232 | template<typename U>
|
---|
233 | HRESULT As(Details::ComPtrRef<ComPtr<U>> p) const throw() {
|
---|
234 | return ptr_->QueryInterface(__uuidof(U), p);
|
---|
235 | }
|
---|
236 |
|
---|
237 | template<typename U>
|
---|
238 | HRESULT As(ComPtr<U> *p) const throw() {
|
---|
239 | return ptr_->QueryInterface(__uuidof(U), reinterpret_cast<void**>(p->ReleaseAndGetAddressOf()));
|
---|
240 | }
|
---|
241 |
|
---|
242 | HRESULT AsIID(REFIID riid, ComPtr<IUnknown> *p) const throw() {
|
---|
243 | return ptr_->QueryInterface(riid, reinterpret_cast<void**>(p->ReleaseAndGetAddressOf()));
|
---|
244 | }
|
---|
245 |
|
---|
246 | /*
|
---|
247 | HRESULT AsWeak(WeakRef *pWeakRef) const throw() {
|
---|
248 | return ::Microsoft::WRL::AsWeak(ptr_, pWeakRef);
|
---|
249 | }
|
---|
250 | */
|
---|
251 | protected:
|
---|
252 | InterfaceType *ptr_;
|
---|
253 |
|
---|
254 | void InternalAddRef() const throw() {
|
---|
255 | if(ptr_)
|
---|
256 | ptr_->AddRef();
|
---|
257 | }
|
---|
258 |
|
---|
259 | unsigned long InternalRelease() throw() {
|
---|
260 | InterfaceType *tmp = ptr_;
|
---|
261 | if(!tmp)
|
---|
262 | return 0;
|
---|
263 | ptr_ = nullptr;
|
---|
264 | return tmp->Release();
|
---|
265 | }
|
---|
266 | };
|
---|
267 | }
|
---|
268 | }
|
---|
269 |
|
---|
270 | template<typename T>
|
---|
271 | void **IID_PPV_ARGS_Helper(::Microsoft::WRL::Details::ComPtrRef<T> pp) throw() {
|
---|
272 | static_assert(__is_base_of(IUnknown, typename T::InterfaceType), "Expected COM interface");
|
---|
273 | return pp;
|
---|
274 | }
|
---|
275 |
|
---|
276 | namespace Windows {
|
---|
277 | namespace Foundation {
|
---|
278 | template<typename T>
|
---|
279 | inline HRESULT ActivateInstance(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> instance) throw() {
|
---|
280 | return ActivateInstance(classid, instance.ReleaseAndGetAddressOf());
|
---|
281 | }
|
---|
282 |
|
---|
283 | template<typename T>
|
---|
284 | inline HRESULT GetActivationFactory(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> factory) throw() {
|
---|
285 | return RoGetActivationFactory(classid, IID_INS_ARGS(factory.ReleaseAndGetAddressOf()));
|
---|
286 | }
|
---|
287 | }
|
---|
288 | }
|
---|
289 |
|
---|
290 | namespace ABI {
|
---|
291 | namespace Windows {
|
---|
292 | namespace Foundation {
|
---|
293 | template<typename T>
|
---|
294 | inline HRESULT ActivateInstance(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> instance) throw() {
|
---|
295 | return ActivateInstance(classid, instance.ReleaseAndGetAddressOf());
|
---|
296 | }
|
---|
297 |
|
---|
298 | template<typename T>
|
---|
299 | inline HRESULT GetActivationFactory(HSTRING classid, ::Microsoft::WRL::Details::ComPtrRef<T> factory) throw() {
|
---|
300 | return RoGetActivationFactory(classid, IID_INS_ARGS(factory.ReleaseAndGetAddressOf()));
|
---|
301 | }
|
---|
302 | }
|
---|
303 | }
|
---|
304 | }
|
---|
305 |
|
---|
306 | #endif
|
---|