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