Chromium Code Reviews| Index: base/win/scoped_comptr.h |
| diff --git a/base/win/scoped_comptr.h b/base/win/scoped_comptr.h |
| index 74c429d703cfa63138b28a0654ce56bf7356e713..6683eff168a5143ff6395313ca3999737f2ae302 100644 |
| --- a/base/win/scoped_comptr.h |
| +++ b/base/win/scoped_comptr.h |
| @@ -13,11 +13,20 @@ |
| namespace base { |
| namespace win { |
| +namespace details { |
| + |
| +template <typename T> |
| +class ScopedComPtrRef; |
| + |
| +} // details |
| + |
| // DEPRECATED: Use Microsoft::WRL::ComPtr instead. |
| // A fairly minimalistic smart class for COM interface pointers. |
| template <class Interface, const IID* interface_id = &__uuidof(Interface)> |
| class ScopedComPtr { |
| public: |
| + using InterfaceType = Interface; |
| + |
| // Utility template to prevent users of ScopedComPtr from calling AddRef |
| // and/or Release() without going through the ScopedComPtr class. |
| class BlockIUnknownMethods : public Interface { |
| @@ -90,11 +99,6 @@ class ScopedComPtr { |
| return &ptr_; |
| } |
| - // A convenience for whenever a void pointer is needed as an out argument. |
| - void** ReceiveVoid() { |
| - return reinterpret_cast<void**>(Receive()); |
| - } |
| - |
| template <class Query> |
| HRESULT QueryInterface(Query** p) { |
| DCHECK(p); |
| @@ -210,6 +214,11 @@ class ScopedComPtr { |
| return ptr_ != rhs; |
| } |
| + details::ScopedComPtrRef<ScopedComPtr<Interface, interface_id>> operator&() { |
| + return details::ScopedComPtrRef<ScopedComPtr<Interface, interface_id>>( |
| + this); |
| + } |
| + |
| void swap(ScopedComPtr<Interface, interface_id>& r) { |
| Interface* tmp = ptr_; |
| ptr_ = r.ptr_; |
| @@ -220,6 +229,32 @@ class ScopedComPtr { |
| Interface* ptr_ = nullptr; |
| }; |
| +namespace details { |
| + |
| +// ComPtrRef equivalent transitional reference type to handle ComPtr equivalent |
| +// void** implicit casting. T should be a ScopedComPtr. |
| +template <typename T> |
| +class ScopedComPtrRef { |
| + public: |
| + ScopedComPtrRef(T* scoped_com_ptr) : scoped_com_ptr_(scoped_com_ptr) {} |
|
scottmg
2017/04/27 23:16:07
explicit
|
| + |
| + // ComPtr equivalent conversion operators. |
| + operator void**() const { |
| + return reinterpret_cast<void**>(scoped_com_ptr_->Receive()); |
| + } |
| + |
| + // Allows ScopedComPtr to be passed to functions as a pointer. |
| + operator T*() { return scoped_com_ptr_; } |
| + |
| + // Allows IID_PPV_ARGS to perform __uuidof(**(ppType)). |
| + typename T::InterfaceType* operator*() { return scoped_com_ptr_->Get(); } |
| + |
| + private: |
| + T* const scoped_com_ptr_; |
| +}; |
| + |
| +} // details |
| + |
| template <typename T, typename U> |
| bool operator==(const T* lhs, const ScopedComPtr<U>& rhs) { |
| return lhs == rhs.Get(); |
| @@ -257,8 +292,8 @@ std::ostream& operator<<(std::ostream& out, const ScopedComPtr<T>& p) { |
| // Helper to make IID_PPV_ARGS work with ScopedComPtr. |
| template <typename T> |
| -void** IID_PPV_ARGS_Helper(base::win::ScopedComPtr<T>* pp) throw() { |
| - return pp->ReceiveVoid(); |
| +void** IID_PPV_ARGS_Helper(base::win::details::ScopedComPtrRef<T> pp) throw() { |
| + return pp; |
| } |
| } // namespace win |