shared-ptr.h Source File

| Home · All Classes · All Namespaces · Modules · Functions · Files

shared-ptr.h
1
23 #ifndef _TelepathyQt_shared_ptr_h_HEADER_GUARD_
24 #define _TelepathyQt_shared_ptr_h_HEADER_GUARD_
25
26 #ifndef IN_TP_QT_HEADER
27 #error IN_TP_QT_HEADER
28 #endif
29
30 #include <TelepathyQt/Global>
31
32 #include <QHash>
33 #include <QObject>
34
35 namespace Tp
36 {
37
38 class RefCounted;
39 template <class T> class SharedPtr;
40 template <class T> class WeakPtr;
41
42 class TP_QT_EXPORT RefCounted
43 {
44 Q_DISABLE_COPY(RefCounted)
45
46 class SharedCount
47 {
48 Q_DISABLE_COPY(SharedCount)
49
50 public:
51 SharedCount(RefCounted *d)
52 : d(d), strongref(0), weakref(0)
53 {
54 }
55
56 private:
57 template <class T> friend class SharedPtr;
58 template <class T> friend class WeakPtr;
59 friend class RefCounted;
60
61 RefCounted *d;
62 mutable QAtomicInt strongref;
63 mutable QAtomicInt weakref;
64 };
65
66 public:
67 inline RefCounted() : sc(new SharedCount(this))
68 {
69 sc->weakref.ref();
70 }
71
72 inline virtual ~RefCounted()
73 {
74 sc->d = 0;
75 if (!sc->weakref.deref()) {
76 delete sc;
77 }
78 }
79
80 private:
81 template <class T> friend class SharedPtr;
82 template <class T> friend class WeakPtr;
83 // TODO: Remove when Conn.I.ContactList, etc becomes mandatory. This is required to circumvent
84 // a reference cycle when using contact list channels, due to the fact that Channels hold
85 // strong references to their parent Connection, but not needed when using
86 // Conn.I.ContactList and friends.
87 friend class ContactManager;
88
89 inline void ref() const { sc->strongref.ref(); }
90 inline bool deref() const { return sc->strongref.deref(); }
91
92 SharedCount *sc;
93 };
94
95 template <class T>
96 class SharedPtr
97 {
98 typedef bool (SharedPtr<T>::*UnspecifiedBoolType)() const;
99
100 public:
101 inline SharedPtr() : d(0) { }
102 explicit inline SharedPtr(T *d) : d(d) { if (d) { d->ref(); } }
103 template <typename Subclass>
104 inline SharedPtr(const SharedPtr<Subclass> &o) : d(o.data()) { if (d) { d->ref(); } }
105 inline SharedPtr(const SharedPtr<T> &o) : d(o.d) { if (d) { d->ref(); } }
106 explicit inline SharedPtr(const WeakPtr<T> &o)
107 {
108 RefCounted::SharedCount *sc = o.sc;
109 if (sc) {
110 // increase the strongref, but never up from zero
111 // or less (negative is used on untracked objects)
112 register int tmp = sc->strongref.fetchAndAddOrdered(0);
113 while (tmp > 0) {
114 // try to increment from "tmp" to "tmp + 1"
115 if (sc->strongref.testAndSetRelaxed(tmp, tmp + 1)) {
116 // succeeded
117 break;
118 }
119 // failed, try again
120 tmp = sc->strongref.fetchAndAddOrdered(0);
121 }
122
123 if (tmp > 0) {
124 d = dynamic_cast<T*>(sc->d);
125 Q_ASSERT(d != NULL);
126 } else {
127 d = 0;
128 }
129 } else {
130 d = 0;
131 }
132 }
133
134 inline ~SharedPtr()
135 {
136 if (d && !d->deref()) {
137 T *saved = d;
138 d = 0;
139 delete saved;
140 }
141 }
142
143 inline void reset()
144 {
145 SharedPtr<T>().swap(*this);
146 }
147
148 inline T *data() const { return d; }
149 inline const T *constData() const { return d; }
150 inline T *operator->() { return d; }
151 inline T *operator->() const { return d; }
152
153 inline bool isNull() const { return !d; }
154 inline bool operator!() const { return isNull(); }
155 operator UnspecifiedBoolType() const { return !isNull() ? &SharedPtr<T>::operator! : 0; }
156
157 inline bool operator==(const SharedPtr<T> &o) const { return d == o.d; }
158 inline bool operator!=(const SharedPtr<T> &o) const { return d != o.d; }
159 inline bool operator==(const T *ptr) const { return d == ptr; }
160 inline bool operator!=(const T *ptr) const { return d != ptr; }
161
162 inline SharedPtr<T> &operator=(const SharedPtr<T> &o)
163 {
164 SharedPtr<T>(o).swap(*this);
165 return *this;
166 }
167
168 inline void swap(SharedPtr<T> &o)
169 {
170 T *tmp = d;
171 d = o.d;
172 o.d = tmp;
173 }
174
175 template <class X>
176 static inline SharedPtr<T> staticCast(const SharedPtr<X> &src)
177 {
178 return SharedPtr<T>(static_cast<T*>(src.data()));
179 }
180
181 template <class X>
182 static inline SharedPtr<T> dynamicCast(const SharedPtr<X> &src)
183 {
184 return SharedPtr<T>(dynamic_cast<T*>(src.data()));
185 }
186
187 template <class X>
188 static inline SharedPtr<T> constCast(const SharedPtr<X> &src)
189 {
190 return SharedPtr<T>(const_cast<T*>(src.data()));
191 }
192
193 template <class X>
194 static inline SharedPtr<T> qObjectCast(const SharedPtr<X> &src)
195 {
196 return SharedPtr<T>(qobject_cast<T*>(src.data()));
197 }
198
199 private:
200 friend class WeakPtr<T>;
201
202 T *d;
203 };
204
205 template<typename T>
206 inline uint qHash(const SharedPtr<T> &ptr)
207 {
208 return QT_PREPEND_NAMESPACE(qHash<T>(ptr.data()));
209 }
210
211 template<typename T> inline uint qHash(const WeakPtr<T> &ptr);
212
213 template <class T>
214 class WeakPtr
215 {
216 typedef bool (WeakPtr<T>::*UnspecifiedBoolType)() const;
217
218 public:
219 inline WeakPtr() : sc(0) { }
220 explicit inline WeakPtr(T *d)
221 {
222 if (d) {
223 sc = d->sc;
224 sc->weakref.ref();
225 } else {
226 sc = 0;
227 }
228 }
229 inline WeakPtr(const WeakPtr<T> &o) : sc(o.sc) { if (sc) { sc->weakref.ref(); } }
230 inline WeakPtr(const SharedPtr<T> &o)
231 {
232 if (o.d) {
233 sc = o.d->sc;
234 sc->weakref.ref();
235 } else {
236 sc = 0;
237 }
238 }
239 inline ~WeakPtr()
240 {
241 if (sc && !sc->weakref.deref()) {
242 delete sc;
243 }
244 }
245
246 inline bool isNull() const { return !sc || sc->strongref.fetchAndAddOrdered(0) <= 0; }
247 inline bool operator!() const { return isNull(); }
248 operator UnspecifiedBoolType() const { return !isNull() ? &WeakPtr<T>::operator! : 0; }
249
250 inline WeakPtr<T> &operator=(const WeakPtr<T> &o)
251 {
252 WeakPtr<T>(o).swap(*this);
253 return *this;
254 }
255
256 inline WeakPtr<T> &operator=(const SharedPtr<T> &o)
257 {
258 WeakPtr<T>(o).swap(*this);
259 return *this;
260 }
261
262 inline void swap(WeakPtr<T> &o)
263 {
264 RefCounted::SharedCount *tmp = sc;
265 sc = o.sc;
266 o.sc = tmp;
267 }
268
269 SharedPtr<T> toStrongRef() const { return SharedPtr<T>(*this); }
270
271 private:
272 friend class SharedPtr<T>;
273 friend uint qHash<T>(const WeakPtr<T> &ptr);
274
275 RefCounted::SharedCount *sc;
276 };
277
278 template<typename T>
279 inline uint qHash(const WeakPtr<T> &ptr)
280 {
281 T *actualPtr = ptr.sc ? ptr.sc.d : 0;
282 return QT_PREPEND_NAMESPACE(qHash<T>(actualPtr));
283 }
284
285 } // Tp
286
287 #endif
Tp::ContactManager
The ContactManager class is responsible for managing contacts.
Definition: contact-manager.h:50
Tp::WeakPtr::operator=
WeakPtr< T > & operator=(const SharedPtr< T > &o)
Definition: shared-ptr.h:256
Tp::SharedPtr::isNull
bool isNull() const
Definition: shared-ptr.h:153
Tp::WeakPtr::WeakPtr
WeakPtr(T *d)
Definition: shared-ptr.h:220
Tp::WeakPtr
The WeakPtr class holds a weak reference to an object managed by SharedPtr.
Definition: shared-ptr.h:40
Tp::SharedPtr::SharedPtr
SharedPtr()
Definition: shared-ptr.h:101
Tp::SharedPtr::operator->
T * operator->() const
Definition: shared-ptr.h:151
Tp::SharedPtr::data
T * data() const
Definition: shared-ptr.h:148
Tp::WeakPtr::WeakPtr
WeakPtr(const SharedPtr< T > &o)
Definition: shared-ptr.h:230
Tp::SharedPtr::operator!=
bool operator!=(const T *ptr) const
Definition: shared-ptr.h:160
Tp::SharedPtr::qObjectCast
static SharedPtr< T > qObjectCast(const SharedPtr< X > &src)
Definition: shared-ptr.h:194
Tp::SharedPtr::~SharedPtr
~SharedPtr()
Definition: shared-ptr.h:134
Tp::SharedPtr::SharedPtr
SharedPtr(const SharedPtr< T > &o)
Definition: shared-ptr.h:105
Tp::SharedPtr::staticCast
static SharedPtr< T > staticCast(const SharedPtr< X > &src)
Definition: shared-ptr.h:176
Tp::WeakPtr::WeakPtr
WeakPtr(const WeakPtr< T > &o)
Definition: shared-ptr.h:229
Tp::WeakPtr::operator=
WeakPtr< T > & operator=(const WeakPtr< T > &o)
Definition: shared-ptr.h:250
Tp::WeakPtr::isNull
bool isNull() const
Definition: shared-ptr.h:246
Tp::WeakPtr::WeakPtr
WeakPtr()
Definition: shared-ptr.h:219
Tp::SharedPtr
The SharedPtr class is a pointer to an explicitly shared object.
Definition: shared-ptr.h:39
Tp::RefCounted::RefCounted
RefCounted()
Definition: shared-ptr.h:67
Tp::RefCounted::~RefCounted
virtual ~RefCounted()
Definition: shared-ptr.h:72
Tp::SharedPtr::reset
void reset()
Definition: shared-ptr.h:143
Tp::SharedPtr::operator==
bool operator==(const SharedPtr< T > &o) const
Definition: shared-ptr.h:157
Tp::WeakPtr::operator!
bool operator!() const
Definition: shared-ptr.h:247
Tp::WeakPtr::~WeakPtr
~WeakPtr()
Definition: shared-ptr.h:239
Tp::SharedPtr::operator!=
bool operator!=(const SharedPtr< T > &o) const
Definition: shared-ptr.h:158
Tp::SharedPtr::constData
const T * constData() const
Definition: shared-ptr.h:149
Tp::SharedPtr::operator=
SharedPtr< T > & operator=(const SharedPtr< T > &o)
Definition: shared-ptr.h:162
Tp::SharedPtr::dynamicCast
static SharedPtr< T > dynamicCast(const SharedPtr< X > &src)
Definition: shared-ptr.h:182
Tp::SharedPtr::SharedPtr
SharedPtr(const SharedPtr< Subclass > &o)
Definition: shared-ptr.h:104
Tp::WeakPtr::swap
void swap(WeakPtr< T > &o)
Definition: shared-ptr.h:262
Tp::SharedPtr::swap
void swap(SharedPtr< T > &o)
Definition: shared-ptr.h:168
Tp::qHash
uint qHash(const ChannelClassSpec &spec)
Definition: channel-class-spec.h:283
Tp::RefCounted
The RefCounted class is a base class for shared objects used by SharedPtr.
Definition: shared-ptr.h:42
Tp::WeakPtr::toStrongRef
SharedPtr< T > toStrongRef() const
Definition: shared-ptr.h:269
Tp::SharedPtr::constCast
static SharedPtr< T > constCast(const SharedPtr< X > &src)
Definition: shared-ptr.h:188
Tp::SharedPtr::operator==
bool operator==(const T *ptr) const
Definition: shared-ptr.h:159
Tp::SharedPtr::operator->
T * operator->()
Definition: shared-ptr.h:150
Tp::SharedPtr::SharedPtr
SharedPtr(T *d)
Definition: shared-ptr.h:102
Tp::SharedPtr::SharedPtr
SharedPtr(const WeakPtr< T > &o)
Definition: shared-ptr.h:106
Tp::SharedPtr::operator!
bool operator!() const
Definition: shared-ptr.h:154