WTF
RefPtr.h
Go to the documentation of this file.
00001 // -*- mode: c++; c-basic-offset: 4 -*- 00002 /* 00003 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Library General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Library General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Library General Public License 00016 * along with this library; see the file COPYING.LIB. If not, write to 00017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 * Boston, MA 02110-1301, USA. 00019 * 00020 */ 00021 00022 #ifndef WTF_RefPtr_h 00023 #define WTF_RefPtr_h 00024 00025 #include <algorithm> 00026 #include "AlwaysInline.h" 00027 00028 namespace WTF { 00029 00030 enum PlacementNewAdoptType { PlacementNewAdopt }; 00031 00032 template <typename T> class PassRefPtr; 00033 00034 enum HashTableDeletedValueType { HashTableDeletedValue }; 00035 00036 template <typename T> class RefPtr { 00037 public: 00038 RefPtr() : m_ptr(0) { } 00039 RefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); } 00040 RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) ptr->ref(); } 00041 // see comment in PassRefPtr.h for why this takes const reference 00042 template <typename U> RefPtr(const PassRefPtr<U>&); 00043 00044 // Special constructor for cases where we overwrite an object in place. 00045 RefPtr(PlacementNewAdoptType) { } 00046 00047 // Hash table deleted values, which are only constructed and never copied or destroyed. 00048 RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { } 00049 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); } 00050 00051 ~RefPtr() { if (T* ptr = m_ptr) ptr->deref(); } 00052 00053 template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); } 00054 00055 T* get() const { return m_ptr; } 00056 00057 void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; } 00058 PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; } 00059 00060 T& operator*() const { return *m_ptr; } 00061 ALWAYS_INLINE T* operator->() const { return m_ptr; } 00062 00063 bool operator!() const { return !m_ptr; } 00064 00065 // This conversion operator allows implicit conversion to bool but not to other integer types. 00066 typedef T* RefPtr::*UnspecifiedBoolType; 00067 operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; } 00068 00069 RefPtr& operator=(const RefPtr&); 00070 RefPtr& operator=(T*); 00071 RefPtr& operator=(const PassRefPtr<T>&); 00072 template <typename U> RefPtr& operator=(const RefPtr<U>&); 00073 template <typename U> RefPtr& operator=(const PassRefPtr<U>&); 00074 00075 void swap(RefPtr&); 00076 00077 private: 00078 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } 00079 00080 T* m_ptr; 00081 }; 00082 00083 template <typename T> template <typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o) 00084 : m_ptr(o.releaseRef()) 00085 { 00086 } 00087 00088 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o) 00089 { 00090 T* optr = o.get(); 00091 if (optr) 00092 optr->ref(); 00093 T* ptr = m_ptr; 00094 m_ptr = optr; 00095 if (ptr) 00096 ptr->deref(); 00097 return *this; 00098 } 00099 00100 template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o) 00101 { 00102 T* optr = o.get(); 00103 if (optr) 00104 optr->ref(); 00105 T* ptr = m_ptr; 00106 m_ptr = optr; 00107 if (ptr) 00108 ptr->deref(); 00109 return *this; 00110 } 00111 00112 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr) 00113 { 00114 if (optr) 00115 optr->ref(); 00116 T* ptr = m_ptr; 00117 m_ptr = optr; 00118 if (ptr) 00119 ptr->deref(); 00120 return *this; 00121 } 00122 00123 template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>& o) 00124 { 00125 T* ptr = m_ptr; 00126 m_ptr = o.releaseRef(); 00127 if (ptr) 00128 ptr->deref(); 00129 return *this; 00130 } 00131 00132 template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<U>& o) 00133 { 00134 T* ptr = m_ptr; 00135 m_ptr = o.releaseRef(); 00136 if (ptr) 00137 ptr->deref(); 00138 return *this; 00139 } 00140 00141 template <class T> inline void RefPtr<T>::swap(RefPtr<T>& o) 00142 { 00143 std::swap(m_ptr, o.m_ptr); 00144 } 00145 00146 template <class T> inline void swap(RefPtr<T>& a, RefPtr<T>& b) 00147 { 00148 a.swap(b); 00149 } 00150 00151 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b) 00152 { 00153 return a.get() == b.get(); 00154 } 00155 00156 template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, U* b) 00157 { 00158 return a.get() == b; 00159 } 00160 00161 template <typename T, typename U> inline bool operator==(T* a, const RefPtr<U>& b) 00162 { 00163 return a == b.get(); 00164 } 00165 00166 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b) 00167 { 00168 return a.get() != b.get(); 00169 } 00170 00171 template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, U* b) 00172 { 00173 return a.get() != b; 00174 } 00175 00176 template <typename T, typename U> inline bool operator!=(T* a, const RefPtr<U>& b) 00177 { 00178 return a != b.get(); 00179 } 00180 00181 template <typename T, typename U> inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p) 00182 { 00183 return RefPtr<T>(static_cast<T*>(p.get())); 00184 } 00185 00186 template <typename T, typename U> inline RefPtr<T> const_pointer_cast(const RefPtr<U>& p) 00187 { 00188 return RefPtr<T>(const_cast<T*>(p.get())); 00189 } 00190 00191 template <typename T> inline T* getPtr(const RefPtr<T>& p) 00192 { 00193 return p.get(); 00194 } 00195 00196 } // namespace WTF 00197 00198 using WTF::RefPtr; 00199 using WTF::static_pointer_cast; 00200 using WTF::const_pointer_cast; 00201 00202 #endif // WTF_RefPtr_h
KDE 4.6 API Reference