15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  Copyright (C) 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  This library is free software; you can redistribute it and/or
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  modify it under the terms of the GNU Library General Public
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  License as published by the Free Software Foundation; either
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  version 2 of the License, or (at your option) any later version.
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  This library is distributed in the hope that it will be useful,
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  but WITHOUT ANY WARRANTY; without even the implied warranty of
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  Library General Public License for more details.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  You should have received a copy of the GNU Library General Public License
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  along with this library; see the file COPYING.LIB.  If not, write to
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  Boston, MA 02110-1301, USA.
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef RetainPtr_h
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define RetainPtr_h
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
240019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch#include "wtf/HashTableDeletedValueType.h"
25591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/HashTraits.h"
26591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/NullPtr.h"
27591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/TypeTraits.h"
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <algorithm>
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if USE(CF)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <CoreFoundation/CoreFoundation.h>
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifdef __OBJC__
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#import <Foundation/Foundation.h>
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef CF_RELEASES_ARGUMENT
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define CF_RELEASES_ARGUMENT
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef NS_RELEASES_ARGUMENT
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define NS_RELEASES_ARGUMENT
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WTF {
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Unlike most most of our smart pointers, RetainPtr can take either the pointer type or the pointed-to type,
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // so both RetainPtr<NSDictionary> and RetainPtr<CFDictionaryRef> will work.
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    enum AdoptCFTag { AdoptCF };
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    enum AdoptNSTag { AdoptNS };
5302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifdef __OBJC__
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    inline void adoptNSReference(id ptr)
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (ptr) {
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CFRetain(ptr);
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            [ptr release];
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> class RetainPtr {
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    public:
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        typedef typename RemovePointer<T>::Type ValueType;
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        typedef ValueType* PtrType;
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RetainPtr() : m_ptr(0) {}
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RetainPtr(PtrType ptr) : m_ptr(ptr) { if (ptr) CFRetain(ptr); }
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RetainPtr(AdoptCFTag, PtrType ptr) : m_ptr(ptr) { }
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RetainPtr(AdoptNSTag, PtrType ptr) : m_ptr(ptr) { adoptNSReference(ptr); }
7402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RetainPtr(const RetainPtr& o) : m_ptr(o.m_ptr) { if (PtrType ptr = m_ptr) CFRetain(ptr); }
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RetainPtr(RetainPtr&& o) : m_ptr(o.leakRef()) { }
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Hash table deleted values, which are only constructed and never copied or destroyed.
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RetainPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
8402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ~RetainPtr() { if (PtrType ptr = m_ptr) CFRelease(ptr); }
8602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        template<typename U> RetainPtr(const RetainPtr<U>&);
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void clear();
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        PtrType leakRef() WARN_UNUSED_RETURN;
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        PtrType get() const { return m_ptr; }
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        PtrType operator->() const { return m_ptr; }
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if COMPILER_SUPPORTS(CXX_EXPLICIT_CONVERSIONS)
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        explicit operator PtrType() const { return m_ptr; }
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool operator!() const { return !m_ptr; }
9902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // This conversion operator allows implicit conversion to bool but not to other integer types.
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        typedef PtrType RetainPtr::*UnspecifiedBoolType;
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        operator UnspecifiedBoolType() const { return m_ptr ? &RetainPtr::m_ptr : 0; }
10302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RetainPtr& operator=(const RetainPtr&);
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        template<typename U> RetainPtr& operator=(const RetainPtr<U>&);
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RetainPtr& operator=(PtrType);
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        template<typename U> RetainPtr& operator=(U*);
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RetainPtr& operator=(RetainPtr&&);
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        template<typename U> RetainPtr& operator=(RetainPtr<U>&&);
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if !COMPILER_SUPPORTS(CXX_NULLPTR)
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        RetainPtr& operator=(std::nullptr_t) { clear(); return *this; }
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void adoptCF(PtrType);
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void adoptNS(PtrType);
12002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        void swap(RetainPtr&);
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    private:
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        static PtrType hashTableDeletedValue() { return reinterpret_cast<PtrType>(-1); }
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        PtrType m_ptr;
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
12802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> template<typename U> inline RetainPtr<T>::RetainPtr(const RetainPtr<U>& o)
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_ptr(o.get())
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (PtrType ptr = m_ptr)
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CFRetain(ptr);
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> inline void RetainPtr<T>::clear()
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (PtrType ptr = m_ptr) {
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_ptr = 0;
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CFRelease(ptr);
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> inline typename RetainPtr<T>::PtrType RetainPtr<T>::leakRef()
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        PtrType ptr = m_ptr;
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_ptr = 0;
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return ptr;
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<T>& o)
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        PtrType optr = o.get();
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (optr)
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CFRetain(optr);
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        PtrType ptr = m_ptr;
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_ptr = optr;
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (ptr)
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CFRelease(ptr);
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return *this;
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
16202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<U>& o)
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        PtrType optr = o.get();
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (optr)
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CFRetain(optr);
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        PtrType ptr = m_ptr;
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_ptr = optr;
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (ptr)
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CFRelease(ptr);
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return *this;
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(PtrType optr)
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (optr)
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CFRetain(optr);
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        PtrType ptr = m_ptr;
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_ptr = optr;
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (ptr)
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CFRelease(ptr);
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return *this;
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(U* optr)
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (optr)
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CFRetain(optr);
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        PtrType ptr = m_ptr;
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_ptr = optr;
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (ptr)
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CFRelease(ptr);
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return *this;
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr<T>&& o)
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        adoptCF(o.leakRef());
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return *this;
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
20302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(RetainPtr<U>&& o)
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        adoptCF(o.leakRef());
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return *this;
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> inline void RetainPtr<T>::adoptCF(PtrType optr)
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        PtrType ptr = m_ptr;
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_ptr = optr;
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (ptr)
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CFRelease(ptr);
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> inline void RetainPtr<T>::adoptNS(PtrType optr)
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        adoptNSReference(optr);
22202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        PtrType ptr = m_ptr;
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_ptr = optr;
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (ptr)
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CFRelease(ptr);
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> inline void RetainPtr<T>::swap(RetainPtr<T>& o)
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        std::swap(m_ptr, o.m_ptr);
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> inline void swap(RetainPtr<T>& a, RetainPtr<T>& b)
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        a.swap(b);
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T, typename U> inline bool operator==(const RetainPtr<T>& a, const RetainPtr<U>& b)
24002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    {
24102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        return a.get() == b.get();
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T, typename U> inline bool operator==(const RetainPtr<T>& a, U* b)
24502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    {
24602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        return a.get() == b;
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
24802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
24902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    template<typename T, typename U> inline bool operator==(T* a, const RetainPtr<U>& b)
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
25102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        return a == b.get();
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
25302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T, typename U> inline bool operator!=(const RetainPtr<T>& a, const RetainPtr<U>& b)
25502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    {
25602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        return a.get() != b.get();
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T, typename U> inline bool operator!=(const RetainPtr<T>& a, U* b)
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
26102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        return a.get() != b;
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T, typename U> inline bool operator!=(T* a, const RetainPtr<U>& b)
26502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    {
26602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        return a != b.get();
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> inline RetainPtr<T> adoptCF(T CF_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> inline RetainPtr<T> adoptCF(T o)
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return RetainPtr<T>(AdoptCF, o);
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> inline RetainPtr<T> adoptNS(T NS_RELEASES_ARGUMENT) WARN_UNUSED_RETURN;
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> inline RetainPtr<T> adoptNS(T o)
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return RetainPtr<T>(AdoptNS, o);
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Helper function for creating a RetainPtr using template argument deduction.
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> inline RetainPtr<T> retainPtr(T) WARN_UNUSED_RETURN;
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename T> inline RetainPtr<T> retainPtr(T o)
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return RetainPtr<T>(o);
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename P> struct HashTraits<RetainPtr<P> > : SimpleClassHashTraits<RetainPtr<P> > { };
28902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    template<typename P> struct PtrHash<RetainPtr<P> > : PtrHash<typename RetainPtr<P>::PtrType> {
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        using PtrHash<typename RetainPtr<P>::PtrType>::hash;
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        static unsigned hash(const RetainPtr<P>& key) { return hash(key.get()); }
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        using PtrHash<typename RetainPtr<P>::PtrType>::equal;
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        static bool equal(const RetainPtr<P>& a, const RetainPtr<P>& b) { return a == b; }
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        static bool equal(typename RetainPtr<P>::PtrType a, const RetainPtr<P>& b) { return a == b; }
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        static bool equal(const RetainPtr<P>& a, typename RetainPtr<P>::PtrType b) { return a == b; }
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
298926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
299e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    template<typename P> struct DefaultHash<RetainPtr<P> > { typedef PtrHash<RetainPtr<P> > Hash; };
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WTF
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using WTF::AdoptCF;
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using WTF::AdoptNS;
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using WTF::adoptCF;
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using WTF::adoptNS;
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using WTF::RetainPtr;
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using WTF::retainPtr;
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // WTF_RetainPtr_h
310