18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
2f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick * Copyright (C) 2007, 2010 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef COMPtr_h
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define COMPtr_h
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifndef NOMINMAX
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define NOMINMAX
31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <unknwn.h>
34e14391e94c850b8bd03680c23b38978db68687a8John Reck#include <wtf/Assertions.h>
35e14391e94c850b8bd03680c23b38978db68687a8John Reck#include <wtf/HashTraits.h>
36e14391e94c850b8bd03680c23b38978db68687a8John Reck
37e14391e94c850b8bd03680c23b38978db68687a8John Reck#if !OS(WINCE)
38e14391e94c850b8bd03680c23b38978db68687a8John Reck#include <guiddef.h>
39e14391e94c850b8bd03680c23b38978db68687a8John Reck#endif
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef long HRESULT;
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// FIXME: Should we put this into the WebCore namespace and use "using" on it
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// as we do with things in WTF?
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectenum AdoptCOMTag { AdoptCOM };
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectenum QueryTag { Query };
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectenum CreateTag { Create };
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
50f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T> class COMPtr {
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpublic:
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    COMPtr() : m_ptr(0) { }
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    COMPtr(T* ptr) : m_ptr(ptr) { if (m_ptr) m_ptr->AddRef(); }
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    COMPtr(AdoptCOMTag, T* ptr) : m_ptr(ptr) { }
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    COMPtr(const COMPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) ptr->AddRef(); }
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    COMPtr(QueryTag, IUnknown* ptr) : m_ptr(copyQueryInterfaceRef(ptr)) { }
58f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename U> COMPtr(QueryTag, const COMPtr<U>& ptr) : m_ptr(copyQueryInterfaceRef(ptr.get())) { }
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    COMPtr(CreateTag, const IID& clsid) : m_ptr(createInstance(clsid)) { }
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Hash table deleted values, which are only constructed and never copied or destroyed.
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    COMPtr(WTF::HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ~COMPtr() { if (m_ptr) m_ptr->Release(); }
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    T* get() const { return m_ptr; }
69f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
70f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    void clear();
71f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    T* leakRef();
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    T& operator*() const { return *m_ptr; }
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    T* operator->() const { return m_ptr; }
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    T** operator&() { ASSERT(!m_ptr); return &m_ptr; }
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool operator!() const { return !m_ptr; }
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This conversion operator allows implicit conversion to bool but not to other integer types.
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    typedef T* (COMPtr::*UnspecifiedBoolType)() const;
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    operator UnspecifiedBoolType() const { return m_ptr ? &COMPtr::get : 0; }
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    COMPtr& operator=(const COMPtr&);
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    COMPtr& operator=(T*);
86f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename U> COMPtr& operator=(const COMPtr<U>&);
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void query(IUnknown* ptr) { adoptRef(copyQueryInterfaceRef(ptr)); }
89f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename U> void query(const COMPtr<U>& ptr) { query(ptr.get()); }
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void create(const IID& clsid) { adoptRef(createInstance(clsid)); }
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
93f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename U> HRESULT copyRefTo(U**);
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void adoptRef(T*);
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
96f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    // FIXME: Remove releaseRef once we change all callers to call leakRef instead.
97f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    T* releaseRef() { return leakRef(); }
98f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectprivate:
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static T* copyQueryInterfaceRef(IUnknown*);
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static T* createInstance(const IID& clsid);
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    T* m_ptr;
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
107f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T> inline void COMPtr<T>::clear()
108f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{
109f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    if (T* ptr = m_ptr) {
110f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        m_ptr = 0;
111f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        ptr->Release();
112f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
113f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick}
114f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
115f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T> inline T* COMPtr<T>::leakRef()
116f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{
117f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    T* ptr = m_ptr;
118f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    m_ptr = 0;
119f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    return ptr;
120f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick}
121f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
122f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T> inline T* COMPtr<T>::createInstance(const IID& clsid)
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    T* result;
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (FAILED(CoCreateInstance(clsid, 0, CLSCTX_ALL, __uuidof(result), reinterpret_cast<void**>(&result))))
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
130f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T> inline T* COMPtr<T>::copyQueryInterfaceRef(IUnknown* ptr)
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!ptr)
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    T* result;
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (FAILED(ptr->QueryInterface(&result)))
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
140f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T> template<typename U> inline HRESULT COMPtr<T>::copyRefTo(U** ptr)
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!ptr)
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return E_POINTER;
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    *ptr = m_ptr;
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_ptr)
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_ptr->AddRef();
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return S_OK;
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
150f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T> inline void COMPtr<T>::adoptRef(T *ptr)
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_ptr)
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_ptr->Release();
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_ptr = ptr;
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
157f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T> inline COMPtr<T>& COMPtr<T>::operator=(const COMPtr<T>& o)
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    T* optr = o.get();
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (optr)
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        optr->AddRef();
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    T* ptr = m_ptr;
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_ptr = optr;
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ptr)
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ptr->Release();
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return *this;
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
169f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T> template<typename U> inline COMPtr<T>& COMPtr<T>::operator=(const COMPtr<U>& o)
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    T* optr = o.get();
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (optr)
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        optr->AddRef();
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    T* ptr = m_ptr;
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_ptr = optr;
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ptr)
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ptr->Release();
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return *this;
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
181f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T> inline COMPtr<T>& COMPtr<T>::operator=(T* optr)
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (optr)
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        optr->AddRef();
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    T* ptr = m_ptr;
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_ptr = optr;
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ptr)
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ptr->Release();
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return *this;
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
192f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T, typename U> inline bool operator==(const COMPtr<T>& a, const COMPtr<U>& b)
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return a.get() == b.get();
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
197f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T, typename U> inline bool operator==(const COMPtr<T>& a, U* b)
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return a.get() == b;
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
202f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T, typename U> inline bool operator==(T* a, const COMPtr<U>& b)
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return a == b.get();
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
207f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T, typename U> inline bool operator!=(const COMPtr<T>& a, const COMPtr<U>& b)
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return a.get() != b.get();
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
212f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T, typename U> inline bool operator!=(const COMPtr<T>& a, U* b)
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return a.get() != b;
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
217f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricktemplate<typename T, typename U> inline bool operator!=(T* a, const COMPtr<U>& b)
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return a != b.get();
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WTF {
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    template<typename P> struct HashTraits<COMPtr<P> > : GenericHashTraits<COMPtr<P> > {
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static const bool emptyValueIsZero = true;
226f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        static void constructDeletedValue(COMPtr<P>& slot) { new (&slot) COMPtr<P>(HashTableDeletedValue); }
227f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        static bool isDeletedValue(const COMPtr<P>& value) { return value.isHashTableDeletedValue(); }
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    template<typename P> struct PtrHash<COMPtr<P> > : PtrHash<P*> {
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        using PtrHash<P*>::hash;
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static unsigned hash(const COMPtr<P>& key) { return hash(key.get()); }
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        using PtrHash<P*>::equal;
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static bool equal(const COMPtr<P>& a, const COMPtr<P>& b) { return a == b; }
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static bool equal(P* a, const COMPtr<P>& b) { return a == b; }
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        static bool equal(const COMPtr<P>& a, P* b) { return a == b; }
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    template<typename P> struct DefaultHash<COMPtr<P> > { typedef PtrHash<COMPtr<P> > Hash; };
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
243