Chromium Code Reviews| 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 |