• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (C) 2005, 2006, 2007, 2008 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 #ifndef WTF_RefPtr_h
22 #define WTF_RefPtr_h
23 
24 #include <algorithm>
25 #include "AlwaysInline.h"
26 #include "FastAllocBase.h"
27 
28 namespace WTF {
29 
30     enum PlacementNewAdoptType { PlacementNewAdopt };
31 
32     template <typename T> class PassRefPtr;
33 
34     enum HashTableDeletedValueType { HashTableDeletedValue };
35 
36     template <typename T> class RefPtr : public FastAllocBase {
37     public:
RefPtr()38         RefPtr() : m_ptr(0) { }
RefPtr(T * ptr)39         RefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
RefPtr(const RefPtr & o)40         RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) ptr->ref(); }
41         // see comment in PassRefPtr.h for why this takes const reference
42         template <typename U> RefPtr(const PassRefPtr<U>&);
43 
44         // Special constructor for cases where we overwrite an object in place.
RefPtr(PlacementNewAdoptType)45         RefPtr(PlacementNewAdoptType) { }
46 
47         // Hash table deleted values, which are only constructed and never copied or destroyed.
RefPtr(HashTableDeletedValueType)48         RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
isHashTableDeletedValue()49         bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
50 
~RefPtr()51         ~RefPtr() { if (T* ptr = m_ptr) ptr->deref(); }
52 
RefPtr(const RefPtr<U> & o)53         template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); }
54 
get()55         T* get() const { return m_ptr; }
56 
clear()57         void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; }
release()58         PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; }
59 
60         T& operator*() const { return *m_ptr; }
61         ALWAYS_INLINE T* operator->() const { return m_ptr; }
62 
63         bool operator!() const { return !m_ptr; }
64 
65         // This conversion operator allows implicit conversion to bool but not to other integer types.
66 #if COMPILER(WINSCW)
67         operator bool() const { return m_ptr; }
68 #else
69         typedef T* RefPtr::*UnspecifiedBoolType;
UnspecifiedBoolType()70         operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; }
71 #endif
72 
73         RefPtr& operator=(const RefPtr&);
74         RefPtr& operator=(T*);
75         RefPtr& operator=(const PassRefPtr<T>&);
76         template <typename U> RefPtr& operator=(const RefPtr<U>&);
77         template <typename U> RefPtr& operator=(const PassRefPtr<U>&);
78 
79         void swap(RefPtr&);
80 
81     private:
hashTableDeletedValue()82         static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
83 
84         T* m_ptr;
85     };
86 
RefPtr(const PassRefPtr<U> & o)87     template <typename T> template <typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o)
88         : m_ptr(o.releaseRef())
89     {
90     }
91 
92     template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o)
93     {
94         T* optr = o.get();
95         if (optr)
96             optr->ref();
97         T* ptr = m_ptr;
98         m_ptr = optr;
99         if (ptr)
100             ptr->deref();
101         return *this;
102     }
103 
104     template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o)
105     {
106         T* optr = o.get();
107         if (optr)
108             optr->ref();
109         T* ptr = m_ptr;
110         m_ptr = optr;
111         if (ptr)
112             ptr->deref();
113         return *this;
114     }
115 
116     template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr)
117     {
118         if (optr)
119             optr->ref();
120         T* ptr = m_ptr;
121         m_ptr = optr;
122         if (ptr)
123             ptr->deref();
124         return *this;
125     }
126 
127     template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>& o)
128     {
129         T* ptr = m_ptr;
130         m_ptr = o.releaseRef();
131         if (ptr)
132             ptr->deref();
133         return *this;
134     }
135 
136     template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<U>& o)
137     {
138         T* ptr = m_ptr;
139         m_ptr = o.releaseRef();
140         if (ptr)
141             ptr->deref();
142         return *this;
143     }
144 
swap(RefPtr<T> & o)145     template <class T> inline void RefPtr<T>::swap(RefPtr<T>& o)
146     {
147         std::swap(m_ptr, o.m_ptr);
148     }
149 
swap(RefPtr<T> & a,RefPtr<T> & b)150     template <class T> inline void swap(RefPtr<T>& a, RefPtr<T>& b)
151     {
152         a.swap(b);
153     }
154 
155     template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b)
156     {
157         return a.get() == b.get();
158     }
159 
160     template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, U* b)
161     {
162         return a.get() == b;
163     }
164 
165     template <typename T, typename U> inline bool operator==(T* a, const RefPtr<U>& b)
166     {
167         return a == b.get();
168     }
169 
170     template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b)
171     {
172         return a.get() != b.get();
173     }
174 
175     template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, U* b)
176     {
177         return a.get() != b;
178     }
179 
180     template <typename T, typename U> inline bool operator!=(T* a, const RefPtr<U>& b)
181     {
182         return a != b.get();
183     }
184 
static_pointer_cast(const RefPtr<U> & p)185     template <typename T, typename U> inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p)
186     {
187         return RefPtr<T>(static_cast<T*>(p.get()));
188     }
189 
const_pointer_cast(const RefPtr<U> & p)190     template <typename T, typename U> inline RefPtr<T> const_pointer_cast(const RefPtr<U>& p)
191     {
192         return RefPtr<T>(const_cast<T*>(p.get()));
193     }
194 
getPtr(const RefPtr<T> & p)195     template <typename T> inline T* getPtr(const RefPtr<T>& p)
196     {
197         return p.get();
198     }
199 
200 } // namespace WTF
201 
202 using WTF::RefPtr;
203 using WTF::static_pointer_cast;
204 using WTF::const_pointer_cast;
205 
206 #endif // WTF_RefPtr_h
207