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