OLD | NEW |
1 /* | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. | 2 // Use of this source code is governed by a BSD-style license that can be |
3 * All rights reserved. | 3 // found in the LICENSE file. |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Library General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Library General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Library General Public License | |
16 * along with this library; see the file COPYING.LIB. If not, write to | |
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
18 * Boston, MA 02110-1301, USA. | |
19 * | |
20 */ | |
21 | 4 |
22 #ifndef WTF_RefPtr_h | 5 #include "platform/wtf/RefPtr.h" |
23 #define WTF_RefPtr_h | |
24 | 6 |
25 #include "wtf/Allocator.h" | 7 // The contents of this header was moved to platform/wtf as part of |
26 #include "wtf/HashTableDeletedValueType.h" | 8 // WTF migration project. See the following post for details: |
27 #include "wtf/PassRefPtr.h" | 9 // https://groups.google.com/a/chromium.org/d/msg/blink-dev/tLdAZCTlcAA/bYXVT8gY
CAAJ |
28 #include "wtf/allocator/PartitionAllocator.h" | |
29 #include <algorithm> | |
30 #include <utility> | |
31 | |
32 namespace WTF { | |
33 | |
34 template <typename T> | |
35 class PassRefPtr; | |
36 template <typename T> | |
37 class RefPtrValuePeeker; | |
38 | |
39 template <typename T> | |
40 class RefPtr { | |
41 USING_FAST_MALLOC(RefPtr); | |
42 | |
43 public: | |
44 ALWAYS_INLINE RefPtr() : m_ptr(nullptr) {} | |
45 ALWAYS_INLINE RefPtr(std::nullptr_t) : m_ptr(nullptr) {} | |
46 ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } | |
47 ALWAYS_INLINE explicit RefPtr(T& ref) : m_ptr(&ref) { m_ptr->ref(); } | |
48 ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { | |
49 refIfNotNull(m_ptr); | |
50 } | |
51 template <typename U> | |
52 RefPtr(const RefPtr<U>& o, EnsurePtrConvertibleArgDecl(U, T)) | |
53 : m_ptr(o.get()) { | |
54 refIfNotNull(m_ptr); | |
55 } | |
56 RefPtr(RefPtr&& o) : m_ptr(o.m_ptr) { o.m_ptr = nullptr; } | |
57 | |
58 // See comments in PassRefPtr.h for an explanation of why this takes a const | |
59 // reference. | |
60 template <typename U> | |
61 RefPtr(const PassRefPtr<U>&, EnsurePtrConvertibleArgDecl(U, T)); | |
62 | |
63 // Hash table deleted values, which are only constructed and never copied or | |
64 // destroyed. | |
65 RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) {} | |
66 bool isHashTableDeletedValue() const { | |
67 return m_ptr == hashTableDeletedValue(); | |
68 } | |
69 | |
70 ALWAYS_INLINE ~RefPtr() { derefIfNotNull(m_ptr); } | |
71 | |
72 ALWAYS_INLINE T* get() const { return m_ptr; } | |
73 T* leakRef() WARN_UNUSED_RESULT; | |
74 void clear(); | |
75 PassRefPtr<T> release() { | |
76 PassRefPtr<T> tmp = adoptRef(m_ptr); | |
77 m_ptr = nullptr; | |
78 return tmp; | |
79 } | |
80 | |
81 T& operator*() const { return *m_ptr; } | |
82 ALWAYS_INLINE T* operator->() const { return m_ptr; } | |
83 | |
84 bool operator!() const { return !m_ptr; } | |
85 explicit operator bool() const { return m_ptr != nullptr; } | |
86 | |
87 RefPtr& operator=(RefPtr o) { | |
88 swap(o); | |
89 return *this; | |
90 } | |
91 RefPtr& operator=(std::nullptr_t) { | |
92 clear(); | |
93 return *this; | |
94 } | |
95 // This is required by HashMap<RefPtr>>. | |
96 template <typename U> | |
97 RefPtr& operator=(RefPtrValuePeeker<U>); | |
98 | |
99 void swap(RefPtr&); | |
100 | |
101 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } | |
102 | |
103 private: | |
104 T* m_ptr; | |
105 }; | |
106 | |
107 template <typename T> | |
108 template <typename U> | |
109 inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o, | |
110 EnsurePtrConvertibleArgDefn(U, T)) | |
111 : m_ptr(o.leakRef()) {} | |
112 | |
113 template <typename T> | |
114 inline T* RefPtr<T>::leakRef() { | |
115 T* ptr = m_ptr; | |
116 m_ptr = nullptr; | |
117 return ptr; | |
118 } | |
119 | |
120 template <typename T> | |
121 inline void RefPtr<T>::clear() { | |
122 T* ptr = m_ptr; | |
123 m_ptr = nullptr; | |
124 derefIfNotNull(ptr); | |
125 } | |
126 | |
127 template <typename T> | |
128 template <typename U> | |
129 inline RefPtr<T>& RefPtr<T>::operator=(RefPtrValuePeeker<U> optr) { | |
130 RefPtr ptr = static_cast<U*>(optr); | |
131 swap(ptr); | |
132 return *this; | |
133 } | |
134 | |
135 template <class T> | |
136 inline void RefPtr<T>::swap(RefPtr& o) { | |
137 std::swap(m_ptr, o.m_ptr); | |
138 } | |
139 | |
140 template <class T> | |
141 inline void swap(RefPtr<T>& a, RefPtr<T>& b) { | |
142 a.swap(b); | |
143 } | |
144 | |
145 template <typename T, typename U> | |
146 inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b) { | |
147 return a.get() == b.get(); | |
148 } | |
149 | |
150 template <typename T, typename U> | |
151 inline bool operator==(const RefPtr<T>& a, U* b) { | |
152 return a.get() == b; | |
153 } | |
154 | |
155 template <typename T, typename U> | |
156 inline bool operator==(T* a, const RefPtr<U>& b) { | |
157 return a == b.get(); | |
158 } | |
159 | |
160 template <typename T> | |
161 inline bool operator==(const RefPtr<T>& a, std::nullptr_t) { | |
162 return !a.get(); | |
163 } | |
164 | |
165 template <typename T> | |
166 inline bool operator==(std::nullptr_t, const RefPtr<T>& b) { | |
167 return !b.get(); | |
168 } | |
169 | |
170 template <typename T, typename U> | |
171 inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b) { | |
172 return a.get() != b.get(); | |
173 } | |
174 | |
175 template <typename T, typename U> | |
176 inline bool operator!=(const RefPtr<T>& a, U* b) { | |
177 return a.get() != b; | |
178 } | |
179 | |
180 template <typename T, typename U> | |
181 inline bool operator!=(T* a, const RefPtr<U>& b) { | |
182 return a != b.get(); | |
183 } | |
184 | |
185 template <typename T> | |
186 inline bool operator!=(const RefPtr<T>& a, std::nullptr_t) { | |
187 return a.get(); | |
188 } | |
189 | |
190 template <typename T> | |
191 inline bool operator!=(std::nullptr_t, const RefPtr<T>& b) { | |
192 return b.get(); | |
193 } | |
194 | |
195 template <typename T> | |
196 inline T* getPtr(const RefPtr<T>& p) { | |
197 return p.get(); | |
198 } | |
199 | |
200 template <typename T> | |
201 class RefPtrValuePeeker { | |
202 DISALLOW_NEW(); | |
203 | |
204 public: | |
205 ALWAYS_INLINE RefPtrValuePeeker(T* p) : m_ptr(p) {} | |
206 ALWAYS_INLINE RefPtrValuePeeker(std::nullptr_t) : m_ptr(nullptr) {} | |
207 template <typename U> | |
208 RefPtrValuePeeker(const RefPtr<U>& p) : m_ptr(p.get()) {} | |
209 template <typename U> | |
210 RefPtrValuePeeker(const PassRefPtr<U>& p) : m_ptr(p.get()) {} | |
211 | |
212 ALWAYS_INLINE operator T*() const { return m_ptr; } | |
213 | |
214 private: | |
215 T* m_ptr; | |
216 }; | |
217 | |
218 } // namespace WTF | |
219 | |
220 using WTF::RefPtr; | |
221 | |
222 #endif // WTF_RefPtr_h | |
OLD | NEW |