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 
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 
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
uint qHash(const ChannelClassSpec &spec)
Definition: channel-class-spec.h:283
bool operator==(const T *ptr) const
Definition: shared-ptr.h:159
static SharedPtr< T > dynamicCast(const SharedPtr< X > &src)
Definition: shared-ptr.h:182
SharedPtr(const SharedPtr< Subclass > &o)
Definition: shared-ptr.h:104
bool operator==(const SharedPtr< T > &o) const
Definition: shared-ptr.h:157
void swap(WeakPtr< T > &o)
Definition: shared-ptr.h:262
The RefCounted class is a base class for shared objects used by SharedPtr.
Definition: shared-ptr.h:42
SharedPtr(const SharedPtr< T > &o)
Definition: shared-ptr.h:105
SharedPtr< T > & operator=(const SharedPtr< T > &o)
Definition: shared-ptr.h:162
SharedPtr< T > toStrongRef() const
Definition: shared-ptr.h:269
void swap(SharedPtr< T > &o)
Definition: shared-ptr.h:168
static SharedPtr< T > qObjectCast(const SharedPtr< X > &src)
Definition: shared-ptr.h:194
T * operator->() const
Definition: shared-ptr.h:151
WeakPtr(const SharedPtr< T > &o)
Definition: shared-ptr.h:230
The ContactManager class is responsible for managing contacts.
Definition: contact-manager.h:50
static SharedPtr< T > constCast(const SharedPtr< X > &src)
Definition: shared-ptr.h:188
WeakPtr(const WeakPtr< T > &o)
Definition: shared-ptr.h:229
The WeakPtr class holds a weak reference to an object managed by SharedPtr.
Definition: shared-ptr.h:40
bool operator!() const
Definition: shared-ptr.h:154
RefCounted()
Definition: shared-ptr.h:67
virtual ~RefCounted()
Definition: shared-ptr.h:72
~SharedPtr()
Definition: shared-ptr.h:134
WeakPtr< T > & operator=(const SharedPtr< T > &o)
Definition: shared-ptr.h:256
T * operator->()
Definition: shared-ptr.h:150
SharedPtr()
Definition: shared-ptr.h:101
WeakPtr()
Definition: shared-ptr.h:219
WeakPtr< T > & operator=(const WeakPtr< T > &o)
Definition: shared-ptr.h:250
static SharedPtr< T > staticCast(const SharedPtr< X > &src)
Definition: shared-ptr.h:176
bool operator!=(const SharedPtr< T > &o) const
Definition: shared-ptr.h:158
T * data() const
Definition: shared-ptr.h:148
~WeakPtr()
Definition: shared-ptr.h:239
bool isNull() const
Definition: shared-ptr.h:246
SharedPtr(T *d)
Definition: shared-ptr.h:102
bool operator!() const
Definition: shared-ptr.h:247
void reset()
Definition: shared-ptr.h:143
bool operator!=(const T *ptr) const
Definition: shared-ptr.h:160
bool isNull() const
Definition: shared-ptr.h:153
const T * constData() const
Definition: shared-ptr.h:149
Definition: abstract-adaptor.cpp:31
SharedPtr(const WeakPtr< T > &o)
Definition: shared-ptr.h:106
The SharedPtr class is a pointer to an explicitly shared object.
Definition: shared-ptr.h:39
WeakPtr(T *d)
Definition: shared-ptr.h:220


Copyright © 2008-2011 Collabora Ltd. and Nokia Corporation
Telepathy-Qt 0.9.7