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 33extern "C" void g_object_unref(gpointer); 34extern "C" gpointer g_object_ref_sink(gpointer); 35 36namespace WTF { 37 38enum GRefPtrAdoptType { GRefPtrAdopt }; 39template <typename T> inline T* refGPtr(T*); 40template <typename T> inline void derefGPtr(T*); 41template <typename T> class GRefPtr; 42template <typename T> GRefPtr<T> adoptGRef(T*); 43 44template <typename T> class GRefPtr { 45public: 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 111private: 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 119template <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 131template <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 142template <class T> inline void GRefPtr<T>::swap(GRefPtr<T>& o) 143{ 144 std::swap(m_ptr, o.m_ptr); 145} 146 147template <class T> inline void swap(GRefPtr<T>& a, GRefPtr<T>& b) 148{ 149 a.swap(b); 150} 151 152template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, const GRefPtr<U>& b) 153{ 154 return a.get() == b.get(); 155} 156 157template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, U* b) 158{ 159 return a.get() == b; 160} 161 162template <typename T, typename U> inline bool operator==(T* a, const GRefPtr<U>& b) 163{ 164 return a == b.get(); 165} 166 167template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, const GRefPtr<U>& b) 168{ 169 return a.get() != b.get(); 170} 171 172template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, U* b) 173{ 174 return a.get() != b; 175} 176 177template <typename T, typename U> inline bool operator!=(T* a, const GRefPtr<U>& b) 178{ 179 return a != b.get(); 180} 181 182template <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 187template <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 192template <typename T> inline T* getPtr(const GRefPtr<T>& p) 193{ 194 return p.get(); 195} 196 197template <typename T> GRefPtr<T> adoptGRef(T* p) 198{ 199 return GRefPtr<T>(p, GRefPtrAdopt); 200} 201 202template <> GHashTable* refGPtr(GHashTable* ptr); 203template <> void derefGPtr(GHashTable* ptr); 204template <> GVariant* refGPtr(GVariant* ptr); 205template <> void derefGPtr(GVariant* ptr); 206template <> GSource* refGPtr(GSource* ptr); 207template <> void derefGPtr(GSource* ptr); 208 209template <typename T> inline T* refGPtr(T* ptr) 210{ 211 if (ptr) 212 g_object_ref_sink(ptr); 213 return ptr; 214} 215 216template <typename T> inline void derefGPtr(T* ptr) 217{ 218 if (ptr) 219 g_object_unref(ptr); 220} 221 222} // namespace WTF 223 224using WTF::GRefPtr; 225using WTF::adoptGRef; 226 227#endif // ENABLE(GLIB_SUPPORT) 228 229#endif // WTF_GRefPtr_h 230