File indexing completed on 2024-05-12 15:43:39
0001 /* 0002 * Copyright (C) 2005, 2006, 2007 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_PassRefPtr_h 0022 #define WTF_PassRefPtr_h 0023 0024 #include <wtf/AlwaysInline.h> 0025 0026 namespace WTF 0027 { 0028 0029 template<typename T> class RefPtr; 0030 template<typename T> class PassRefPtr; 0031 template <typename T> PassRefPtr<T> adoptRef(T *); 0032 0033 template<typename T> class PassRefPtr 0034 { 0035 public: 0036 PassRefPtr() : m_ptr(nullptr) {} 0037 PassRefPtr(T *ptr) : m_ptr(ptr) 0038 { 0039 if (ptr) { 0040 ptr->ref(); 0041 } 0042 } 0043 // It somewhat breaks the type system to allow transfer of ownership out of 0044 // a const PassRefPtr. However, it makes it much easier to work with PassRefPtr 0045 // temporaries, and we don't really have a need to use real const PassRefPtrs 0046 // anyway. 0047 PassRefPtr(const PassRefPtr &o) : m_ptr(o.releaseRef()) {} 0048 template <typename U> PassRefPtr(const PassRefPtr<U> &o) : m_ptr(o.releaseRef()) { } 0049 0050 ALWAYS_INLINE ~PassRefPtr() 0051 { 0052 if (T *ptr = m_ptr) { 0053 ptr->deref(); 0054 } 0055 } 0056 0057 template <class U> 0058 PassRefPtr(const RefPtr<U> &o) : m_ptr(o.get()) 0059 { 0060 if (T *ptr = m_ptr) { 0061 ptr->ref(); 0062 } 0063 } 0064 0065 T *get() const 0066 { 0067 return m_ptr; 0068 } 0069 0070 void clear() 0071 { 0072 if (T *ptr = m_ptr) { 0073 ptr->deref(); 0074 } m_ptr = nullptr; 0075 } 0076 T *releaseRef() const 0077 { 0078 T *tmp = m_ptr; 0079 m_ptr = nullptr; 0080 return tmp; 0081 } 0082 0083 T &operator*() const 0084 { 0085 return *m_ptr; 0086 } 0087 T *operator->() const 0088 { 0089 return m_ptr; 0090 } 0091 0092 bool operator!() const 0093 { 0094 return !m_ptr; 0095 } 0096 0097 // This conversion operator allows implicit conversion to bool but not to other integer types. 0098 typedef T *PassRefPtr::*UnspecifiedBoolType; 0099 operator UnspecifiedBoolType() const 0100 { 0101 return m_ptr ? &PassRefPtr::m_ptr : nullptr; 0102 } 0103 0104 PassRefPtr &operator=(T *); 0105 PassRefPtr &operator=(const PassRefPtr &); 0106 template <typename U> PassRefPtr &operator=(const PassRefPtr<U> &); 0107 template <typename U> PassRefPtr &operator=(const RefPtr<U> &); 0108 0109 friend PassRefPtr adoptRef<T>(T *); 0110 private: 0111 // adopting constructor 0112 PassRefPtr(T *ptr, bool) : m_ptr(ptr) {} 0113 mutable T *m_ptr; 0114 }; 0115 0116 template <typename T> template <typename U> inline PassRefPtr<T> &PassRefPtr<T>::operator=(const RefPtr<U> &o) 0117 { 0118 T *optr = o.get(); 0119 if (optr) { 0120 optr->ref(); 0121 } 0122 T *ptr = m_ptr; 0123 m_ptr = optr; 0124 if (ptr) { 0125 ptr->deref(); 0126 } 0127 return *this; 0128 } 0129 0130 template <typename T> inline PassRefPtr<T> &PassRefPtr<T>::operator=(T *optr) 0131 { 0132 if (optr) { 0133 optr->ref(); 0134 } 0135 T *ptr = m_ptr; 0136 m_ptr = optr; 0137 if (ptr) { 0138 ptr->deref(); 0139 } 0140 return *this; 0141 } 0142 0143 template <typename T> inline PassRefPtr<T> &PassRefPtr<T>::operator=(const PassRefPtr<T> &ref) 0144 { 0145 T *ptr = m_ptr; 0146 m_ptr = ref.releaseRef(); 0147 if (ptr) { 0148 ptr->deref(); 0149 } 0150 return *this; 0151 } 0152 0153 template <typename T> template <typename U> inline PassRefPtr<T> &PassRefPtr<T>::operator=(const PassRefPtr<U> &ref) 0154 { 0155 T *ptr = m_ptr; 0156 m_ptr = ref.releaseRef(); 0157 if (ptr) { 0158 ptr->deref(); 0159 } 0160 return *this; 0161 } 0162 0163 template <typename T, typename U> inline bool operator==(const PassRefPtr<T> &a, const PassRefPtr<U> &b) 0164 { 0165 return a.get() == b.get(); 0166 } 0167 0168 template <typename T, typename U> inline bool operator==(const PassRefPtr<T> &a, const RefPtr<U> &b) 0169 { 0170 return a.get() == b.get(); 0171 } 0172 0173 template <typename T, typename U> inline bool operator==(const RefPtr<T> &a, const PassRefPtr<U> &b) 0174 { 0175 return a.get() == b.get(); 0176 } 0177 0178 template <typename T, typename U> inline bool operator==(const PassRefPtr<T> &a, U *b) 0179 { 0180 return a.get() == b; 0181 } 0182 0183 template <typename T, typename U> inline bool operator==(T *a, const PassRefPtr<U> &b) 0184 { 0185 return a == b.get(); 0186 } 0187 0188 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T> &a, const PassRefPtr<U> &b) 0189 { 0190 return a.get() != b.get(); 0191 } 0192 0193 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T> &a, const RefPtr<U> &b) 0194 { 0195 return a.get() != b.get(); 0196 } 0197 0198 template <typename T, typename U> inline bool operator!=(const RefPtr<T> &a, const PassRefPtr<U> &b) 0199 { 0200 return a.get() != b.get(); 0201 } 0202 0203 template <typename T, typename U> inline bool operator!=(const PassRefPtr<T> &a, U *b) 0204 { 0205 return a.get() != b; 0206 } 0207 0208 template <typename T, typename U> inline bool operator!=(T *a, const PassRefPtr<U> &b) 0209 { 0210 return a != b.get(); 0211 } 0212 0213 template <typename T> inline PassRefPtr<T> adoptRef(T *p) 0214 { 0215 return PassRefPtr<T>(p, true); 0216 } 0217 0218 template <typename T, typename U> inline PassRefPtr<T> static_pointer_cast(const PassRefPtr<U> &p) 0219 { 0220 return adoptRef(static_cast<T *>(p.releaseRef())); 0221 } 0222 0223 template <typename T, typename U> inline PassRefPtr<T> const_pointer_cast(const PassRefPtr<U> &p) 0224 { 0225 return adoptRef(const_cast<T *>(p.releaseRef())); 0226 } 0227 0228 template <typename T> inline T *getPtr(const PassRefPtr<T> &p) 0229 { 0230 return p.get(); 0231 } 0232 0233 } // namespace WTF 0234 0235 using WTF::PassRefPtr; 0236 using WTF::adoptRef; 0237 using WTF::static_pointer_cast; 0238 using WTF::const_pointer_cast; 0239 0240 #endif // WTF_PassRefPtr_h