OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reser
ved. | |
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 <wtf/Assertions.h> | |
25 #include <wtf/NullPtr.h> | |
26 | |
27 namespace WTF { | |
28 | |
29 template<typename T> class RefPtr; | |
30 template<typename T> class PassRefPtr; | |
31 template<typename T> PassRefPtr<T> adoptRef(T*); | |
32 | |
33 inline void adopted(const void*) { } | |
34 | |
35 template<typename T> ALWAYS_INLINE void refIfNotNull(T* ptr) | |
36 { | |
37 if (LIKELY(ptr != 0)) | |
38 ptr->ref(); | |
39 } | |
40 | |
41 template<typename T> ALWAYS_INLINE void derefIfNotNull(T* ptr) | |
42 { | |
43 if (LIKELY(ptr != 0)) | |
44 ptr->deref(); | |
45 } | |
46 | |
47 template<typename T> class PassRefPtr { | |
48 public: | |
49 PassRefPtr() : m_ptr(0) { } | |
50 PassRefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } | |
51 // It somewhat breaks the type system to allow transfer of ownership out
of | |
52 // a const PassRefPtr. However, it makes it much easier to work with Pas
sRefPtr | |
53 // temporaries, and we don't have a need to use real const PassRefPtrs a
nyway. | |
54 PassRefPtr(const PassRefPtr& o) : m_ptr(o.leakRef()) { } | |
55 template<typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.leakRe
f()) { } | |
56 | |
57 ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull(m_ptr); } | |
58 | |
59 template<typename U> PassRefPtr(const RefPtr<U>&); | |
60 | |
61 T* get() const { return m_ptr; } | |
62 | |
63 T* leakRef() const WARN_UNUSED_RETURN; | |
64 | |
65 T& operator*() const { return *m_ptr; } | |
66 T* operator->() const { return m_ptr; } | |
67 | |
68 bool operator!() const { return !m_ptr; } | |
69 | |
70 // This conversion operator allows implicit conversion to bool but not t
o other integer types. | |
71 typedef T* (PassRefPtr::*UnspecifiedBoolType); | |
72 operator UnspecifiedBoolType() const { return m_ptr ? &PassRefPtr::m_ptr
: 0; } | |
73 | |
74 PassRefPtr& operator=(const PassRefPtr&) { COMPILE_ASSERT(!sizeof(T*), P
assRefPtr_should_never_be_assigned_to); return *this; } | |
75 | |
76 friend PassRefPtr adoptRef<T>(T*); | |
77 | |
78 private: | |
79 // adopting constructor | |
80 PassRefPtr(T* ptr, bool) : m_ptr(ptr) { } | |
81 | |
82 mutable T* m_ptr; | |
83 }; | |
84 | |
85 template<typename T> template<typename U> inline PassRefPtr<T>::PassRefPtr(c
onst RefPtr<U>& o) | |
86 : m_ptr(o.get()) | |
87 { | |
88 T* ptr = m_ptr; | |
89 refIfNotNull(ptr); | |
90 } | |
91 | |
92 template<typename T> inline T* PassRefPtr<T>::leakRef() const | |
93 { | |
94 T* ptr = m_ptr; | |
95 m_ptr = 0; | |
96 return ptr; | |
97 } | |
98 | |
99 template<typename T, typename U> inline bool operator==(const PassRefPtr<T>&
a, const PassRefPtr<U>& b) | |
100 { | |
101 return a.get() == b.get(); | |
102 } | |
103 | |
104 template<typename T, typename U> inline bool operator==(const PassRefPtr<T>&
a, const RefPtr<U>& b) | |
105 { | |
106 return a.get() == b.get(); | |
107 } | |
108 | |
109 template<typename T, typename U> inline bool operator==(const RefPtr<T>& a,
const PassRefPtr<U>& b) | |
110 { | |
111 return a.get() == b.get(); | |
112 } | |
113 | |
114 template<typename T, typename U> inline bool operator==(const PassRefPtr<T>&
a, U* b) | |
115 { | |
116 return a.get() == b; | |
117 } | |
118 | |
119 template<typename T, typename U> inline bool operator==(T* a, const PassRefP
tr<U>& b) | |
120 { | |
121 return a == b.get(); | |
122 } | |
123 | |
124 template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>&
a, const PassRefPtr<U>& b) | |
125 { | |
126 return a.get() != b.get(); | |
127 } | |
128 | |
129 template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>&
a, const RefPtr<U>& b) | |
130 { | |
131 return a.get() != b.get(); | |
132 } | |
133 | |
134 template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a,
const PassRefPtr<U>& b) | |
135 { | |
136 return a.get() != b.get(); | |
137 } | |
138 | |
139 template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>&
a, U* b) | |
140 { | |
141 return a.get() != b; | |
142 } | |
143 | |
144 template<typename T, typename U> inline bool operator!=(T* a, const PassRefP
tr<U>& b) | |
145 { | |
146 return a != b.get(); | |
147 } | |
148 | |
149 template<typename T> inline PassRefPtr<T> adoptRef(T* p) | |
150 { | |
151 adopted(p); | |
152 return PassRefPtr<T>(p, true); | |
153 } | |
154 | |
155 template<typename T, typename U> inline PassRefPtr<T> static_pointer_cast(co
nst PassRefPtr<U>& p) | |
156 { | |
157 return adoptRef(static_cast<T*>(p.leakRef())); | |
158 } | |
159 | |
160 template<typename T, typename U> inline PassRefPtr<T> const_pointer_cast(con
st PassRefPtr<U>& p) | |
161 { | |
162 return adoptRef(const_cast<T*>(p.leakRef())); | |
163 } | |
164 | |
165 template<typename T> inline T* getPtr(const PassRefPtr<T>& p) | |
166 { | |
167 return p.get(); | |
168 } | |
169 | |
170 } // namespace WTF | |
171 | |
172 using WTF::PassRefPtr; | |
173 using WTF::adoptRef; | |
174 using WTF::static_pointer_cast; | |
175 using WTF::const_pointer_cast; | |
176 | |
177 #endif // WTF_PassRefPtr_h | |
OLD | NEW |