Qt 4.8
qsharedpointer_impl.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef Q_QDOC
43 
44 #ifndef QSHAREDPOINTER_H
45 #error Do not include qsharedpointer_impl.h directly
46 #endif
47 
48 #if 0
49 // These macros are duplicated here to make syncqt not complain a about
50 // this header, as we have a "qt_sync_stop_processing" below, which in turn
51 // is here because this file contains a template mess and duplicates the
52 // classes found in qsharedpointer.h
55 QT_MODULE(Core)
58 #pragma qt_sync_stop_processing
59 #endif
60 
61 #include <new>
62 #include <QtCore/qatomic.h>
63 #include <QtCore/qobject.h> // for qobject_cast
64 
66 
68 
69 QT_MODULE(Core)
70 
71 // Macro QSHAREDPOINTER_VERIFY_AUTO_CAST
72 // generates a compiler error if the following construct isn't valid:
73 // T *ptr1;
74 // X *ptr2 = ptr1;
75 //
76 #ifdef QT_NO_DEBUG
77 # define QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X) qt_noop()
78 #else
79 
80 template<typename T> inline void qt_sharedpointer_cast_check(T *) { }
81 # define QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X) \
82  qt_sharedpointer_cast_check<T>(static_cast<X *>(0))
83 #endif
84 
85 //
86 // forward declarations
87 //
88 template <class T> class QWeakPointer;
89 template <class T> class QSharedPointer;
90 
91 template <class X, class T>
93 template <class X, class T>
95 template <class X, class T>
97 
98 #ifndef QT_NO_QOBJECT
99 template <class X, class T>
101 #endif
102 
103 namespace QtSharedPointer {
104  template <class T> class InternalRefCount;
105  template <class T> class ExternalRefCount;
106 
107  template <class X, class Y> QSharedPointer<X> copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
108 
109  // used in debug mode to verify the reuse of pointers
110  Q_CORE_EXPORT void internalSafetyCheckAdd2(const void *, const volatile void *);
111  Q_CORE_EXPORT void internalSafetyCheckRemove2(const void *);
112 
113  template <class T, typename Klass, typename RetVal>
114  inline void executeDeleter(T *t, RetVal (Klass:: *memberDeleter)())
115  { (t->*memberDeleter)(); }
116  template <class T, typename Deleter>
117  inline void executeDeleter(T *t, Deleter d)
118  { d(t); }
119  template <class T> inline void normalDeleter(T *t) { delete t; }
120 
121  // this uses partial template specialization
122  template <class T> struct RemovePointer;
123  template <class T> struct RemovePointer<T *> { typedef T Type; };
124  template <class T> struct RemovePointer<QSharedPointer<T> > { typedef T Type; };
125  template <class T> struct RemovePointer<QWeakPointer<T> > { typedef T Type; };
126 
127  // This class provides the basic functionality of a pointer wrapper.
128  // Its existence is mostly legacy, since originally QSharedPointer
129  // could also be used for internally-refcounted objects.
130  template <class T>
131  class Basic
132  {
133 #ifndef Q_CC_NOKIAX86
134  typedef T *Basic:: *RestrictedBool;
135 #endif
136  public:
137  typedef T Type;
138  typedef T element_type;
139  typedef T value_type;
140  typedef value_type *pointer;
141  typedef const value_type *const_pointer;
142  typedef value_type &reference;
143  typedef const value_type &const_reference;
144  typedef qptrdiff difference_type;
145 
146  inline T *data() const { return value; }
147  inline bool isNull() const { return !data(); }
148 #ifndef Q_CC_NOKIAX86
149  inline operator RestrictedBool() const { return isNull() ? 0 : &Basic::value; }
150 #else
151  inline operator bool() const { return isNull() ? 0 : &Basic::value; }
152 #endif
153  inline bool operator !() const { return isNull(); }
154  inline T &operator*() const { return *data(); }
155  inline T *operator->() const { return data(); }
156 
157  protected:
158  inline Basic(T *ptr = 0) : value(ptr) { }
159  inline Basic(Qt::Initialization) { }
160  // ~Basic();
161 
162  inline void internalConstruct(T *ptr)
163  {
164  value = ptr;
165  }
166 
167 #if defined(Q_NO_TEMPLATE_FRIENDS)
168  public:
169 #else
170  template <class X> friend class QT_PREPEND_NAMESPACE(QWeakPointer);
171 #endif
172 
173  Type *value;
174  };
175 
176  // This class is the d-pointer of QSharedPointer and QWeakPointer.
177  //
178  // It is a reference-counted reference counter. "strongref" is the inner
179  // reference counter, and it tracks the lifetime of the pointer itself.
180  // "weakref" is the outer reference counter and it tracks the lifetime of
181  // the ExternalRefCountData object.
182  struct ExternalRefCountData
183  {
184  QBasicAtomicInt weakref;
185  QBasicAtomicInt strongref;
186 
187  inline ExternalRefCountData()
188  {
189  strongref = 1;
190  weakref = 1;
191  }
192  inline ExternalRefCountData(Qt::Initialization) { }
193  virtual inline ~ExternalRefCountData() { Q_ASSERT(!weakref); Q_ASSERT(strongref <= 0); }
194 
195  // overridden by derived classes
196  // returns false to indicate caller should delete the pointer
197  // returns true in case it has already done so
198  virtual inline bool destroy() { return false; }
199 
200 #ifndef QT_NO_QOBJECT
201  Q_CORE_EXPORT static ExternalRefCountData *getAndRef(const QObject *);
202  Q_CORE_EXPORT void setQObjectShared(const QObject *, bool enable);
203 #endif
204  inline void setQObjectShared(...) { }
205  };
206  // sizeof(ExternalRefCount) = 12 (32-bit) / 16 (64-bit)
207 
208  // This class extends ExternalRefCountData with a pointer
209  // to a function, which is called by the destroy() function.
210  struct ExternalRefCountWithDestroyFn: public ExternalRefCountData
211  {
212  typedef void (*DestroyerFn)(ExternalRefCountData *);
213  DestroyerFn destroyer;
214 
215  inline ExternalRefCountWithDestroyFn(DestroyerFn d)
216  : destroyer(d)
217  { }
218 
219  inline bool destroy() { destroyer(this); return true; }
220  inline void operator delete(void *ptr) { ::operator delete(ptr); }
221  inline void operator delete(void *, void *) { }
222  };
223  // sizeof(ExternalRefCountWithDestroyFn) = 16 (32-bit) / 24 (64-bit)
224 
225  // This class extends ExternalRefCountWithDestroyFn and implements
226  // the static function that deletes the object. The pointer and the
227  // custom deleter are kept in the "extra" member.
228  template <class T, typename Deleter>
229  struct ExternalRefCountWithCustomDeleter: public ExternalRefCountWithDestroyFn
230  {
231  typedef ExternalRefCountWithCustomDeleter Self;
232  typedef ExternalRefCountWithDestroyFn BaseClass;
233 
234  struct CustomDeleter
235  {
236  Deleter deleter;
237  T *ptr;
238 
239  inline CustomDeleter(T *p, Deleter d) : deleter(d), ptr(p) {}
240  };
241  CustomDeleter extra;
242  // sizeof(CustomDeleter) = sizeof(Deleter) + sizeof(void*)
243  // for Deleter = function pointer: 8 (32-bit) / 16 (64-bit)
244  // for Deleter = PMF: 12 (32-bit) / 24 (64-bit) (GCC)
245 
246  static inline void deleter(ExternalRefCountData *self)
247  {
248  Self *realself = static_cast<Self *>(self);
249  executeDeleter(realself->extra.ptr, realself->extra.deleter);
250 
251  // delete the deleter too
252  realself->extra.~CustomDeleter();
253  }
254  static void safetyCheckDeleter(ExternalRefCountData *self)
255  {
256  internalSafetyCheckRemove2(self);
257  deleter(self);
258  }
259 
260  static inline Self *create(T *ptr, Deleter userDeleter)
261  {
262 # ifdef QT_SHAREDPOINTER_TRACK_POINTERS
263  DestroyerFn destroy = &safetyCheckDeleter;
264 # else
265  DestroyerFn destroy = &deleter;
266 # endif
267  Self *d = static_cast<Self *>(::operator new(sizeof(Self)));
268 
269  // initialize the two sub-objects
270  new (&d->extra) CustomDeleter(ptr, userDeleter);
271  new (d) BaseClass(destroy); // can't throw
272 
273  return d;
274  }
275  private:
276  // prevent construction and the emission of virtual symbols
277  ExternalRefCountWithCustomDeleter();
278  ~ExternalRefCountWithCustomDeleter();
279  };
280 
281  // This class extends ExternalRefCountWithDestroyFn and adds a "T"
282  // member. That way, when the create() function is called, we allocate
283  // memory for both QSharedPointer's d-pointer and the actual object being
284  // tracked.
285  template <class T>
286  struct ExternalRefCountWithContiguousData: public ExternalRefCountWithDestroyFn
287  {
288  typedef ExternalRefCountWithDestroyFn Parent;
289  T data;
290 
291  static void deleter(ExternalRefCountData *self)
292  {
293  ExternalRefCountWithContiguousData *that =
294  static_cast<ExternalRefCountWithContiguousData *>(self);
295  that->data.~T();
296  }
297  static void safetyCheckDeleter(ExternalRefCountData *self)
298  {
299  internalSafetyCheckRemove2(self);
300  deleter(self);
301  }
302 
303  static inline ExternalRefCountData *create(T **ptr)
304  {
305 # ifdef QT_SHAREDPOINTER_TRACK_POINTERS
306  DestroyerFn destroy = &safetyCheckDeleter;
307 # else
308  DestroyerFn destroy = &deleter;
309 # endif
310  ExternalRefCountWithContiguousData *d =
311  static_cast<ExternalRefCountWithContiguousData *>(::operator new(sizeof(ExternalRefCountWithContiguousData)));
312 
313  // initialize the d-pointer sub-object
314  // leave d->data uninitialized
315  new (d) Parent(destroy); // can't throw
316 
317  *ptr = &d->data;
318  return d;
319  }
320 
321  private:
322  // prevent construction and the emission of virtual symbols
323  ExternalRefCountWithContiguousData();
324  ~ExternalRefCountWithContiguousData();
325  };
326 
327  // This is the main body of QSharedPointer. It implements the
328  // external reference counting functionality.
329  template <class T>
330  class ExternalRefCount: public Basic<T>
331  {
332  protected:
333  typedef ExternalRefCountData Data;
334 
335  inline void deref()
336  { deref(d, this->value); }
337  static inline void deref(Data *d, T *value)
338  {
339  if (!d) return;
340  if (!d->strongref.deref()) {
341  if (!d->destroy())
342  delete value;
343  }
344  if (!d->weakref.deref())
345  delete d;
346  }
347 
348  inline void internalConstruct(T *ptr)
349  {
350 #ifdef QT_SHAREDPOINTER_TRACK_POINTERS
351  internalConstruct<void (*)(T *)>(ptr, normalDeleter);
352 #else
353  if (ptr)
354  d = new Data;
355  else
356  d = 0;
357  internalFinishConstruction(ptr);
358 #endif
359  }
360 
361  template <typename Deleter>
362  inline void internalConstruct(T *ptr, Deleter deleter)
363  {
364  if (ptr)
366  else
367  d = 0;
368  internalFinishConstruction(ptr);
369  }
370 
371  inline void internalCreate()
372  {
373  T *ptr;
375  Basic<T>::internalConstruct(ptr);
376  }
377 
378  inline void internalFinishConstruction(T *ptr)
379  {
380  Basic<T>::internalConstruct(ptr);
381 #ifdef QT_SHAREDPOINTER_TRACK_POINTERS
382  if (ptr) internalSafetyCheckAdd2(d, ptr);
383 #endif
384  if (ptr) d->setQObjectShared(ptr, true);
385  }
386 
387  inline ExternalRefCount() : d(0) { }
388  inline ExternalRefCount(Qt::Initialization i) : Basic<T>(i) { }
389 
390  inline ExternalRefCount(T *ptr) : Basic<T>(Qt::Uninitialized) // throws
391  { internalConstruct(ptr); }
392  template <typename Deleter>
393  inline ExternalRefCount(T *ptr, Deleter deleter) : Basic<T>(Qt::Uninitialized) // throws
394  { internalConstruct(ptr, deleter); }
395 
396  inline ExternalRefCount(const ExternalRefCount<T> &other) : Basic<T>(other), d(other.d)
397  { if (d) ref(); }
398  template <class X>
399  inline ExternalRefCount(const ExternalRefCount<X> &other) : Basic<T>(other.value), d(other.d)
400  { if (d) ref(); }
401  inline ~ExternalRefCount() { deref(); }
402 
403  template <class X>
404  inline void internalCopy(const ExternalRefCount<X> &other)
405  {
406  Data *o = other.d;
407  T *actual = other.value;
408  if (o)
409  other.ref();
410  qSwap(d, o);
411  qSwap(this->value, actual);
412  deref(o, actual);
413  }
414 
415  inline void internalSwap(ExternalRefCount &other)
416  {
417  qSwap(d, other.d);
418  qSwap(this->value, other.value);
419  }
420 
421 #if defined(Q_NO_TEMPLATE_FRIENDS)
422  public:
423 #else
424  template <class X> friend class ExternalRefCount;
425  template <class X> friend class QT_PREPEND_NAMESPACE(QWeakPointer);
426  template <class X, class Y> friend QSharedPointer<X> copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
427 #endif
428  inline void ref() const { d->weakref.ref(); d->strongref.ref(); }
429 
430  inline void internalSet(Data *o, T *actual)
431  {
432  if (o) {
433  // increase the strongref, but never up from zero
434  // or less (-1 is used by QWeakPointer on untracked QObject)
435  register int tmp = o->strongref;
436  while (tmp > 0) {
437  // try to increment from "tmp" to "tmp + 1"
438  if (o->strongref.testAndSetRelaxed(tmp, tmp + 1))
439  break; // succeeded
440  tmp = o->strongref; // failed, try again
441  }
442 
443  if (tmp > 0)
444  o->weakref.ref();
445  else
446  o = 0;
447  }
448 
449  qSwap(d, o);
450  qSwap(this->value, actual);
451  if (!d || d->strongref == 0)
452  this->value = 0;
453 
454  // dereference saved data
455  deref(o, actual);
456  }
457 
458  Data *d;
459 
460  private:
461  template<class X> ExternalRefCount(const InternalRefCount<X> &);
462  };
463 } // namespace QtSharedPointer
464 
465 template <class T>
466 class QSharedPointer: public QtSharedPointer::ExternalRefCount<T>
467 {
468  typedef typename QtSharedPointer::ExternalRefCount<T> BaseClass;
469 public:
470  inline QSharedPointer() { }
471  // inline ~QSharedPointer() { }
472 
473  inline explicit QSharedPointer(T *ptr) : BaseClass(ptr) // throws
474  { }
475 
476  template <typename Deleter>
477  inline QSharedPointer(T *ptr, Deleter d) : BaseClass(ptr, d) // throws
478  { }
479 
480  inline QSharedPointer(const QSharedPointer<T> &other) : BaseClass(other) { }
481  inline QSharedPointer<T> &operator=(const QSharedPointer<T> &other)
482  {
483  BaseClass::internalCopy(other);
484  return *this;
485  }
486 #ifdef Q_COMPILER_RVALUE_REFS
487  inline QSharedPointer<T> &operator=(QSharedPointer<T> &&other)
488  {
490  return *this;
491  }
492 #endif
493 
494  template <class X>
495  inline QSharedPointer(const QSharedPointer<X> &other) : BaseClass(other)
496  { }
497 
498  template <class X>
499  inline QSharedPointer<T> &operator=(const QSharedPointer<X> &other)
500  {
501  QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X); // if you get an error in this line, the cast is invalid
502  BaseClass::internalCopy(other);
503  return *this;
504  }
505 
506  template <class X>
507  inline QSharedPointer(const QWeakPointer<X> &other) : BaseClass(Qt::Uninitialized)
508  { this->d = 0; *this = other; }
509 
510  template <class X>
511  inline QSharedPointer<T> &operator=(const QWeakPointer<X> &other)
512  { BaseClass::internalSet(other.d, other.value); return *this; }
513 
514  inline void swap(QSharedPointer &other)
516 
517  template <class X>
518  QSharedPointer<X> staticCast() const
519  {
520  return qSharedPointerCast<X, T>(*this);
521  }
522 
523  template <class X>
524  QSharedPointer<X> dynamicCast() const
525  {
526  return qSharedPointerDynamicCast<X, T>(*this);
527  }
528 
529  template <class X>
530  QSharedPointer<X> constCast() const
531  {
532  return qSharedPointerConstCast<X, T>(*this);
533  }
534 
535 #ifndef QT_NO_QOBJECT
536  template <class X>
537  QSharedPointer<X> objectCast() const
538  {
539  return qSharedPointerObjectCast<X, T>(*this);
540  }
541 #endif
542 
543  inline void clear() { *this = QSharedPointer<T>(); }
544 
545  QWeakPointer<T> toWeakRef() const;
546 
547 protected:
548  inline explicit QSharedPointer(Qt::Initialization i) : BaseClass(i) {}
549 
550 public:
551  static inline QSharedPointer<T> create()
552  {
554  result.internalCreate();
555 
556  // now initialize the data
557  new (result.data()) T();
558  result.internalFinishConstruction(result.data());
559  return result;
560  }
561 };
562 
563 template <class T>
564 class QWeakPointer
565 {
566 #ifndef Q_CC_NOKIAX86
567  typedef T *QWeakPointer:: *RestrictedBool;
568 #endif
569  typedef QtSharedPointer::ExternalRefCountData Data;
570 
571 public:
572  typedef T element_type;
573  typedef T value_type;
574  typedef value_type *pointer;
575  typedef const value_type *const_pointer;
576  typedef value_type &reference;
577  typedef const value_type &const_reference;
578  typedef qptrdiff difference_type;
579 
580  inline bool isNull() const { return d == 0 || d->strongref == 0 || value == 0; }
581 #ifndef Q_CC_NOKIAX86
582  inline operator RestrictedBool() const { return isNull() ? 0 : &QWeakPointer::value; }
583 #else
584  inline operator bool() const { return isNull() ? 0 : &QWeakPointer::value; }
585 #endif
586  inline bool operator !() const { return isNull(); }
587  inline T *data() const { return d == 0 || d->strongref == 0 ? 0 : value; }
588 
589  inline QWeakPointer() : d(0), value(0) { }
590  inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; }
591 
592 #ifndef QT_NO_QOBJECT
593  // special constructor that is enabled only if X derives from QObject
594  template <class X>
595  inline QWeakPointer(X *ptr) : d(ptr ? Data::getAndRef(ptr) : 0), value(ptr)
596  { }
597 #endif
598  template <class X>
599  inline QWeakPointer &operator=(X *ptr)
600  { return *this = QWeakPointer(ptr); }
601 
602  inline QWeakPointer(const QWeakPointer<T> &o) : d(o.d), value(o.value)
603  { if (d) d->weakref.ref(); }
604  inline QWeakPointer<T> &operator=(const QWeakPointer<T> &o)
605  {
606  internalSet(o.d, o.value);
607  return *this;
608  }
609 
610  inline QWeakPointer(const QSharedPointer<T> &o) : d(o.d), value(o.data())
611  { if (d) d->weakref.ref();}
612  inline QWeakPointer<T> &operator=(const QSharedPointer<T> &o)
613  {
614  internalSet(o.d, o.value);
615  return *this;
616  }
617 
618  template <class X>
619  inline QWeakPointer(const QWeakPointer<X> &o) : d(0), value(0)
620  { *this = o; }
621 
622  template <class X>
623  inline QWeakPointer<T> &operator=(const QWeakPointer<X> &o)
624  {
625  // conversion between X and T could require access to the virtual table
626  // so force the operation to go through QSharedPointer
627  *this = o.toStrongRef();
628  return *this;
629  }
630 
631  template <class X>
632  inline bool operator==(const QWeakPointer<X> &o) const
633  { return d == o.d && value == static_cast<const T *>(o.value); }
634 
635  template <class X>
636  inline bool operator!=(const QWeakPointer<X> &o) const
637  { return !(*this == o); }
638 
639  template <class X>
640  inline QWeakPointer(const QSharedPointer<X> &o) : d(0), value(0)
641  { *this = o; }
642 
643  template <class X>
644  inline QWeakPointer<T> &operator=(const QSharedPointer<X> &o)
645  {
646  QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X); // if you get an error in this line, the cast is invalid
647  internalSet(o.d, o.data());
648  return *this;
649  }
650 
651  template <class X>
652  inline bool operator==(const QSharedPointer<X> &o) const
653  { return d == o.d; }
654 
655  template <class X>
656  inline bool operator!=(const QSharedPointer<X> &o) const
657  { return !(*this == o); }
658 
659  inline void clear() { *this = QWeakPointer<T>(); }
660 
661  inline QSharedPointer<T> toStrongRef() const { return QSharedPointer<T>(*this); }
662 
663 #if defined(QWEAKPOINTER_ENABLE_ARROW)
664  inline T *operator->() const { return data(); }
665 #endif
666 
667 private:
668 
669 #if defined(Q_NO_TEMPLATE_FRIENDS)
670 public:
671 #else
672  template <class X> friend class QSharedPointer;
673 #endif
674 
675  inline void internalSet(Data *o, T *actual)
676  {
677  if (d == o) return;
678  if (o)
679  o->weakref.ref();
680  if (d && !d->weakref.deref())
681  delete d;
682  d = o;
683  value = actual;
684  }
685 
686  Data *d;
687  T *value;
688 };
689 
690 //
691 // operator== and operator!=
692 //
693 template <class T, class X>
694 bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
695 {
696  return ptr1.data() == ptr2.data();
697 }
698 template <class T, class X>
699 bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
700 {
701  return ptr1.data() != ptr2.data();
702 }
703 
704 template <class T, class X>
705 bool operator==(const QSharedPointer<T> &ptr1, const X *ptr2)
706 {
707  return ptr1.data() == ptr2;
708 }
709 template <class T, class X>
710 bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2)
711 {
712  return ptr1 == ptr2.data();
713 }
714 template <class T, class X>
715 bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2)
716 {
717  return !(ptr1 == ptr2);
718 }
719 template <class T, class X>
720 bool operator!=(const T *ptr1, const QSharedPointer<X> &ptr2)
721 {
722  return !(ptr2 == ptr1);
723 }
724 
725 template <class T, class X>
726 bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
727 {
728  return ptr2 == ptr1;
729 }
730 template <class T, class X>
731 bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
732 {
733  return ptr2 != ptr1;
734 }
735 
736 //
737 // operator-
738 //
739 template <class T, class X>
741 {
742  return ptr1.data() - ptr2.data();
743 }
744 template <class T, class X>
746 {
747  return ptr1.data() - ptr2;
748 }
749 template <class T, class X>
751 {
752  return ptr1 - ptr2.data();
753 }
754 
755 //
756 // operator<
757 //
758 template <class T, class X>
759 Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
760 {
761  return ptr1.data() < ptr2.data();
762 }
763 template <class T, class X>
764 Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, X *ptr2)
765 {
766  return ptr1.data() < ptr2;
767 }
768 template <class T, class X>
769 Q_INLINE_TEMPLATE bool operator<(T *ptr1, const QSharedPointer<X> &ptr2)
770 {
771  return ptr1 < ptr2.data();
772 }
773 
774 //
775 // qHash
776 //
777 template <class T> inline uint qHash(const T *key); // defined in qhash.h
778 template <class T>
780 {
781  return QT_PREPEND_NAMESPACE(qHash)<T>(ptr.data());
782 }
783 
784 
785 template <class T>
787 {
788  return QWeakPointer<T>(*this);
789 }
790 
791 template <class T>
792 inline void qSwap(QSharedPointer<T> &p1, QSharedPointer<T> &p2)
793 {
794  p1.swap(p2);
795 }
796 
797 #ifndef QT_NO_STL
799 namespace std {
800  template <class T>
802  { p1.swap(p2); }
803 }
805 #endif
806 
807 namespace QtSharedPointer {
808 // helper functions:
809  template <class X, class T>
810  Q_INLINE_TEMPLATE QSharedPointer<X> copyAndSetPointer(X *ptr, const QSharedPointer<T> &src)
811  {
812  QSharedPointer<X> result;
813  result.internalSet(src.d, ptr);
814  return result;
815  }
816 }
817 
818 // cast operators
819 template <class X, class T>
821 {
822  register X *ptr = static_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
823  return QtSharedPointer::copyAndSetPointer(ptr, src);
824 }
825 template <class X, class T>
827 {
828  return qSharedPointerCast<X, T>(src.toStrongRef());
829 }
830 
831 template <class X, class T>
833 {
834  register X *ptr = dynamic_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
835  if (!ptr)
836  return QSharedPointer<X>();
837  return QtSharedPointer::copyAndSetPointer(ptr, src);
838 }
839 template <class X, class T>
841 {
842  return qSharedPointerDynamicCast<X, T>(src.toStrongRef());
843 }
844 
845 template <class X, class T>
847 {
848  register X *ptr = const_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
849  return QtSharedPointer::copyAndSetPointer(ptr, src);
850 }
851 template <class X, class T>
853 {
854  return qSharedPointerConstCast<X, T>(src.toStrongRef());
855 }
856 
857 template <class X, class T>
860 {
861  return qSharedPointerCast<X, T>(src).toWeakRef();
862 }
863 
864 #ifndef QT_NO_QOBJECT
865 template <class X, class T>
867 {
868  register X *ptr = qobject_cast<X *>(src.data());
869  return QtSharedPointer::copyAndSetPointer(ptr, src);
870 }
871 template <class X, class T>
873 {
874  return qSharedPointerObjectCast<X>(src.toStrongRef());
875 }
876 
877 template <class X, class T>
880 {
882 }
883 template <class X, class T>
885 qobject_cast(const QWeakPointer<T> &src)
886 {
888 }
889 #endif
890 
891 
894 
895 
897 
899 
900 #endif
T qobject_cast(QObject *object)
Definition: qobject.h:375
double d
Definition: qnumeric_p.h:62
uint qHash(const QProcEnvKey &key)
Definition: qprocess_p.h:96
timeval operator-(const timeval &t1, const timeval &t2)
Definition: qcore_unix_p.h:133
QSharedPointer< X > qSharedPointerConstCast(const QSharedPointer< T > &other)
Returns a shared pointer to the pointer held by other, cast to type X.
The QSharedPointer class holds a strong reference to a shared pointer.
QSharedPointer< T > toStrongRef() const
Promotes this weak reference to a strong one and returns a QSharedPointer object holding that referen...
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QSharedPointer< X > qSharedPointerObjectCast(const QSharedPointer< T > &src)
#define QT_MODULE(x)
Definition: qglobal.h:2783
#define QT_BEGIN_HEADER
Definition: qglobal.h:136
static Expression::Ptr create(Expression *const expr, const YYLTYPE &sourceLocator, const ParserContext *const parseInfo)
static void clear(QVariant::Private *d)
Definition: qvariant.cpp:197
QWeakPointer< T > toWeakRef() const
Returns a weak reference object that shares the pointer referenced by this object.
STL namespace.
bool operator!=(QBool b1, bool b2)
Definition: qglobal.h:2026
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
QWeakPointer< X > qWeakPointerCast(const QWeakPointer< T > &src)
QSharedPointer< X > qSharedPointerConstCast(const QSharedPointer< T > &src)
QSharedPointer< X > qSharedPointerDynamicCast(const QSharedPointer< T > &other)
Returns a shared pointer to the pointer held by other, using a dynamic cast to type X to obtain an in...
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QIntegerForSizeof< void * >::Signed qptrdiff
Definition: qglobal.h:987
#define QT_PREPEND_NAMESPACE(name)
This macro qualifies identifier with the full namespace.
Definition: qglobal.h:87
#define Q_INLINE_TEMPLATE
Definition: qglobal.h:1713
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
timeval operator*(const timeval &t1, int mul)
Definition: qcore_unix_p.h:140
const T * ptr(const T &t)
QSharedPointer< X > qSharedPointerCast(const QSharedPointer< T > &other)
void qSwap(T &value1, T &value2)
Definition: qglobal.h:2181
QSharedPointer< X > qSharedPointerDynamicCast(const QSharedPointer< T > &src)
T * data() const
Returns the value of the pointer referenced by this object.
#define Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS)
Definition: qglobal.h:2161
Q_INLINE_TEMPLATE void swap(::QScopedPointer< T, Cleanup > &p1, ::QScopedPointer< T, Cleanup > &p2)
QSharedPointer< X > qSharedPointerObjectCast(const QSharedPointer< T > &other)
The qSharedPointerObjectCast function is for casting a shared pointer.
#define Q_CORE_EXPORT
Definition: qglobal.h:1449
int key
Definition: qnamespace.h:54
Initialization
Definition: qnamespace.h:1729
QSharedPointer< X > qSharedPointerCast(const QSharedPointer< T > &other)
Returns a shared pointer to the pointer held by other, cast to type X.
#define QT_END_HEADER
Definition: qglobal.h:137
bool operator==(QBool b1, bool b2)
Definition: qglobal.h:2023
static bool isNull(const QVariant::Private *d)
Definition: qvariant.cpp:300
The QWeakPointer class holds a weak reference to a shared pointer.