1 /* 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 3 * Copyright (C) 2008 Collabora Ltd. 4 * Copyright (C) 2009 Martin Robinson 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Library General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Library General Public License for more details. 15 * 16 * You should have received a copy of the GNU Library General Public License 17 * along with this library; see the file COPYING.LIB. If not, write to 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef WTF_GRefPtr_h 24 #define WTF_GRefPtr_h 25 26 #if ENABLE(GLIB_SUPPORT) 27 28 #include "AlwaysInline.h" 29 #include "GRefPtr.h" 30 #include "RefPtr.h" 31 #include <algorithm> 32 33 extern "C" void g_object_unref(gpointer); 34 extern "C" gpointer g_object_ref_sink(gpointer); 35 36 namespace WTF { 37 38 enum GRefPtrAdoptType { GRefPtrAdopt }; 39 template <typename T> inline T* refGPtr(T*); 40 template <typename T> inline void derefGPtr(T*); 41 template <typename T> class GRefPtr; 42 template <typename T> GRefPtr<T> adoptGRef(T*); 43 44 template <typename T> class GRefPtr { 45 public: 46 GRefPtr() : m_ptr(0) { } 47 48 GRefPtr(T* ptr) 49 : m_ptr(ptr) 50 { 51 if (ptr) 52 refGPtr(ptr); 53 } 54 55 GRefPtr(const GRefPtr& o) 56 : m_ptr(o.m_ptr) 57 { 58 if (T* ptr = m_ptr) 59 refGPtr(ptr); 60 } 61 62 template <typename U> GRefPtr(const GRefPtr<U>& o) 63 : m_ptr(o.get()) 64 { 65 if (T* ptr = m_ptr) 66 refGPtr(ptr); 67 } 68 69 ~GRefPtr() 70 { 71 if (T* ptr = m_ptr) 72 derefGPtr(ptr); 73 } 74 75 void clear() 76 { 77 T* ptr = m_ptr; 78 m_ptr = 0; 79 if (ptr) 80 derefGPtr(ptr); 81 } 82 83 T* leakRef() WARN_UNUSED_RETURN 84 { 85 T* ptr = m_ptr; 86 m_ptr = 0; 87 return ptr; 88 } 89 90 // Hash table deleted values, which are only constructed and never copied or destroyed. 91 GRefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { } 92 bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); } 93 94 T* get() const { return m_ptr; } 95 T& operator*() const { return *m_ptr; } 96 ALWAYS_INLINE T* operator->() const { return m_ptr; } 97 98 bool operator!() const { return !m_ptr; } 99 100 // This conversion operator allows implicit conversion to bool but not to other integer types. 101 typedef T* GRefPtr::*UnspecifiedBoolType; 102 operator UnspecifiedBoolType() const { return m_ptr ? &GRefPtr::m_ptr : 0; } 103 104 GRefPtr& operator=(const GRefPtr&); 105 GRefPtr& operator=(T*); 106 template <typename U> GRefPtr& operator=(const GRefPtr<U>&); 107 108 void swap(GRefPtr&); 109 friend GRefPtr adoptGRef<T>(T*); 110 111 private: 112 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } 113 // Adopting constructor. 114 GRefPtr(T* ptr, GRefPtrAdoptType) : m_ptr(ptr) {} 115 116 T* m_ptr; 117 }; 118 119 template <typename T> inline GRefPtr<T>& GRefPtr<T>::operator=(const GRefPtr<T>& o) 120 { 121 T* optr = o.get(); 122 if (optr) 123 refGPtr(optr); 124 T* ptr = m_ptr; 125 m_ptr = optr; 126 if (ptr) 127 derefGPtr(ptr); 128 return *this; 129 } 130 131 template <typename T> inline GRefPtr<T>& GRefPtr<T>::operator=(T* optr) 132 { 133 T* ptr = m_ptr; 134 if (optr) 135 refGPtr(optr); 136 m_ptr = optr; 137 if (ptr) 138 derefGPtr(ptr); 139 return *this; 140 } 141 142 template <class T> inline void GRefPtr<T>::swap(GRefPtr<T>& o) 143 { 144 std::swap(m_ptr, o.m_ptr); 145 } 146 147 template <class T> inline void swap(GRefPtr<T>& a, GRefPtr<T>& b) 148 { 149 a.swap(b); 150 } 151 152 template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, const GRefPtr<U>& b) 153 { 154 return a.get() == b.get(); 155 } 156 157 template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, U* b) 158 { 159 return a.get() == b; 160 } 161 162 template <typename T, typename U> inline bool operator==(T* a, const GRefPtr<U>& b) 163 { 164 return a == b.get(); 165 } 166 167 template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, const GRefPtr<U>& b) 168 { 169 return a.get() != b.get(); 170 } 171 172 template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, U* b) 173 { 174 return a.get() != b; 175 } 176 177 template <typename T, typename U> inline bool operator!=(T* a, const GRefPtr<U>& b) 178 { 179 return a != b.get(); 180 } 181 182 template <typename T, typename U> inline GRefPtr<T> static_pointer_cast(const GRefPtr<U>& p) 183 { 184 return GRefPtr<T>(static_cast<T*>(p.get())); 185 } 186 187 template <typename T, typename U> inline GRefPtr<T> const_pointer_cast(const GRefPtr<U>& p) 188 { 189 return GRefPtr<T>(const_cast<T*>(p.get())); 190 } 191 192 template <typename T> inline T* getPtr(const GRefPtr<T>& p) 193 { 194 return p.get(); 195 } 196 197 template <typename T> GRefPtr<T> adoptGRef(T* p) 198 { 199 return GRefPtr<T>(p, GRefPtrAdopt); 200 } 201 202 template <> GHashTable* refGPtr(GHashTable* ptr); 203 template <> void derefGPtr(GHashTable* ptr); 204 template <> GVariant* refGPtr(GVariant* ptr); 205 template <> void derefGPtr(GVariant* ptr); 206 template <> GSource* refGPtr(GSource* ptr); 207 template <> void derefGPtr(GSource* ptr); 208 209 template <typename T> inline T* refGPtr(T* ptr) 210 { 211 if (ptr) 212 g_object_ref_sink(ptr); 213 return ptr; 214 } 215 216 template <typename T> inline void derefGPtr(T* ptr) 217 { 218 if (ptr) 219 g_object_unref(ptr); 220 } 221 222 } // namespace WTF 223 224 using WTF::GRefPtr; 225 using WTF::adoptGRef; 226 227 #endif // ENABLE(GLIB_SUPPORT) 228 229 #endif // WTF_GRefPtr_h 230