1 /* 2 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013 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 // RefPtr and PassRefPtr are documented at http://webkit.org/coding/RefPtr.html 22 23 #ifndef WTF_RefPtr_h 24 #define WTF_RefPtr_h 25 26 #include <algorithm> 27 #include "wtf/HashTableDeletedValueType.h" 28 #include "wtf/PassRefPtr.h" 29 30 namespace WTF { 31 32 template<typename T> class PassRefPtr; 33 34 template<typename T> class RefPtr { 35 public: 36 ALWAYS_INLINE RefPtr() : m_ptr(0) { } 37 ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } 38 ALWAYS_INLINE explicit RefPtr(T& ref) : m_ptr(&ref) { m_ptr->ref(); } 39 ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { refIfNotNull(m_ptr); } 40 template<typename U> RefPtr(const RefPtr<U>& o, EnsurePtrConvertibleArgDecl(U, T)) : m_ptr(o.get()) { refIfNotNull(m_ptr); } 41 42 // See comments in PassRefPtr.h for an explanation of why this takes a const reference. 43 template<typename U> RefPtr(const PassRefPtr<U>&, EnsurePtrConvertibleArgDecl(U, T)); 44 45 // Hash table deleted values, which are only constructed and never copied or destroyed. 46 RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { } 47 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); } 48 49 ALWAYS_INLINE ~RefPtr() { derefIfNotNull(m_ptr); } 50 51 T* get() const { return m_ptr; } 52 53 void clear(); 54 PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; } 55 56 T& operator*() const { return *m_ptr; } 57 ALWAYS_INLINE T* operator->() const { return m_ptr; } 58 59 bool operator!() const { return !m_ptr; } 60 61 // This conversion operator allows implicit conversion to bool but not to other integer types. 62 typedef T* (RefPtr::*UnspecifiedBoolType); 63 operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; } 64 65 RefPtr& operator=(const RefPtr&); 66 RefPtr& operator=(T*); 67 RefPtr& operator=(const PassRefPtr<T>&); 68 #if !COMPILER_SUPPORTS(CXX_NULLPTR) 69 RefPtr& operator=(std::nullptr_t) { clear(); return *this; } 70 #endif 71 template<typename U> RefPtr<T>& operator=(const RefPtr<U>&); 72 template<typename U> RefPtr<T>& operator=(const PassRefPtr<U>&); 73 74 void swap(RefPtr&); 75 76 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } 77 78 private: 79 T* m_ptr; 80 }; 81 82 template<typename T> template<typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o, EnsurePtrConvertibleArgDefn(U, T)) 83 : m_ptr(o.leakRef()) 84 { 85 } 86 87 template<typename T> inline void RefPtr<T>::clear() 88 { 89 T* ptr = m_ptr; 90 m_ptr = 0; 91 derefIfNotNull(ptr); 92 } 93 94 template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr& o) 95 { 96 RefPtr ptr = o; 97 swap(ptr); 98 return *this; 99 } 100 101 template<typename T> template<typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o) 102 { 103 RefPtr ptr = o; 104 swap(ptr); 105 return *this; 106 } 107 108 template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr) 109 { 110 RefPtr ptr = optr; 111 swap(ptr); 112 return *this; 113 } 114 115 template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>& o) 116 { 117 RefPtr ptr = o; 118 swap(ptr); 119 return *this; 120 } 121 122 template<typename T> template<typename U> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<U>& o) 123 { 124 RefPtr ptr = o; 125 swap(ptr); 126 return *this; 127 } 128 129 template<class T> inline void RefPtr<T>::swap(RefPtr& o) 130 { 131 std::swap(m_ptr, o.m_ptr); 132 } 133 134 template<class T> inline void swap(RefPtr<T>& a, RefPtr<T>& b) 135 { 136 a.swap(b); 137 } 138 139 template<typename T, typename U> inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b) 140 { 141 return a.get() == b.get(); 142 } 143 144 template<typename T, typename U> inline bool operator==(const RefPtr<T>& a, U* b) 145 { 146 return a.get() == b; 147 } 148 149 template<typename T, typename U> inline bool operator==(T* a, const RefPtr<U>& b) 150 { 151 return a == b.get(); 152 } 153 154 template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b) 155 { 156 return a.get() != b.get(); 157 } 158 159 template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, U* b) 160 { 161 return a.get() != b; 162 } 163 164 template<typename T, typename U> inline bool operator!=(T* a, const RefPtr<U>& b) 165 { 166 return a != b.get(); 167 } 168 169 template<typename T, typename U> inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p) 170 { 171 return RefPtr<T>(static_cast<T*>(p.get())); 172 } 173 174 template<typename T> inline T* getPtr(const RefPtr<T>& p) 175 { 176 return p.get(); 177 } 178 179 } // namespace WTF 180 181 using WTF::RefPtr; 182 using WTF::static_pointer_cast; 183 184 #endif // WTF_RefPtr_h 185