• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
GRefPtr()46     GRefPtr() : m_ptr(0) { }
47 
GRefPtr(T * ptr)48     GRefPtr(T* ptr)
49         : m_ptr(ptr)
50     {
51         if (ptr)
52             refGPtr(ptr);
53     }
54 
GRefPtr(const GRefPtr & o)55     GRefPtr(const GRefPtr& o)
56         : m_ptr(o.m_ptr)
57     {
58         if (T* ptr = m_ptr)
59             refGPtr(ptr);
60     }
61 
GRefPtr(const GRefPtr<U> & o)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 
~GRefPtr()69     ~GRefPtr()
70     {
71         if (T* ptr = m_ptr)
72             derefGPtr(ptr);
73     }
74 
clear()75     void clear()
76     {
77         T* ptr = m_ptr;
78         m_ptr = 0;
79         if (ptr)
80             derefGPtr(ptr);
81     }
82 
leakRef()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.
GRefPtr(HashTableDeletedValueType)91     GRefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
isHashTableDeletedValue()92     bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
93 
get()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;
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:
hashTableDeletedValue()112     static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
113     // Adopting constructor.
GRefPtr(T * ptr,GRefPtrAdoptType)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 
swap(GRefPtr<T> & o)142 template <class T> inline void GRefPtr<T>::swap(GRefPtr<T>& o)
143 {
144     std::swap(m_ptr, o.m_ptr);
145 }
146 
swap(GRefPtr<T> & a,GRefPtr<T> & b)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 
static_pointer_cast(const GRefPtr<U> & p)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 
const_pointer_cast(const GRefPtr<U> & p)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 
getPtr(const GRefPtr<T> & p)192 template <typename T> inline T* getPtr(const GRefPtr<T>& p)
193 {
194     return p.get();
195 }
196 
adoptGRef(T * p)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 
refGPtr(T * ptr)209 template <typename T> inline T* refGPtr(T* ptr)
210 {
211     if (ptr)
212         g_object_ref_sink(ptr);
213     return ptr;
214 }
215 
derefGPtr(T * ptr)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