OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_WIN_SCOPED_COMPTR_H_ | 5 #ifndef BASE_WIN_SCOPED_COMPTR_H_ |
6 #define BASE_WIN_SCOPED_COMPTR_H_ | 6 #define BASE_WIN_SCOPED_COMPTR_H_ |
7 | 7 |
8 #include <objbase.h> | 8 #include <objbase.h> |
9 #include <unknwn.h> | 9 #include <unknwn.h> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 | 12 |
13 namespace base { | 13 namespace base { |
14 namespace win { | 14 namespace win { |
15 | 15 |
16 namespace details { | |
17 | |
18 template <typename T> | |
19 class ScopedComPtrRef; | |
20 | |
21 } // details | |
22 | |
16 // DEPRECATED: Use Microsoft::WRL::ComPtr instead. | 23 // DEPRECATED: Use Microsoft::WRL::ComPtr instead. |
17 // A fairly minimalistic smart class for COM interface pointers. | 24 // A fairly minimalistic smart class for COM interface pointers. |
18 template <class Interface, const IID* interface_id = &__uuidof(Interface)> | 25 template <class Interface, const IID* interface_id = &__uuidof(Interface)> |
19 class ScopedComPtr { | 26 class ScopedComPtr { |
20 public: | 27 public: |
28 using InterfaceType = Interface; | |
29 | |
21 // Utility template to prevent users of ScopedComPtr from calling AddRef | 30 // Utility template to prevent users of ScopedComPtr from calling AddRef |
22 // and/or Release() without going through the ScopedComPtr class. | 31 // and/or Release() without going through the ScopedComPtr class. |
23 class BlockIUnknownMethods : public Interface { | 32 class BlockIUnknownMethods : public Interface { |
24 private: | 33 private: |
25 STDMETHOD(QueryInterface)(REFIID iid, void** object) = 0; | 34 STDMETHOD(QueryInterface)(REFIID iid, void** object) = 0; |
26 STDMETHOD_(ULONG, AddRef)() = 0; | 35 STDMETHOD_(ULONG, AddRef)() = 0; |
27 STDMETHOD_(ULONG, Release)() = 0; | 36 STDMETHOD_(ULONG, Release)() = 0; |
28 }; | 37 }; |
29 | 38 |
30 ScopedComPtr() { | 39 ScopedComPtr() { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
83 | 92 |
84 // Retrieves the pointer address. | 93 // Retrieves the pointer address. |
85 // Used to receive object pointers as out arguments (and take ownership). | 94 // Used to receive object pointers as out arguments (and take ownership). |
86 // The function DCHECKs on the current value being NULL. | 95 // The function DCHECKs on the current value being NULL. |
87 // Usage: Foo(p.Receive()); | 96 // Usage: Foo(p.Receive()); |
88 Interface** Receive() { | 97 Interface** Receive() { |
89 DCHECK(!ptr_) << "Object leak. Pointer must be NULL"; | 98 DCHECK(!ptr_) << "Object leak. Pointer must be NULL"; |
90 return &ptr_; | 99 return &ptr_; |
91 } | 100 } |
92 | 101 |
93 // A convenience for whenever a void pointer is needed as an out argument. | |
94 void** ReceiveVoid() { | |
95 return reinterpret_cast<void**>(Receive()); | |
96 } | |
97 | |
98 template <class Query> | 102 template <class Query> |
99 HRESULT QueryInterface(Query** p) { | 103 HRESULT QueryInterface(Query** p) { |
100 DCHECK(p); | 104 DCHECK(p); |
101 DCHECK(ptr_); | 105 DCHECK(ptr_); |
102 // IUnknown already has a template version of QueryInterface | 106 // IUnknown already has a template version of QueryInterface |
103 // so the iid parameter is implicit here. The only thing this | 107 // so the iid parameter is implicit here. The only thing this |
104 // function adds are the DCHECKs. | 108 // function adds are the DCHECKs. |
105 return ptr_->QueryInterface(IID_PPV_ARGS(p)); | 109 return ptr_->QueryInterface(IID_PPV_ARGS(p)); |
106 } | 110 } |
107 | 111 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
203 template <typename U> | 207 template <typename U> |
204 bool operator!=(const ScopedComPtr<U>& rhs) const { | 208 bool operator!=(const ScopedComPtr<U>& rhs) const { |
205 return ptr_ != rhs.Get(); | 209 return ptr_ != rhs.Get(); |
206 } | 210 } |
207 | 211 |
208 template <typename U> | 212 template <typename U> |
209 bool operator!=(const U* rhs) const { | 213 bool operator!=(const U* rhs) const { |
210 return ptr_ != rhs; | 214 return ptr_ != rhs; |
211 } | 215 } |
212 | 216 |
217 details::ScopedComPtrRef<ScopedComPtr<Interface, interface_id>> operator&() { | |
218 return details::ScopedComPtrRef<ScopedComPtr<Interface, interface_id>>( | |
219 this); | |
220 } | |
221 | |
213 void swap(ScopedComPtr<Interface, interface_id>& r) { | 222 void swap(ScopedComPtr<Interface, interface_id>& r) { |
214 Interface* tmp = ptr_; | 223 Interface* tmp = ptr_; |
215 ptr_ = r.ptr_; | 224 ptr_ = r.ptr_; |
216 r.ptr_ = tmp; | 225 r.ptr_ = tmp; |
217 } | 226 } |
218 | 227 |
219 private: | 228 private: |
220 Interface* ptr_ = nullptr; | 229 Interface* ptr_ = nullptr; |
221 }; | 230 }; |
222 | 231 |
232 namespace details { | |
233 | |
234 // ComPtrRef equivalent transitional reference type to handle ComPtr equivalent | |
235 // void** implicit casting. T should be a ScopedComPtr. | |
236 template <typename T> | |
237 class ScopedComPtrRef { | |
238 public: | |
239 ScopedComPtrRef(T* scoped_com_ptr) : scoped_com_ptr_(scoped_com_ptr) {} | |
scottmg
2017/04/27 23:16:07
explicit
| |
240 | |
241 // ComPtr equivalent conversion operators. | |
242 operator void**() const { | |
243 return reinterpret_cast<void**>(scoped_com_ptr_->Receive()); | |
244 } | |
245 | |
246 // Allows ScopedComPtr to be passed to functions as a pointer. | |
247 operator T*() { return scoped_com_ptr_; } | |
248 | |
249 // Allows IID_PPV_ARGS to perform __uuidof(**(ppType)). | |
250 typename T::InterfaceType* operator*() { return scoped_com_ptr_->Get(); } | |
251 | |
252 private: | |
253 T* const scoped_com_ptr_; | |
254 }; | |
255 | |
256 } // details | |
257 | |
223 template <typename T, typename U> | 258 template <typename T, typename U> |
224 bool operator==(const T* lhs, const ScopedComPtr<U>& rhs) { | 259 bool operator==(const T* lhs, const ScopedComPtr<U>& rhs) { |
225 return lhs == rhs.Get(); | 260 return lhs == rhs.Get(); |
226 } | 261 } |
227 | 262 |
228 template <typename T> | 263 template <typename T> |
229 bool operator==(const ScopedComPtr<T>& lhs, std::nullptr_t null) { | 264 bool operator==(const ScopedComPtr<T>& lhs, std::nullptr_t null) { |
230 return !static_cast<bool>(lhs); | 265 return !static_cast<bool>(lhs); |
231 } | 266 } |
232 | 267 |
(...skipping 17 matching lines...) Expand all Loading... | |
250 return !operator==(null, rhs); | 285 return !operator==(null, rhs); |
251 } | 286 } |
252 | 287 |
253 template <typename T> | 288 template <typename T> |
254 std::ostream& operator<<(std::ostream& out, const ScopedComPtr<T>& p) { | 289 std::ostream& operator<<(std::ostream& out, const ScopedComPtr<T>& p) { |
255 return out << p.Get(); | 290 return out << p.Get(); |
256 } | 291 } |
257 | 292 |
258 // Helper to make IID_PPV_ARGS work with ScopedComPtr. | 293 // Helper to make IID_PPV_ARGS work with ScopedComPtr. |
259 template <typename T> | 294 template <typename T> |
260 void** IID_PPV_ARGS_Helper(base::win::ScopedComPtr<T>* pp) throw() { | 295 void** IID_PPV_ARGS_Helper(base::win::details::ScopedComPtrRef<T> pp) throw() { |
261 return pp->ReceiveVoid(); | 296 return pp; |
262 } | 297 } |
263 | 298 |
264 } // namespace win | 299 } // namespace win |
265 } // namespace base | 300 } // namespace base |
266 | 301 |
267 #endif // BASE_WIN_SCOPED_COMPTR_H_ | 302 #endif // BASE_WIN_SCOPED_COMPTR_H_ |
OLD | NEW |