Rebaseline svg/custom/foreignObject-crash-on-hover.xml.
[chromium-blink-merge.git] / base / scoped_comptr_win.h
blobdbe2805a134939dcb83ccfd286321a8e149c9c73
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef BASE_SCOPED_COMPTR_WIN_H_
6 #define BASE_SCOPED_COMPTR_WIN_H_
8 #include <unknwn.h>
10 #include "base/logging.h"
11 #include "base/ref_counted.h"
13 // Utility template to prevent users of ScopedComPtr from calling AddRef and/or
14 // Release() without going through the ScopedComPtr class.
15 template <class Interface>
16 class BlockIUnknownMethods : public Interface {
17 private:
18 STDMETHOD(QueryInterface)(REFIID iid, void** object) = 0;
19 STDMETHOD_(ULONG, AddRef)() = 0;
20 STDMETHOD_(ULONG, Release)() = 0;
23 // A fairly minimalistic smart class for COM interface pointers.
24 // Uses scoped_refptr for the basic smart pointer functionality
25 // and adds a few IUnknown specific services.
26 template <class Interface, const IID* interface_id = &__uuidof(Interface)>
27 class ScopedComPtr : public scoped_refptr<Interface> {
28 public:
29 typedef scoped_refptr<Interface> ParentClass;
31 ScopedComPtr() {
34 explicit ScopedComPtr(Interface* p) : ParentClass(p) {
37 ScopedComPtr(const ScopedComPtr<Interface, interface_id>& p)
38 : ParentClass(p) {
41 ~ScopedComPtr() {
42 // We don't want the smart pointer class to be bigger than the pointer
43 // it wraps.
44 COMPILE_ASSERT(sizeof(ScopedComPtr<Interface, interface_id>) ==
45 sizeof(Interface*), ScopedComPtrSize);
48 // Explicit Release() of the held object. Useful for reuse of the
49 // ScopedComPtr instance.
50 // Note that this function equates to IUnknown::Release and should not
51 // be confused with e.g. scoped_ptr::release().
52 void Release() {
53 if (ptr_ != NULL) {
54 ptr_->Release();
55 ptr_ = NULL;
59 // Sets the internal pointer to NULL and returns the held object without
60 // releasing the reference.
61 Interface* Detach() {
62 Interface* p = ptr_;
63 ptr_ = NULL;
64 return p;
67 // Accepts an interface pointer that has already been addref-ed.
68 void Attach(Interface* p) {
69 DCHECK(ptr_ == NULL);
70 ptr_ = p;
73 // Retrieves the pointer address.
74 // Used to receive object pointers as out arguments (and take ownership).
75 // The function DCHECKs on the current value being NULL.
76 // Usage: Foo(p.Receive());
77 Interface** Receive() {
78 DCHECK(ptr_ == NULL) << "Object leak. Pointer must be NULL";
79 return &ptr_;
82 template <class Query>
83 HRESULT QueryInterface(Query** p) {
84 DCHECK(p != NULL);
85 DCHECK(ptr_ != NULL);
86 // IUnknown already has a template version of QueryInterface
87 // so the iid parameter is implicit here. The only thing this
88 // function adds are the DCHECKs.
89 return ptr_->QueryInterface(p);
92 // QI for times when the IID is not associated with the type.
93 HRESULT QueryInterface(const IID& iid, void** obj) {
94 DCHECK(obj != NULL);
95 DCHECK(ptr_ != NULL);
96 return ptr_->QueryInterface(iid, obj);
99 // Queries |other| for the interface this object wraps and returns the
100 // error code from the other->QueryInterface operation.
101 HRESULT QueryFrom(IUnknown* object) {
102 DCHECK(object != NULL);
103 return object->QueryInterface(Receive());
106 // Convenience wrapper around CoCreateInstance
107 HRESULT CreateInstance(const CLSID& clsid, IUnknown* outer = NULL,
108 DWORD context = CLSCTX_ALL) {
109 DCHECK(ptr_ == NULL);
110 HRESULT hr = ::CoCreateInstance(clsid, outer, context, *interface_id,
111 reinterpret_cast<void**>(&ptr_));
112 return hr;
115 // Checks if the identity of |other| and this object is the same.
116 bool IsSameObject(IUnknown* other) {
117 if (!other && !ptr_)
118 return true;
120 if (!other || !ptr_)
121 return false;
123 ScopedComPtr<IUnknown> my_identity;
124 QueryInterface(my_identity.Receive());
126 ScopedComPtr<IUnknown> other_identity;
127 other->QueryInterface(other_identity.Receive());
129 return static_cast<IUnknown*>(my_identity) ==
130 static_cast<IUnknown*>(other_identity);
133 // Provides direct access to the interface.
134 // Here we use a well known trick to make sure we block access to
135 // IUknown methods so that something bad like this doesn't happen:
136 // ScopedComPtr<IUnknown> p(Foo());
137 // p->Release();
138 // ... later the destructor runs, which will Release() again.
139 // and to get the benefit of the DCHECKs we add to QueryInterface.
140 // There's still a way to call these methods if you absolutely must
141 // by statically casting the ScopedComPtr instance to the wrapped interface
142 // and then making the call... but generally that shouldn't be necessary.
143 BlockIUnknownMethods<Interface>* operator->() const {
144 DCHECK(ptr_ != NULL);
145 return reinterpret_cast<BlockIUnknownMethods<Interface>*>(ptr_);
148 // Pull in operator=() from the parent class.
149 using scoped_refptr<Interface>::operator=;
151 // static methods
153 static const IID& iid() {
154 return *interface_id;
158 #endif // BASE_SCOPED_COMPTR_WIN_H_