• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (C) 2005, 2006, 2007 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_PassRefPtr_h
22 #define WTF_PassRefPtr_h
23 
24 #include "AlwaysInline.h"
25 
26 namespace WTF {
27 
28     template<typename T> class RefPtr;
29     template<typename T> class PassRefPtr;
30     template <typename T> PassRefPtr<T> adoptRef(T*);
31 
32     template<typename T> class PassRefPtr {
33     public:
PassRefPtr()34         PassRefPtr() : m_ptr(0) {}
PassRefPtr(T * ptr)35         PassRefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
36         // It somewhat breaks the type system to allow transfer of ownership out of
37         // a const PassRefPtr. However, it makes it much easier to work with PassRefPtr
38         // temporaries, and we don't really have a need to use real const PassRefPtrs
39         // anyway.
PassRefPtr(const PassRefPtr & o)40         PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef()) {}
PassRefPtr(const PassRefPtr<U> & o)41         template <typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { }
42 
~PassRefPtr()43         ALWAYS_INLINE ~PassRefPtr() { if (UNLIKELY(m_ptr != 0)) m_ptr->deref(); }
44 
45         template <class U>
PassRefPtr(const RefPtr<U> & o)46         PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); }
47 
get()48         T* get() const { return m_ptr; }
49 
clear()50         void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; }
releaseRef()51         T* releaseRef() const { T* tmp = m_ptr; m_ptr = 0; return tmp; }
52 
53         T& operator*() const { return *m_ptr; }
54         T* operator->() const { return m_ptr; }
55 
56         bool operator!() const { return !m_ptr; }
57 
58         // This conversion operator allows implicit conversion to bool but not to other integer types.
59 #if COMPILER(WINSCW)
60         operator bool() const { return m_ptr; }
61 #else
62         typedef T* PassRefPtr::*UnspecifiedBoolType;
UnspecifiedBoolType()63         operator UnspecifiedBoolType() const { return m_ptr ? &PassRefPtr::m_ptr : 0; }
64 #endif
65         PassRefPtr& operator=(T*);
66         PassRefPtr& operator=(const PassRefPtr&);
67         template <typename U> PassRefPtr& operator=(const PassRefPtr<U>&);
68         template <typename U> PassRefPtr& operator=(const RefPtr<U>&);
69 
70         friend PassRefPtr adoptRef<T>(T*);
71     private:
72         // adopting constructor
PassRefPtr(T * ptr,bool)73         PassRefPtr(T* ptr, bool) : m_ptr(ptr) {}
74         mutable T* m_ptr;
75     };
76 
77     template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<U>& o)
78     {
79         T* optr = o.get();
80         if (optr)
81             optr->ref();
82         T* ptr = m_ptr;
83         m_ptr = optr;
84         if (ptr)
85             ptr->deref();
86         return *this;
87     }
88 
89     template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(T* optr)
90     {
91         if (optr)
92             optr->ref();
93         T* ptr = m_ptr;
94         m_ptr = optr;
95         if (ptr)
96             ptr->deref();
97         return *this;
98     }
99 
100     template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<T>& ref)
101     {
102         T* ptr = m_ptr;
103         m_ptr = ref.releaseRef();
104         if (ptr)
105             ptr->deref();
106         return *this;
107     }
108 
109     template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<U>& ref)
110     {
111         T* ptr = m_ptr;
112         m_ptr = ref.releaseRef();
113         if (ptr)
114             ptr->deref();
115         return *this;
116     }
117 
118     template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const PassRefPtr<U>& b)
119     {
120         return a.get() == b.get();
121     }
122 
123     template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const RefPtr<U>& b)
124     {
125         return a.get() == b.get();
126     }
127 
128     template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, const PassRefPtr<U>& b)
129     {
130         return a.get() == b.get();
131     }
132 
133     template <typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, U* b)
134     {
135         return a.get() == b;
136     }
137 
138     template <typename T, typename U> inline bool operator==(T* a, const PassRefPtr<U>& b)
139     {
140         return a == b.get();
141     }
142 
143     template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const PassRefPtr<U>& b)
144     {
145         return a.get() != b.get();
146     }
147 
148     template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const RefPtr<U>& b)
149     {
150         return a.get() != b.get();
151     }
152 
153     template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const PassRefPtr<U>& b)
154     {
155         return a.get() != b.get();
156     }
157 
158     template <typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, U* b)
159     {
160         return a.get() != b;
161     }
162 
163     template <typename T, typename U> inline bool operator!=(T* a, const PassRefPtr<U>& b)
164     {
165         return a != b.get();
166     }
167 
adoptRef(T * p)168     template <typename T> inline PassRefPtr<T> adoptRef(T* p)
169     {
170         return PassRefPtr<T>(p, true);
171     }
172 
static_pointer_cast(const PassRefPtr<U> & p)173     template <typename T, typename U> inline PassRefPtr<T> static_pointer_cast(const PassRefPtr<U>& p)
174     {
175         return adoptRef(static_cast<T*>(p.releaseRef()));
176     }
177 
const_pointer_cast(const PassRefPtr<U> & p)178     template <typename T, typename U> inline PassRefPtr<T> const_pointer_cast(const PassRefPtr<U>& p)
179     {
180         return adoptRef(const_cast<T*>(p.releaseRef()));
181     }
182 
getPtr(const PassRefPtr<T> & p)183     template <typename T> inline T* getPtr(const PassRefPtr<T>& p)
184     {
185         return p.get();
186     }
187 
188 } // namespace WTF
189 
190 using WTF::PassRefPtr;
191 using WTF::adoptRef;
192 using WTF::static_pointer_cast;
193 using WTF::const_pointer_cast;
194 
195 #endif // WTF_PassRefPtr_h
196