18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
2f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick *  Copyright (C) 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is free software; you can redistribute it and/or
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  modify it under the terms of the GNU Library General Public
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  License as published by the Free Software Foundation; either
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  version 2 of the License, or (at your option) any later version.
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  This library is distributed in the hope that it will be useful,
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  but WITHOUT ANY WARRANTY; without even the implied warranty of
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Library General Public License for more details.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  You should have received a copy of the GNU Library General Public License
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  along with this library; see the file COPYING.LIB.  If not, write to
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  Boston, MA 02110-1301, USA.
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef RetainPtr_h
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define RetainPtr_h
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen#include "HashTraits.h"
25a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "NullPtr.h"
268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "TypeTraits.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <algorithm>
2881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
2981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if USE(CF)
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <CoreFoundation/CoreFoundation.h>
3181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef __OBJC__
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <Foundation/Foundation.h>
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WTF {
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Unlike most most of our smart pointers, RetainPtr can take either the pointer type or the pointed-to type,
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // so both RetainPtr<NSDictionary> and RetainPtr<CFDictionaryRef> will work.
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    enum AdoptCFTag { AdoptCF };
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    enum AdoptNSTag { AdoptNS };
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef __OBJC__
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    inline void adoptNSReference(id ptr)
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ptr) {
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CFRetain(ptr);
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            [ptr release];
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
55f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T> class RetainPtr {
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    public:
578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        typedef typename RemovePointer<T>::Type ValueType;
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        typedef ValueType* PtrType;
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RetainPtr() : m_ptr(0) {}
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RetainPtr(PtrType ptr) : m_ptr(ptr) { if (ptr) CFRetain(ptr); }
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RetainPtr(AdoptCFTag, PtrType ptr) : m_ptr(ptr) { }
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RetainPtr(AdoptNSTag, PtrType ptr) : m_ptr(ptr) { adoptNSReference(ptr); }
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RetainPtr(const RetainPtr& o) : m_ptr(o.m_ptr) { if (PtrType ptr = m_ptr) CFRetain(ptr); }
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        // Hash table deleted values, which are only constructed and never copied or destroyed.
6906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        RetainPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
7006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
7106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ~RetainPtr() { if (PtrType ptr = m_ptr) CFRelease(ptr); }
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
74f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        template<typename U> RetainPtr(const RetainPtr<U>&);
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PtrType get() const { return m_ptr; }
77f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
78f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        void clear();
79f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        PtrType leakRef() WARN_UNUSED_RETURN;
80f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PtrType operator->() const { return m_ptr; }
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        bool operator!() const { return !m_ptr; }
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This conversion operator allows implicit conversion to bool but not to other integer types.
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        typedef PtrType RetainPtr::*UnspecifiedBoolType;
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        operator UnspecifiedBoolType() const { return m_ptr ? &RetainPtr::m_ptr : 0; }
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RetainPtr& operator=(const RetainPtr&);
90f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        template<typename U> RetainPtr& operator=(const RetainPtr<U>&);
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        RetainPtr& operator=(PtrType);
92f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        template<typename U> RetainPtr& operator=(U*);
93cad810f21b803229eb11403f9209855525a25d57Steve Block#if !HAVE(NULLPTR)
94a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        RetainPtr& operator=(std::nullptr_t) { clear(); return *this; }
95cad810f21b803229eb11403f9209855525a25d57Steve Block#endif
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        void adoptCF(PtrType);
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        void adoptNS(PtrType);
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        void swap(RetainPtr&);
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
102f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        // FIXME: Remove releaseRef once we change all callers to call leakRef instead.
103f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        PtrType releaseRef() { return leakRef(); }
104f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private:
10606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
10706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PtrType m_ptr;
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    };
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
111f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T> template<typename U> inline RetainPtr<T>::RetainPtr(const RetainPtr<U>& o)
112f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        : m_ptr(o.get())
113f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    {
114f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        if (PtrType ptr = m_ptr)
115f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            CFRetain(ptr);
116f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
117f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
118f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T> inline void RetainPtr<T>::clear()
119f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    {
120f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        if (PtrType ptr = m_ptr) {
121f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            m_ptr = 0;
122f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            CFRelease(ptr);
123f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        }
124f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
125f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
126f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T> inline typename RetainPtr<T>::PtrType RetainPtr<T>::leakRef()
127f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    {
128f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        PtrType ptr = m_ptr;
129f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        m_ptr = 0;
130f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        return ptr;
131f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    }
132f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
133f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<T>& o)
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PtrType optr = o.get();
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (optr)
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CFRetain(optr);
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PtrType ptr = m_ptr;
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_ptr = optr;
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ptr)
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CFRelease(ptr);
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return *this;
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
145f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<U>& o)
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PtrType optr = o.get();
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (optr)
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CFRetain(optr);
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PtrType ptr = m_ptr;
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_ptr = optr;
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ptr)
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CFRelease(ptr);
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return *this;
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
157f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(PtrType optr)
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (optr)
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CFRetain(optr);
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PtrType ptr = m_ptr;
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_ptr = optr;
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ptr)
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CFRelease(ptr);
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return *this;
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
168f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T> inline void RetainPtr<T>::adoptCF(PtrType optr)
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PtrType ptr = m_ptr;
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_ptr = optr;
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ptr)
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CFRelease(ptr);
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
176f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T> inline void RetainPtr<T>::adoptNS(PtrType optr)
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        adoptNSReference(optr);
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PtrType ptr = m_ptr;
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_ptr = optr;
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ptr)
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CFRelease(ptr);
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
186f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(U* optr)
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (optr)
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CFRetain(optr);
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PtrType ptr = m_ptr;
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_ptr = optr;
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (ptr)
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            CFRelease(ptr);
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return *this;
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
197f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T> inline void RetainPtr<T>::swap(RetainPtr<T>& o)
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        std::swap(m_ptr, o.m_ptr);
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
202f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T> inline void swap(RetainPtr<T>& a, RetainPtr<T>& b)
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        a.swap(b);
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
207f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T, typename U> inline bool operator==(const RetainPtr<T>& a, const RetainPtr<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 Merrick    template<typename T, typename U> inline bool operator==(const RetainPtr<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 Merrick    template<typename T, typename U> inline bool operator==(T* a, const RetainPtr<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
222f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T, typename U> inline bool operator!=(const RetainPtr<T>& a, const RetainPtr<U>& b)
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return a.get() != b.get();
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
227f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T, typename U> inline bool operator!=(const RetainPtr<T>& a, U* b)
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return a.get() != b;
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
232f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    template<typename T, typename U> inline bool operator!=(T* a, const RetainPtr<U>& b)
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return a != b.get();
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
23606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
2372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    template<typename P> struct HashTraits<RetainPtr<P> > : SimpleClassHashTraits<RetainPtr<P> > { };
23806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
23906ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    template<typename P> struct PtrHash<RetainPtr<P> > : PtrHash<P*> {
24006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        using PtrHash<P*>::hash;
24106ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        static unsigned hash(const RetainPtr<P>& key) { return hash(key.get()); }
24206ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        using PtrHash<P*>::equal;
24306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        static bool equal(const RetainPtr<P>& a, const RetainPtr<P>& b) { return a == b; }
24406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        static bool equal(P* a, const RetainPtr<P>& b) { return a == b; }
24506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen        static bool equal(const RetainPtr<P>& a, P* b) { return a == b; }
24606ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    };
24706ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
24806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    template<typename P> struct DefaultHash<RetainPtr<P> > { typedef PtrHash<RetainPtr<P> > Hash; };
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WTF
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing WTF::AdoptCF;
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing WTF::AdoptNS;
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing WTF::RetainPtr;
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif // WTF_RetainPtr_h
257