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 |