Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2940)

Unified Diff: base/win/scoped_comptr.h

Issue 2787123006: Remove Base Class from ScopedComPtr and Deprecate (Closed)
Patch Set: Add swap() (is_chrome_branded isn't run on the CQ) Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/win/scoped_comptr.h
diff --git a/base/win/scoped_comptr.h b/base/win/scoped_comptr.h
index 9442672054a90f99a47d49831ad197986bbbacd7..8e052500cc86a978f1634eebc7f4d77b9e9734ee 100644
--- a/base/win/scoped_comptr.h
+++ b/base/win/scoped_comptr.h
@@ -8,16 +8,14 @@
#include <unknwn.h>
#include "base/logging.h"
-#include "base/memory/ref_counted.h"
namespace base {
namespace win {
+// DEPRECATED: Use Microsoft::WRL::ComPtr instead.
// A fairly minimalistic smart class for COM interface pointers.
-// Uses scoped_refptr for the basic smart pointer functionality
-// and adds a few IUnknown specific services.
template <class Interface, const IID* interface_id = &__uuidof(Interface)>
-class ScopedComPtr : public scoped_refptr<Interface> {
+class ScopedComPtr {
public:
// Utility template to prevent users of ScopedComPtr from calling AddRef
// and/or Release() without going through the ScopedComPtr class.
@@ -28,16 +26,17 @@ class ScopedComPtr : public scoped_refptr<Interface> {
STDMETHOD_(ULONG, Release)() = 0;
};
- typedef scoped_refptr<Interface> ParentClass;
-
ScopedComPtr() {
}
- explicit ScopedComPtr(Interface* p) : ParentClass(p) {
+ explicit ScopedComPtr(Interface* p) : ptr_(p) {
+ if (ptr_)
+ ptr_->AddRef();
}
- ScopedComPtr(const ScopedComPtr<Interface, interface_id>& p)
- : ParentClass(p) {
+ ScopedComPtr(const ScopedComPtr<Interface, interface_id>& p) : ptr_(p.get()) {
+ if (ptr_)
+ ptr_->AddRef();
}
~ScopedComPtr() {
@@ -46,31 +45,37 @@ class ScopedComPtr : public scoped_refptr<Interface> {
static_assert(
sizeof(ScopedComPtr<Interface, interface_id>) == sizeof(Interface*),
"ScopedComPtrSize");
+ Release();
}
+ Interface* get() const { return ptr_; }
+
+ explicit operator bool() const { return ptr_ != nullptr; }
+
// Explicit Release() of the held object. Useful for reuse of the
// ScopedComPtr instance.
// Note that this function equates to IUnknown::Release and should not
// be confused with e.g. unique_ptr::release().
void Release() {
- if (this->ptr_ != NULL) {
- this->ptr_->Release();
- this->ptr_ = NULL;
+ Interface* temp = ptr_;
+ if (temp) {
+ ptr_ = nullptr;
+ temp->Release();
}
}
// Sets the internal pointer to NULL and returns the held object without
// releasing the reference.
Interface* Detach() {
- Interface* p = this->ptr_;
- this->ptr_ = NULL;
+ Interface* p = ptr_;
+ ptr_ = nullptr;
return p;
}
// Accepts an interface pointer that has already been addref-ed.
void Attach(Interface* p) {
- DCHECK(!this->ptr_);
- this->ptr_ = p;
+ DCHECK(!ptr_);
+ ptr_ = p;
}
// Retrieves the pointer address.
@@ -78,8 +83,8 @@ class ScopedComPtr : public scoped_refptr<Interface> {
// The function DCHECKs on the current value being NULL.
// Usage: Foo(p.Receive());
Interface** Receive() {
- DCHECK(!this->ptr_) << "Object leak. Pointer must be NULL";
- return &this->ptr_;
+ DCHECK(!ptr_) << "Object leak. Pointer must be NULL";
+ return &ptr_;
}
// A convenience for whenever a void pointer is needed as an out argument.
@@ -89,43 +94,44 @@ class ScopedComPtr : public scoped_refptr<Interface> {
template <class Query>
HRESULT QueryInterface(Query** p) {
- DCHECK(p != NULL);
- DCHECK(this->ptr_ != NULL);
+ DCHECK(p);
+ DCHECK(ptr_);
// IUnknown already has a template version of QueryInterface
// so the iid parameter is implicit here. The only thing this
// function adds are the DCHECKs.
- return this->ptr_->QueryInterface(p);
+ return ptr_->QueryInterface(p);
}
// QI for times when the IID is not associated with the type.
HRESULT QueryInterface(const IID& iid, void** obj) {
- DCHECK(obj != NULL);
- DCHECK(this->ptr_ != NULL);
- return this->ptr_->QueryInterface(iid, obj);
+ DCHECK(obj);
+ DCHECK(ptr_);
+ return ptr_->QueryInterface(iid, obj);
}
// Queries |other| for the interface this object wraps and returns the
// error code from the other->QueryInterface operation.
HRESULT QueryFrom(IUnknown* object) {
- DCHECK(object != NULL);
+ DCHECK(object);
return object->QueryInterface(Receive());
}
// Convenience wrapper around CoCreateInstance
- HRESULT CreateInstance(const CLSID& clsid, IUnknown* outer = NULL,
+ HRESULT CreateInstance(const CLSID& clsid,
+ IUnknown* outer = nullptr,
DWORD context = CLSCTX_ALL) {
- DCHECK(!this->ptr_);
+ DCHECK(!ptr_);
HRESULT hr = ::CoCreateInstance(clsid, outer, context, *interface_id,
- reinterpret_cast<void**>(&this->ptr_));
+ reinterpret_cast<void**>(&ptr_));
return hr;
}
// Checks if the identity of |other| and this object is the same.
bool IsSameObject(IUnknown* other) {
- if (!other && !this->ptr_)
+ if (!other && !ptr_)
return true;
- if (!other || !this->ptr_)
+ if (!other || !ptr_)
return false;
ScopedComPtr<IUnknown> my_identity;
@@ -148,20 +154,109 @@ class ScopedComPtr : public scoped_refptr<Interface> {
// by statically casting the ScopedComPtr instance to the wrapped interface
// and then making the call... but generally that shouldn't be necessary.
BlockIUnknownMethods* operator->() const {
- DCHECK(this->ptr_ != NULL);
- return reinterpret_cast<BlockIUnknownMethods*>(this->ptr_);
+ DCHECK(ptr_);
+ return reinterpret_cast<BlockIUnknownMethods*>(ptr_);
+ }
+
+ ScopedComPtr<Interface, interface_id>& operator=(Interface* rhs) {
+ // AddRef first so that self assignment should work
+ if (rhs)
+ rhs->AddRef();
+ Interface* old_ptr = ptr_;
+ ptr_ = rhs;
+ if (old_ptr)
+ old_ptr->Release();
+ return *this;
}
- // Pull in operator=() from the parent class.
- using scoped_refptr<Interface>::operator=;
+ ScopedComPtr<Interface, interface_id>& operator=(
+ const ScopedComPtr<Interface, interface_id>& rhs) {
+ return *this = rhs.ptr_;
+ }
- // static methods
+ Interface& operator*() const {
+ DCHECK(ptr_);
+ return *ptr_;
+ }
+
+ bool operator==(const ScopedComPtr<Interface, interface_id>& rhs) const {
+ return ptr_ == rhs.get();
+ }
+
+ template <typename U>
+ bool operator==(const ScopedComPtr<U>& rhs) const {
+ return ptr_ == rhs.get();
+ }
+
+ template <typename U>
+ bool operator==(const U* rhs) const {
+ return ptr_ == rhs;
+ }
+
+ bool operator!=(const ScopedComPtr<Interface, interface_id>& rhs) const {
+ return ptr_ != rhs.get();
+ }
+ template <typename U>
+ bool operator!=(const ScopedComPtr<U>& rhs) const {
+ return ptr_ != rhs.get();
+ }
+
+ template <typename U>
+ bool operator!=(const U* rhs) const {
+ return ptr_ != rhs;
+ }
+
+ void swap(ScopedComPtr<Interface, interface_id>& r) {
+ Interface* tmp = ptr_;
+ ptr_ = r.ptr_;
+ r.ptr_ = tmp;
+ }
+
+ // static methods
static const IID& iid() {
return *interface_id;
}
+
+ private:
+ Interface* ptr_ = nullptr;
};
+template <typename T, typename U>
+bool operator==(const T* lhs, const ScopedComPtr<U>& rhs) {
+ return lhs == rhs.get();
+}
+
+template <typename T>
+bool operator==(const ScopedComPtr<T>& lhs, std::nullptr_t null) {
+ return !static_cast<bool>(lhs);
+}
+
+template <typename T>
+bool operator==(std::nullptr_t null, const ScopedComPtr<T>& rhs) {
+ return !static_cast<bool>(rhs);
+}
+
+template <typename T, typename U>
+bool operator!=(const T* lhs, const ScopedComPtr<U>& rhs) {
+ return !operator==(lhs, rhs);
+}
+
+template <typename T>
+bool operator!=(const ScopedComPtr<T>& lhs, std::nullptr_t null) {
+ return !operator==(lhs, null);
+}
+
+template <typename T>
+bool operator!=(std::nullptr_t null, const ScopedComPtr<T>& rhs) {
+ return !operator==(null, rhs);
+}
+
+template <typename T>
+std::ostream& operator<<(std::ostream& out, const ScopedComPtr<T>& p) {
+ return out << p.get();
+}
+
} // namespace win
} // namespace base
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698