File indexing completed on 2024-05-12 15:43:39
0001 /* 0002 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Library General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2 of the License, or (at your option) any later version. 0008 * 0009 * This library is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 * Library General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU Library General Public License 0015 * along with this library; see the file COPYING.LIB. If not, write to 0016 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 * Boston, MA 02110-1301, USA. 0018 * 0019 */ 0020 0021 #ifndef WTF_RefPtr_h 0022 #define WTF_RefPtr_h 0023 0024 #include <algorithm> 0025 #include <wtf/AlwaysInline.h> 0026 #include <wtf/PassRefPtr.h> 0027 0028 namespace WTF 0029 { 0030 0031 enum PlacementNewAdoptType { PlacementNewAdopt }; 0032 0033 template <typename T> class PassRefPtr; 0034 0035 enum HashTableDeletedValueType { HashTableDeletedValue }; 0036 0037 template <typename T> class RefPtr 0038 { 0039 public: 0040 RefPtr() : m_ptr(nullptr) { } 0041 RefPtr(T *ptr) : m_ptr(ptr) 0042 { 0043 if (ptr) { 0044 ptr->ref(); 0045 } 0046 } 0047 RefPtr(const RefPtr &o) : m_ptr(o.m_ptr) 0048 { 0049 if (T *ptr = m_ptr) { 0050 ptr->ref(); 0051 } 0052 } 0053 // see comment in PassRefPtr.h for why this takes const reference 0054 template <typename U> RefPtr(const PassRefPtr<U> &); 0055 0056 // Special constructor for cases where we overwrite an object in place. 0057 RefPtr(PlacementNewAdoptType) { } 0058 0059 // Hash table deleted values, which are only constructed and never copied or destroyed. 0060 RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { } 0061 bool isHashTableDeletedValue() const 0062 { 0063 return m_ptr == hashTableDeletedValue(); 0064 } 0065 0066 ~RefPtr() 0067 { 0068 if (T *ptr = m_ptr) { 0069 ptr->deref(); 0070 } 0071 } 0072 0073 template <typename U> RefPtr(const RefPtr<U> &o) : m_ptr(o.get()) 0074 { 0075 if (T *ptr = m_ptr) { 0076 ptr->ref(); 0077 } 0078 } 0079 0080 T *get() const 0081 { 0082 return m_ptr; 0083 } 0084 0085 void clear() 0086 { 0087 if (T *ptr = m_ptr) { 0088 ptr->deref(); 0089 } m_ptr = nullptr; 0090 } 0091 PassRefPtr<T> release() 0092 { 0093 PassRefPtr<T> tmp = adoptRef(m_ptr); 0094 m_ptr = nullptr; 0095 return tmp; 0096 } 0097 0098 T &operator*() const 0099 { 0100 return *m_ptr; 0101 } 0102 ALWAYS_INLINE T *operator->() const 0103 { 0104 return m_ptr; 0105 } 0106 0107 bool operator!() const 0108 { 0109 return !m_ptr; 0110 } 0111 0112 // This conversion operator allows implicit conversion to bool but not to other integer types. 0113 typedef T *RefPtr::*UnspecifiedBoolType; 0114 operator UnspecifiedBoolType() const 0115 { 0116 return m_ptr ? &RefPtr::m_ptr : nullptr; 0117 } 0118 0119 RefPtr &operator=(const RefPtr &); 0120 RefPtr &operator=(T *); 0121 RefPtr &operator=(const PassRefPtr<T> &); 0122 template <typename U> RefPtr &operator=(const RefPtr<U> &); 0123 template <typename U> RefPtr &operator=(const PassRefPtr<U> &); 0124 0125 void swap(RefPtr &); 0126 0127 private: 0128 static T *hashTableDeletedValue() 0129 { 0130 return reinterpret_cast<T *>(-1); 0131 } 0132 0133 T *m_ptr; 0134 }; 0135 0136 template <typename T> template <typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U> &o) 0137 : m_ptr(o.releaseRef()) 0138 { 0139 } 0140 0141 template <typename T> inline RefPtr<T> &RefPtr<T>::operator=(const RefPtr<T> &o) 0142 { 0143 T *optr = o.get(); 0144 if (optr) { 0145 optr->ref(); 0146 } 0147 T *ptr = m_ptr; 0148 m_ptr = optr; 0149 if (ptr) { 0150 ptr->deref(); 0151 } 0152 return *this; 0153 } 0154 0155 template <typename T> template <typename U> inline RefPtr<T> &RefPtr<T>::operator=(const RefPtr<U> &o) 0156 { 0157 T *optr = o.get(); 0158 if (optr) { 0159 optr->ref(); 0160 } 0161 T *ptr = m_ptr; 0162 m_ptr = optr; 0163 if (ptr) { 0164 ptr->deref(); 0165 } 0166 return *this; 0167 } 0168 0169 template <typename T> inline RefPtr<T> &RefPtr<T>::operator=(T *optr) 0170 { 0171 if (optr) { 0172 optr->ref(); 0173 } 0174 T *ptr = m_ptr; 0175 m_ptr = optr; 0176 if (ptr) { 0177 ptr->deref(); 0178 } 0179 return *this; 0180 } 0181 0182 template <typename T> inline RefPtr<T> &RefPtr<T>::operator=(const PassRefPtr<T> &o) 0183 { 0184 T *ptr = m_ptr; 0185 m_ptr = o.releaseRef(); 0186 if (ptr) { 0187 ptr->deref(); 0188 } 0189 return *this; 0190 } 0191 0192 template <typename T> template <typename U> inline RefPtr<T> &RefPtr<T>::operator=(const PassRefPtr<U> &o) 0193 { 0194 T *ptr = m_ptr; 0195 m_ptr = o.releaseRef(); 0196 if (ptr) { 0197 ptr->deref(); 0198 } 0199 return *this; 0200 } 0201 0202 template <class T> inline void RefPtr<T>::swap(RefPtr<T> &o) 0203 { 0204 std::swap(m_ptr, o.m_ptr); 0205 } 0206 0207 template <class T> inline void swap(RefPtr<T> &a, RefPtr<T> &b) 0208 { 0209 a.swap(b); 0210 } 0211 0212 template <typename T, typename U> inline bool operator==(const RefPtr<T> &a, const RefPtr<U> &b) 0213 { 0214 return a.get() == b.get(); 0215 } 0216 0217 template <typename T, typename U> inline bool operator==(const RefPtr<T> &a, U *b) 0218 { 0219 return a.get() == b; 0220 } 0221 0222 template <typename T, typename U> inline bool operator==(T *a, const RefPtr<U> &b) 0223 { 0224 return a == b.get(); 0225 } 0226 0227 template <typename T, typename U> inline bool operator!=(const RefPtr<T> &a, const RefPtr<U> &b) 0228 { 0229 return a.get() != b.get(); 0230 } 0231 0232 template <typename T, typename U> inline bool operator!=(const RefPtr<T> &a, U *b) 0233 { 0234 return a.get() != b; 0235 } 0236 0237 template <typename T, typename U> inline bool operator!=(T *a, const RefPtr<U> &b) 0238 { 0239 return a != b.get(); 0240 } 0241 0242 template <typename T, typename U> inline RefPtr<T> static_pointer_cast(const RefPtr<U> &p) 0243 { 0244 return RefPtr<T>(static_cast<T *>(p.get())); 0245 } 0246 0247 template <typename T, typename U> inline RefPtr<T> const_pointer_cast(const RefPtr<U> &p) 0248 { 0249 return RefPtr<T>(const_cast<T *>(p.get())); 0250 } 0251 0252 template <typename T> inline T *getPtr(const RefPtr<T> &p) 0253 { 0254 return p.get(); 0255 } 0256 0257 } // namespace WTF 0258 0259 using WTF::RefPtr; 0260 using WTF::static_pointer_cast; 0261 using WTF::const_pointer_cast; 0262 0263 #endif // WTF_RefPtr_h