Home | History | Annotate | Download | only in wtf
      1 /*
      2  *  Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
      3  *
      4  *  This library is free software; you can redistribute it and/or
      5  *  modify it under the terms of the GNU Library General Public
      6  *  License as published by the Free Software Foundation; either
      7  *  version 2 of the License, or (at your option) any later version.
      8  *
      9  *  This library is distributed in the hope that it will be useful,
     10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  *  Library General Public License for more details.
     13  *
     14  *  You should have received a copy of the GNU Library General Public License
     15  *  along with this library; see the file COPYING.LIB.  If not, write to
     16  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  *  Boston, MA 02110-1301, USA.
     18  *
     19  */
     20 
     21 // RefPtr and PassRefPtr are documented at http://webkit.org/coding/RefPtr.html
     22 
     23 #ifndef WTF_RefPtr_h
     24 #define WTF_RefPtr_h
     25 
     26 #include <algorithm>
     27 #include "wtf/FastAllocBase.h"
     28 #include "wtf/HashTableDeletedValueType.h"
     29 #include "wtf/PassRefPtr.h"
     30 
     31 namespace WTF {
     32 
     33     template<typename T> class PassRefPtr;
     34 
     35     template<typename T> class RefPtr {
     36         WTF_MAKE_FAST_ALLOCATED;
     37     public:
     38         ALWAYS_INLINE RefPtr() : m_ptr(0) { }
     39         ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); }
     40         ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { refIfNotNull(m_ptr); }
     41         template<typename U> RefPtr(const RefPtr<U>& o, EnsurePtrConvertibleArgDecl(U, T)) : m_ptr(o.get()) { refIfNotNull(m_ptr); }
     42 
     43         // See comments in PassRefPtr.h for an explanation of why this takes a const reference.
     44         template<typename U> RefPtr(const PassRefPtr<U>&, EnsurePtrConvertibleArgDecl(U, T));
     45 
     46         // Hash table deleted values, which are only constructed and never copied or destroyed.
     47         RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
     48         bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
     49 
     50         ALWAYS_INLINE ~RefPtr() { derefIfNotNull(m_ptr); }
     51 
     52         T* get() const { return m_ptr; }
     53 
     54         void clear();
     55         PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; }
     56 
     57         T& operator*() const { return *m_ptr; }
     58         ALWAYS_INLINE T* operator->() const { return m_ptr; }
     59 
     60         bool operator!() const { return !m_ptr; }
     61 
     62         // This conversion operator allows implicit conversion to bool but not to other integer types.
     63         typedef T* (RefPtr::*UnspecifiedBoolType);
     64         operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; }
     65 
     66         RefPtr& operator=(const RefPtr&);
     67         RefPtr& operator=(T*);
     68         RefPtr& operator=(const PassRefPtr<T>&);
     69 #if !COMPILER_SUPPORTS(CXX_NULLPTR)
     70         RefPtr& operator=(std::nullptr_t) { clear(); return *this; }
     71 #endif
     72         template<typename U> EnsurePtrConvertibleType(RefPtr<T>&, U, T) operator=(const RefPtr<U>&);
     73         template<typename U> EnsurePtrConvertibleType(RefPtr<T>&, U, T) operator=(const PassRefPtr<U>&);
     74 
     75         void swap(RefPtr&);
     76 
     77         static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
     78 
     79     private:
     80         T* m_ptr;
     81     };
     82 
     83     template<typename T> template<typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o, EnsurePtrConvertibleArgDefn(U, T))
     84         : m_ptr(o.leakRef())
     85     {
     86     }
     87 
     88     template<typename T> inline void RefPtr<T>::clear()
     89     {
     90         T* ptr = m_ptr;
     91         m_ptr = 0;
     92         derefIfNotNull(ptr);
     93     }
     94 
     95     template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o)
     96     {
     97         T* optr = o.get();
     98         refIfNotNull(optr);
     99         T* ptr = m_ptr;
    100         m_ptr = optr;
    101         derefIfNotNull(ptr);
    102         return *this;
    103     }
    104 
    105     template<typename T> template<typename U> inline EnsurePtrConvertibleType(RefPtr<T>&, U, T) RefPtr<T>::operator=(const RefPtr<U>& o)
    106     {
    107         T* optr = o.get();
    108         refIfNotNull(optr);
    109         T* ptr = m_ptr;
    110         m_ptr = optr;
    111         derefIfNotNull(ptr);
    112         return *this;
    113     }
    114 
    115     template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr)
    116     {
    117         refIfNotNull(optr);
    118         T* ptr = m_ptr;
    119         m_ptr = optr;
    120         derefIfNotNull(ptr);
    121         return *this;
    122     }
    123 
    124     template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>& o)
    125     {
    126         T* ptr = m_ptr;
    127         m_ptr = o.leakRef();
    128         derefIfNotNull(ptr);
    129         return *this;
    130     }
    131 
    132     template<typename T> template<typename U> inline EnsurePtrConvertibleType(RefPtr<T>&, U, T) RefPtr<T>::operator=(const PassRefPtr<U>& o)
    133     {
    134         T* ptr = m_ptr;
    135         m_ptr = o.leakRef();
    136         derefIfNotNull(ptr);
    137         return *this;
    138     }
    139 
    140     template<class T> inline void RefPtr<T>::swap(RefPtr<T>& o)
    141     {
    142         std::swap(m_ptr, o.m_ptr);
    143     }
    144 
    145     template<class T> inline void swap(RefPtr<T>& a, RefPtr<T>& b)
    146     {
    147         a.swap(b);
    148     }
    149 
    150     template<typename T, typename U> inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b)
    151     {
    152         return a.get() == b.get();
    153     }
    154 
    155     template<typename T, typename U> inline bool operator==(const RefPtr<T>& a, U* b)
    156     {
    157         return a.get() == b;
    158     }
    159 
    160     template<typename T, typename U> inline bool operator==(T* a, const RefPtr<U>& b)
    161     {
    162         return a == b.get();
    163     }
    164 
    165     template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b)
    166     {
    167         return a.get() != b.get();
    168     }
    169 
    170     template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, U* b)
    171     {
    172         return a.get() != b;
    173     }
    174 
    175     template<typename T, typename U> inline bool operator!=(T* a, const RefPtr<U>& b)
    176     {
    177         return a != b.get();
    178     }
    179 
    180     template<typename T, typename U> inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p)
    181     {
    182         return RefPtr<T>(static_cast<T*>(p.get()));
    183     }
    184 
    185     template<typename T> inline RefPtr<T> const_pointer_cast(const RefPtr<T>& p)
    186     {
    187         return RefPtr<T>(const_cast<T*>(p.get()));
    188     }
    189 
    190     template<typename T> inline T* getPtr(const RefPtr<T>& p)
    191     {
    192         return p.get();
    193     }
    194 
    195 } // namespace WTF
    196 
    197 using WTF::RefPtr;
    198 using WTF::static_pointer_cast;
    199 using WTF::const_pointer_cast;
    200 
    201 #endif // WTF_RefPtr_h
    202