- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files
- Directories
- Examples

- File List
- File Members

# qsharedpointer_impl.h

Go to the documentation of this file.

    00001 /****************************************************************************
    00002 **
    00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    00004 ** All rights reserved.
    00005 ** Contact: Nokia Corporation (qt-info@nokia.com)
    00006 **
    00007 ** This file is part of the QtCore module of the Qt Toolkit.
    00008 **
    00009 ** $QT_BEGIN_LICENSE:LGPL$
    00010 ** Commercial Usage
    00011 ** Licensees holding valid Qt Commercial licenses may use this file in
    00012 ** accordance with the Qt Commercial License Agreement provided with the
    00013 ** Software or, alternatively, in accordance with the terms contained in
    00014 ** a written agreement between you and Nokia.
    00015 **
    00016 ** GNU Lesser General Public License Usage
    00017 ** Alternatively, this file may be used under the terms of the GNU Lesser
    00018 ** General Public License version 2.1 as published by the Free Software
    00019 ** Foundation and appearing in the file LICENSE.LGPL included in the
    00020 ** packaging of this file.  Please review the following information to
    00021 ** ensure the GNU Lesser General Public License version 2.1 requirements
    00022 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    00023 **
    00024 ** In addition, as a special exception, Nokia gives you certain additional
    00025 ** rights.  These rights are described in the Nokia Qt LGPL Exception
    00026 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this module.
    00027 **
    00028 ** GNU General Public License Usage
    00029 ** Alternatively, this file may be used under the terms of the GNU
    00030 ** General Public License version 3.0 as published by the Free Software
    00031 ** Foundation and appearing in the file LICENSE.GPL included in the
    00032 ** packaging of this file.  Please review the following information to
    00033 ** ensure the GNU General Public License version 3.0 requirements will be
    00034 ** met: http://www.gnu.org/copyleft/gpl.html.
    00035 **
    00036 ** If you have questions regarding the use of this file, please contact
    00037 ** Nokia at qt-info@nokia.com.
    00038 ** $QT_END_LICENSE$
    00039 **
    00040 ****************************************************************************/
    00041
    00042 #ifndef Q_QDOC
    00043
    00044 #ifndef QSHAREDPOINTER_H
    00045 #error Do not include qsharedpointer_impl.h directly
    00046 #endif
    00047 #if 0
    00048 #pragma qt_sync_stop_processing
    00049 #endif
    00050
    00051 #include <new>
    00052 #include <QtCore/qatomic.h>
    00053 #include <QtCore/qobject.h>    // for qobject_cast
    00054
    00055 QT_BEGIN_HEADER
    00056
    00057 QT_BEGIN_NAMESPACE
    00058
    00059 QT_MODULE(Core)
    00060
    00061 // Macro QSHAREDPOINTER_VERIFY_AUTO_CAST
    00062 //  generates a compiler error if the following construct isn't valid:
    00063 //    T *ptr1;
    00064 //    X *ptr2 = ptr1;
    00065 //
    00066 #ifdef QT_NO_DEBUG
    00067 # define QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X)          qt_noop()
    00068 #else
    00069
    00070 template<typename T> inline void qt_sharedpointer_cast_check(T *) { }
    00071 # define QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X)          \
    00072     qt_sharedpointer_cast_check<T>(static_cast<X *>(0))
    00073 #endif
    00074
    00075 //
    00076 // forward declarations
    00077 //
    00078 template <class T> class QWeakPointer;
    00079 template <class T> class QSharedPointer;
    00080
    00081 template <class X, class T>
    00082 QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &ptr);
    00083 template <class X, class T>
    00084 QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &ptr);
    00085 template <class X, class T>
    00086 QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &ptr);
    00087
    00088 #ifndef QT_NO_QOBJECT
    00089 template <class X, class T>
    00090 QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &ptr);
    00091 #endif
    00092
    00093 namespace QtSharedPointer {
    00094     template <class T> class InternalRefCount;
    00095     template <class T> class ExternalRefCount;
    00096
    00097     template <class X, class Y> QSharedPointer<X> copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
    00098
    00099     // used in debug mode to verify the reuse of pointers
    00100     Q_CORE_EXPORT void internalSafetyCheckAdd2(const void *, const volatile void *);
    00101     Q_CORE_EXPORT void internalSafetyCheckRemove2(const void *);
    00102
    00103     template <class T, typename Klass, typename RetVal>
    00104     inline void executeDeleter(T *t, RetVal (Klass:: *memberDeleter)())
    00105     { (t->*memberDeleter)(); }
    00106     template <class T, typename Deleter>
    00107     inline void executeDeleter(T *t, Deleter d)
    00108     { d(t); }
    00109     template <class T> inline void normalDeleter(T *t) { delete t; }
    00110
    00111     // this uses partial template specialization
    00112     // the only compilers that didn't support this were MSVC 6.0 and 2002
    00113     template <class T> struct RemovePointer;
    00114     template <class T> struct RemovePointer<T *> { typedef T Type; };
    00115     template <class T> struct RemovePointer<QSharedPointer<T> > { typedef T Type; };
    00116     template <class T> struct RemovePointer<QWeakPointer<T> > { typedef T Type; };
    00117
    00118     // This class provides the basic functionality of a pointer wrapper.
    00119     // Its existence is mostly legacy, since originally QSharedPointer
    00120     // could also be used for internally-refcounted objects.
    00121     template <class T>
    00122     class Basic
    00123     {
    00124 #ifndef Q_CC_NOKIAX86
    00125         typedef T *Basic:: *RestrictedBool;
    00126 #endif
    00127     public:
    00128         typedef T Type;
    00129         typedef T element_type;
    00130         typedef T value_type;
    00131         typedef value_type *pointer;
    00132         typedef const value_type *const_pointer;
    00133         typedef value_type &reference;
    00134         typedef const value_type &const_reference;
    00135         typedef qptrdiff difference_type;
    00136
    00137         inline T *data() const { return value; }
    00138         inline bool isNull() const { return !data(); }
    00139 #ifndef Q_CC_NOKIAX86
    00140         inline operator RestrictedBool() const { return isNull() ? 0 : &Basic::value; }
    00141 #else
    00142         inline operator bool() const { return isNull() ? 0 : &Basic::value; }
    00143 #endif
    00144         inline bool operator !() const { return isNull(); }
    00145         inline T &operator*() const { return *data(); }
    00146         inline T *operator->() const { return data(); }
    00147
    00148     protected:
    00149         inline Basic(T *ptr = 0) : value(ptr) { }
    00150         inline Basic(Qt::Initialization) { }
    00151         // ~Basic();
    00152
    00153         inline void internalConstruct(T *ptr)
    00154         {
    00155             value = ptr;
    00156         }
    00157
    00158 #if defined(Q_NO_TEMPLATE_FRIENDS)
    00159     public:
    00160 #else
    00161         template <class X> friend class QT_PREPEND_NAMESPACE(QWeakPointer);
    00162 #endif
    00163
    00164         Type *value;
    00165     };
    00166
    00167     // This class is the d-pointer of QSharedPointer and QWeakPointer.
    00168     //
    00169     // It is a reference-counted reference counter. "strongref" is the inner
    00170     // reference counter, and it tracks the lifetime of the pointer itself.
    00171     // "weakref" is the outer reference counter and it tracks the lifetime of
    00172     // the ExternalRefCountData object.
    00173     struct ExternalRefCountData
    00174     {
    00175         QBasicAtomicInt weakref;
    00176         QBasicAtomicInt strongref;
    00177
    00178         inline ExternalRefCountData()
    00179         {
    00180             strongref = 1;
    00181             weakref = 1;
    00182         }
    00183         inline ExternalRefCountData(Qt::Initialization) { }
    00184         virtual inline ~ExternalRefCountData() { Q_ASSERT(!weakref); Q_ASSERT(strongref <= 0); }
    00185
    00186         // overridden by derived classes
    00187         // returns false to indicate caller should delete the pointer
    00188         // returns true in case it has already done so
    00189         virtual inline bool destroy() { return false; }
    00190
    00191 #ifndef QT_NO_QOBJECT
    00192         Q_CORE_EXPORT static ExternalRefCountData *getAndRef(const QObject *);
    00193         Q_CORE_EXPORT void setQObjectShared(const QObject *, bool enable);
    00194 #endif
    00195         inline void setQObjectShared(...) { }
    00196     };
    00197     // sizeof(ExternalRefCount) = 12 (32-bit) / 16 (64-bit)
    00198
    00199     // This class extends ExternalRefCountData with a pointer
    00200     // to a function, which is called by the destroy() function.
    00201     struct ExternalRefCountWithDestroyFn: public ExternalRefCountData
    00202     {
    00203         typedef void (*DestroyerFn)(ExternalRefCountData *);
    00204         DestroyerFn destroyer;
    00205
    00206         inline ExternalRefCountWithDestroyFn(DestroyerFn d)
    00207             : destroyer(d)
    00208         { }
    00209
    00210         inline bool destroy() { destroyer(this); return true; }
    00211         inline void operator delete(void *ptr) { ::operator delete(ptr); }
    00212         inline void operator delete(void *, void *) { }
    00213     };
    00214     // sizeof(ExternalRefCountWithDestroyFn) = 16 (32-bit) / 24 (64-bit)
    00215
    00216     // This class extends ExternalRefCountWithDestroyFn and implements
    00217     // the static function that deletes the object. The pointer and the
    00218     // custom deleter are kept in the "extra" member.
    00219     template <class T, typename Deleter>
    00220     struct ExternalRefCountWithCustomDeleter: public ExternalRefCountWithDestroyFn
    00221     {
    00222         typedef ExternalRefCountWithCustomDeleter Self;
    00223         typedef ExternalRefCountWithDestroyFn BaseClass;
    00224
    00225         struct CustomDeleter
    00226         {
    00227             Deleter deleter;
    00228             T *ptr;
    00229
    00230             inline CustomDeleter(T *p, Deleter d) : deleter(d), ptr(p) {}
    00231         };
    00232         CustomDeleter extra;
    00233         // sizeof(CustomDeleter) = sizeof(Deleter) + sizeof(void*)
    00234         // for Deleter = function pointer:  8 (32-bit) / 16 (64-bit)
    00235         // for Deleter = PMF: 12 (32-bit) / 24 (64-bit)  (GCC)
    00236
    00237         static inline void deleter(ExternalRefCountData *self)
    00238         {
    00239             Self *realself = static_cast<Self *>(self);
    00240             executeDeleter(realself->extra.ptr, realself->extra.deleter);
    00241
    00242             // delete the deleter too
    00243             realself->extra.~CustomDeleter();
    00244         }
    00245         static void safetyCheckDeleter(ExternalRefCountData *self)
    00246         {
    00247             internalSafetyCheckRemove2(self);
    00248             deleter(self);
    00249         }
    00250
    00251         static inline Self *create(T *ptr, Deleter userDeleter)
    00252         {
    00253 # ifdef QT_SHAREDPOINTER_TRACK_POINTERS
    00254             DestroyerFn destroy = &safetyCheckDeleter;
    00255 # else
    00256             DestroyerFn destroy = &deleter;
    00257 # endif
    00258             Self *d = static_cast<Self *>(::operator new(sizeof(Self)));
    00259
    00260             // initialize the two sub-objects
    00261             new (&d->extra) CustomDeleter(ptr, userDeleter);
    00262             new (d) BaseClass(destroy); // can't throw
    00263
    00264             return d;
    00265         }
    00266     private:
    00267         // prevent construction and the emission of virtual symbols
    00268         ExternalRefCountWithCustomDeleter();
    00269         ~ExternalRefCountWithCustomDeleter();
    00270     };
    00271
    00272     // This class extends ExternalRefCountWithDestroyFn and adds a "T"
    00273     // member. That way, when the create() function is called, we allocate
    00274     // memory for both QSharedPointer's d-pointer and the actual object being
    00275     // tracked.
    00276     template <class T>
    00277     struct ExternalRefCountWithContiguousData: public ExternalRefCountWithDestroyFn
    00278     {
    00279         typedef ExternalRefCountWithDestroyFn Parent;
    00280         T data;
    00281
    00282         static void deleter(ExternalRefCountData *self)
    00283         {
    00284             ExternalRefCountWithContiguousData *that =
    00285                     static_cast<ExternalRefCountWithContiguousData *>(self);
    00286             that->data.~T();
    00287         }
    00288         static void safetyCheckDeleter(ExternalRefCountData *self)
    00289         {
    00290             internalSafetyCheckRemove2(self);
    00291             deleter(self);
    00292         }
    00293
    00294         static inline ExternalRefCountData *create(T **ptr)
    00295         {
    00296 # ifdef QT_SHAREDPOINTER_TRACK_POINTERS
    00297             DestroyerFn destroy = &safetyCheckDeleter;
    00298 # else
    00299             DestroyerFn destroy = &deleter;
    00300 # endif
    00301             ExternalRefCountWithContiguousData *d =
    00302                 static_cast<ExternalRefCountWithContiguousData *>(::operator new(sizeof(ExternalRefCountWithContiguousData)));
    00303
    00304             // initialize the d-pointer sub-object
    00305             // leave d->data uninitialized
    00306             new (d) Parent(destroy); // can't throw
    00307
    00308             *ptr = &d->data;
    00309             return d;
    00310         }
    00311
    00312     private:
    00313         // prevent construction and the emission of virtual symbols
    00314         ExternalRefCountWithContiguousData();
    00315         ~ExternalRefCountWithContiguousData();
    00316     };
    00317
    00318     // This is the main body of QSharedPointer. It implements the
    00319     // external reference counting functionality.
    00320     template <class T>
    00321     class ExternalRefCount: public Basic<T>
    00322     {
    00323     protected:
    00324         typedef ExternalRefCountData Data;
    00325
    00326         inline void ref() const { d->weakref.ref(); d->strongref.ref(); }
    00327         inline void deref()
    00328         { deref(d, this->value); }
    00329         static inline void deref(Data *d, T *value)
    00330         {
    00331             if (!d) return;
    00332             if (!d->strongref.deref()) {
    00333                 if (!d->destroy())
    00334                     delete value;
    00335             }
    00336             if (!d->weakref.deref())
    00337                 delete d;
    00338         }
    00339
    00340         inline void internalConstruct(T *ptr)
    00341         {
    00342 #ifdef QT_SHAREDPOINTER_TRACK_POINTERS
    00343             internalConstruct<void (*)(T *)>(ptr, normalDeleter);
    00344 #else
    00345             if (ptr)
    00346                 d = new Data;
    00347             else
    00348                 d = 0;
    00349             internalFinishConstruction(ptr);
    00350 #endif
    00351         }
    00352
    00353         template <typename Deleter>
    00354         inline void internalConstruct(T *ptr, Deleter deleter)
    00355         {
    00356             if (ptr)
    00357                 d = ExternalRefCountWithCustomDeleter<T, Deleter>::create(ptr, deleter);
    00358             else
    00359                 d = 0;
    00360             internalFinishConstruction(ptr);
    00361         }
    00362
    00363         inline void internalCreate()
    00364         {
    00365             T *ptr;
    00366             d = ExternalRefCountWithContiguousData<T>::create(&ptr);
    00367             Basic<T>::internalConstruct(ptr);
    00368         }
    00369
    00370         inline void internalFinishConstruction(T *ptr)
    00371         {
    00372             Basic<T>::internalConstruct(ptr);
    00373             if (ptr) d->setQObjectShared(ptr, true);
    00374 #ifdef QT_SHAREDPOINTER_TRACK_POINTERS
    00375             if (ptr) internalSafetyCheckAdd2(d, ptr);
    00376 #endif
    00377         }
    00378
    00379         inline ExternalRefCount() : d(0) { }
    00380         inline ExternalRefCount(Qt::Initialization i) : Basic<T>(i) { }
    00381         inline ExternalRefCount(const ExternalRefCount<T> &other) : Basic<T>(other), d(other.d)
    00382         { if (d) ref(); }
    00383         template <class X>
    00384         inline ExternalRefCount(const ExternalRefCount<X> &other) : Basic<T>(other.value), d(other.d)
    00385         { if (d) ref(); }
    00386         inline ~ExternalRefCount() { deref(); }
    00387
    00388         template <class X>
    00389         inline void internalCopy(const ExternalRefCount<X> &other)
    00390         {
    00391             internalSet(other.d, other.data());
    00392         }
    00393
    00394         inline void internalSwap(ExternalRefCount &other)
    00395         {
    00396             qSwap(d, other.d);
    00397             qSwap(this->value, other.value);
    00398         }
    00399
    00400 #if defined(Q_NO_TEMPLATE_FRIENDS)
    00401     public:
    00402 #else
    00403         template <class X> friend class ExternalRefCount;
    00404         template <class X> friend class QT_PREPEND_NAMESPACE(QWeakPointer);
    00405         template <class X, class Y> friend QSharedPointer<X> copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
    00406 #endif
    00407
    00408         inline void internalSet(Data *o, T *actual)
    00409         {
    00410             if (o) {
    00411                 // increase the strongref, but never up from zero
    00412                 // or less (-1 is used by QWeakPointer on untracked QObject)
    00413                 register int tmp = o->strongref;
    00414                 while (tmp > 0) {
    00415                     // try to increment from "tmp" to "tmp + 1"
    00416                     if (o->strongref.testAndSetRelaxed(tmp, tmp + 1))
    00417                         break;   // succeeded
    00418                     tmp = o->strongref;  // failed, try again
    00419                 }
    00420
    00421                 if (tmp > 0)
    00422                     o->weakref.ref();
    00423                 else
    00424                     o = 0;
    00425             }
    00426
    00427             qSwap(d, o);
    00428             qSwap(this->value, actual);
    00429             if (!d || d->strongref == 0)
    00430                 this->value = 0;
    00431
    00432             // dereference saved data
    00433             deref(o, actual);
    00434         }
    00435
    00436         Data *d;
    00437
    00438     private:
    00439         template<class X> ExternalRefCount(const InternalRefCount<X> &);
    00440     };
    00441 } // namespace QtSharedPointer
    00442
    00443 template <class T>
    00444 class QSharedPointer: public QtSharedPointer::ExternalRefCount<T>
    00445 {
    00446     typedef typename QtSharedPointer::ExternalRefCount<T> BaseClass;
    00447 public:
    00448     inline QSharedPointer() { }
    00449     // inline ~QSharedPointer() { }
    00450
    00451     inline explicit QSharedPointer(T *ptr) : BaseClass(Qt::Uninitialized)
    00452     { BaseClass::internalConstruct(ptr); }
    00453
    00454     template <typename Deleter>
    00455     inline QSharedPointer(T *ptr, Deleter d) { BaseClass::internalConstruct(ptr, d); }
    00456
    00457     inline QSharedPointer(const QSharedPointer<T> &other) : BaseClass(other) { }
    00458     inline QSharedPointer<T> &operator=(const QSharedPointer<T> &other)
    00459     {
    00460         BaseClass::internalCopy(other);
    00461         return *this;
    00462     }
    00463
    00464     template <class X>
    00465     inline QSharedPointer(const QSharedPointer<X> &other) : BaseClass(other)
    00466     { }
    00467
    00468     template <class X>
    00469     inline QSharedPointer<T> &operator=(const QSharedPointer<X> &other)
    00470     {
    00471         QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X); // if you get an error in this line, the cast is invalid
    00472         BaseClass::internalCopy(other);
    00473         return *this;
    00474     }
    00475
    00476     template <class X>
    00477     inline QSharedPointer(const QWeakPointer<X> &other) : BaseClass(Qt::Uninitialized)
    00478     { this->d = 0; *this = other; }
    00479
    00480     template <class X>
    00481     inline QSharedPointer<T> &operator=(const QWeakPointer<X> &other)
    00482     { BaseClass::internalSet(other.d, other.value); return *this; }
    00483
    00484     inline void swap(QSharedPointer &other)
    00485     { QSharedPointer<T>::internalSwap(other); }
    00486
    00487     template <class X>
    00488     QSharedPointer<X> staticCast() const
    00489     {
    00490         return qSharedPointerCast<X, T>(*this);
    00491     }
    00492
    00493     template <class X>
    00494     QSharedPointer<X> dynamicCast() const
    00495     {
    00496         return qSharedPointerDynamicCast<X, T>(*this);
    00497     }
    00498
    00499     template <class X>
    00500     QSharedPointer<X> constCast() const
    00501     {
    00502         return qSharedPointerConstCast<X, T>(*this);
    00503     }
    00504
    00505 #ifndef QT_NO_QOBJECT
    00506     template <class X>
    00507     QSharedPointer<X> objectCast() const
    00508     {
    00509         return qSharedPointerObjectCast<X, T>(*this);
    00510     }
    00511 #endif
    00512
    00513     inline void clear() { *this = QSharedPointer<T>(); }
    00514
    00515     QWeakPointer<T> toWeakRef() const;
    00516
    00517 protected:
    00518     inline explicit QSharedPointer(Qt::Initialization i) : BaseClass(i) {}
    00519
    00520 public:
    00521     static inline QSharedPointer<T> create()
    00522     {
    00523         QSharedPointer<T> result(Qt::Uninitialized);
    00524         result.internalCreate();
    00525
    00526         // now initialize the data
    00527         new (result.data()) T();
    00528         result.internalFinishConstruction(result.data());
    00529         return result;
    00530     }
    00531 };
    00532
    00533 template <class T>
    00534 class QWeakPointer
    00535 {
    00536 #ifndef Q_CC_NOKIAX86
    00537     typedef T *QWeakPointer:: *RestrictedBool;
    00538 #endif
    00539     typedef QtSharedPointer::ExternalRefCountData Data;
    00540
    00541 public:
    00542     typedef T element_type;
    00543     typedef T value_type;
    00544     typedef value_type *pointer;
    00545     typedef const value_type *const_pointer;
    00546     typedef value_type &reference;
    00547     typedef const value_type &const_reference;
    00548     typedef qptrdiff difference_type;
    00549
    00550     inline bool isNull() const { return d == 0 || d->strongref == 0 || value == 0; }
    00551 #ifndef Q_CC_NOKIAX86
    00552     inline operator RestrictedBool() const { return isNull() ? 0 : &QWeakPointer::value; }
    00553 #else
    00554     inline operator bool() const { return isNull() ? 0 : &QWeakPointer::value; }
    00555 #endif
    00556     inline bool operator !() const { return isNull(); }
    00557     inline T *data() const { return d == 0 || d->strongref == 0 ? 0 : value; }
    00558
    00559     inline QWeakPointer() : d(0), value(0) { }
    00560     inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; }
    00561
    00562 #ifndef QT_NO_QOBJECT
    00563     // special constructor that is enabled only if X derives from QObject
    00564     template <class X>
    00565     inline QWeakPointer(X *ptr) : d(ptr ? d->getAndRef(ptr) : 0), value(ptr)
    00566     { }
    00567 #endif
    00568     template <class X>
    00569     inline QWeakPointer &operator=(X *ptr)
    00570     { return *this = QWeakPointer(ptr); }
    00571
    00572     inline QWeakPointer(const QWeakPointer<T> &o) : d(o.d), value(o.value)
    00573     { if (d) d->weakref.ref(); }
    00574     inline QWeakPointer<T> &operator=(const QWeakPointer<T> &o)
    00575     {
    00576         internalSet(o.d, o.value);
    00577         return *this;
    00578     }
    00579
    00580     inline QWeakPointer(const QSharedPointer<T> &o) : d(o.d), value(o.data())
    00581     { if (d) d->weakref.ref();}
    00582     inline QWeakPointer<T> &operator=(const QSharedPointer<T> &o)
    00583     {
    00584         internalSet(o.d, o.value);
    00585         return *this;
    00586     }
    00587
    00588     template <class X>
    00589     inline QWeakPointer(const QWeakPointer<X> &o) : d(0), value(0)
    00590     { *this = o; }
    00591
    00592     template <class X>
    00593     inline QWeakPointer<T> &operator=(const QWeakPointer<X> &o)
    00594     {
    00595         // conversion between X and T could require access to the virtual table
    00596         // so force the operation to go through QSharedPointer
    00597         *this = o.toStrongRef();
    00598         return *this;
    00599     }
    00600
    00601     template <class X>
    00602     inline bool operator==(const QWeakPointer<X> &o) const
    00603     { return d == o.d && value == static_cast<const T *>(o.value); }
    00604
    00605     template <class X>
    00606     inline bool operator!=(const QWeakPointer<X> &o) const
    00607     { return !(*this == o); }
    00608
    00609     template <class X>
    00610     inline QWeakPointer(const QSharedPointer<X> &o) : d(0), value(0)
    00611     { *this = o; }
    00612
    00613     template <class X>
    00614     inline QWeakPointer<T> &operator=(const QSharedPointer<X> &o)
    00615     {
    00616         QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X); // if you get an error in this line, the cast is invalid
    00617         internalSet(o.d, o.data());
    00618         return *this;
    00619     }
    00620
    00621     template <class X>
    00622     inline bool operator==(const QSharedPointer<X> &o) const
    00623     { return d == o.d; }
    00624
    00625     template <class X>
    00626     inline bool operator!=(const QSharedPointer<X> &o) const
    00627     { return !(*this == o); }
    00628
    00629     inline void clear() { *this = QWeakPointer<T>(); }
    00630
    00631     inline QSharedPointer<T> toStrongRef() const { return QSharedPointer<T>(*this); }
    00632
    00633 #if defined(QWEAKPOINTER_ENABLE_ARROW)
    00634     inline T *operator->() const { return data(); }
    00635 #endif
    00636
    00637 private:
    00638
    00639 #if defined(Q_NO_TEMPLATE_FRIENDS)
    00640 public:
    00641 #else
    00642     template <class X> friend class QSharedPointer;
    00643 #endif
    00644
    00645     inline void internalSet(Data *o, T *actual)
    00646     {
    00647         if (d == o) return;
    00648         if (o)
    00649             o->weakref.ref();
    00650         if (d && !d->weakref.deref())
    00651             delete d;
    00652         d = o;
    00653         value = actual;
    00654     }
    00655
    00656     Data *d;
    00657     T *value;
    00658 };
    00659
    00660 //
    00661 // operator== and operator!=
    00662 //
    00663 template <class T, class X>
    00664 bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
    00665 {
    00666     return ptr1.data() == ptr2.data();
    00667 }
    00668 template <class T, class X>
    00669 bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
    00670 {
    00671     return ptr1.data() != ptr2.data();
    00672 }
    00673
    00674 template <class T, class X>
    00675 bool operator==(const QSharedPointer<T> &ptr1, const X *ptr2)
    00676 {
    00677     return ptr1.data() == ptr2;
    00678 }
    00679 template <class T, class X>
    00680 bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2)
    00681 {
    00682     return ptr1 == ptr2.data();
    00683 }
    00684 template <class T, class X>
    00685 bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2)
    00686 {
    00687     return !(ptr1 == ptr2);
    00688 }
    00689 template <class T, class X>
    00690 bool operator!=(const T *ptr1, const QSharedPointer<X> &ptr2)
    00691 {
    00692     return !(ptr2 == ptr1);
    00693 }
    00694
    00695 template <class T, class X>
    00696 bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
    00697 {
    00698     return ptr2 == ptr1;
    00699 }
    00700 template <class T, class X>
    00701 bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
    00702 {
    00703     return ptr2 != ptr1;
    00704 }
    00705
    00706 //
    00707 // operator-
    00708 //
    00709 template <class T, class X>
    00710 Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
    00711 {
    00712     return ptr1.data() - ptr2.data();
    00713 }
    00714 template <class T, class X>
    00715 Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, X *ptr2)
    00716 {
    00717     return ptr1.data() - ptr2;
    00718 }
    00719 template <class T, class X>
    00720 Q_INLINE_TEMPLATE typename QSharedPointer<X>::difference_type operator-(T *ptr1, const QSharedPointer<X> &ptr2)
    00721 {
    00722     return ptr1 - ptr2.data();
    00723 }
    00724
    00725 //
    00726 // operator<
    00727 //
    00728 template <class T, class X>
    00729 Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
    00730 {
    00731     return ptr1.data() < ptr2.data();
    00732 }
    00733 template <class T, class X>
    00734 Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, X *ptr2)
    00735 {
    00736     return ptr1.data() < ptr2;
    00737 }
    00738 template <class T, class X>
    00739 Q_INLINE_TEMPLATE bool operator<(T *ptr1, const QSharedPointer<X> &ptr2)
    00740 {
    00741     return ptr1 < ptr2.data();
    00742 }
    00743
    00744 //
    00745 // qHash
    00746 //
    00747 template <class T> inline uint qHash(const T *key); // defined in qhash.h
    00748 template <class T>
    00749 Q_INLINE_TEMPLATE uint qHash(const QSharedPointer<T> &ptr)
    00750 {
    00751     return QT_PREPEND_NAMESPACE(qHash)<T>(ptr.data());
    00752 }
    00753
    00754
    00755 template <class T>
    00756 Q_INLINE_TEMPLATE QWeakPointer<T> QSharedPointer<T>::toWeakRef() const
    00757 {
    00758     return QWeakPointer<T>(*this);
    00759 }
    00760
    00761 template <class T>
    00762 inline void qSwap(QSharedPointer<T> &p1, QSharedPointer<T> &p2)
    00763 {
    00764     p1.swap(p2);
    00765 }
    00766
    00767 namespace QtSharedPointer {
    00768 // helper functions:
    00769     template <class X, class T>
    00770     Q_INLINE_TEMPLATE QSharedPointer<X> copyAndSetPointer(X *ptr, const QSharedPointer<T> &src)
    00771     {
    00772         QSharedPointer<X> result;
    00773         result.internalSet(src.d, ptr);
    00774         return result;
    00775     }
    00776 }
    00777
    00778 // cast operators
    00779 template <class X, class T>
    00780 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &src)
    00781 {
    00782     register X *ptr = static_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
    00783     return QtSharedPointer::copyAndSetPointer(ptr, src);
    00784 }
    00785 template <class X, class T>
    00786 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &src)
    00787 {
    00788     return qSharedPointerCast<X, T>(src.toStrongRef());
    00789 }
    00790
    00791 template <class X, class T>
    00792 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &src)
    00793 {
    00794     register X *ptr = dynamic_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
    00795     return QtSharedPointer::copyAndSetPointer(ptr, src);
    00796 }
    00797 template <class X, class T>
    00798 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer<T> &src)
    00799 {
    00800     return qSharedPointerDynamicCast<X, T>(src.toStrongRef());
    00801 }
    00802
    00803 template <class X, class T>
    00804 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &src)
    00805 {
    00806     register X *ptr = const_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
    00807     return QtSharedPointer::copyAndSetPointer(ptr, src);
    00808 }
    00809 template <class X, class T>
    00810 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(const QWeakPointer<T> &src)
    00811 {
    00812     return qSharedPointerConstCast<X, T>(src.toStrongRef());
    00813 }
    00814
    00815 template <class X, class T>
    00816 Q_INLINE_TEMPLATE
    00817 QWeakPointer<X> qWeakPointerCast(const QSharedPointer<T> &src)
    00818 {
    00819     return qSharedPointerCast<X, T>(src).toWeakRef();
    00820 }
    00821
    00822 #ifndef QT_NO_QOBJECT
    00823 template <class X, class T>
    00824 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &src)
    00825 {
    00826     register X *ptr = qobject_cast<X *>(src.data());
    00827     return QtSharedPointer::copyAndSetPointer(ptr, src);
    00828 }
    00829 template <class X, class T>
    00830 Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(const QWeakPointer<T> &src)
    00831 {
    00832     return qSharedPointerObjectCast<X>(src.toStrongRef());
    00833 }
    00834
    00835 template <class X, class T>
    00836 inline QSharedPointer<typename QtSharedPointer::RemovePointer<X>::Type>
    00837 qobject_cast(const QSharedPointer<T> &src)
    00838 {
    00839     return qSharedPointerObjectCast<typename QtSharedPointer::RemovePointer<X>::Type, T>(src);
    00840 }
    00841 template <class X, class T>
    00842 inline QSharedPointer<typename QtSharedPointer::RemovePointer<X>::Type>
    00843 qobject_cast(const QWeakPointer<T> &src)
    00844 {
    00845     return qSharedPointerObjectCast<typename QtSharedPointer::RemovePointer<X>::Type, T>(src);
    00846 }
    00847
    00848 #endif
    00849
    00850 QT_END_NAMESPACE
    00851
    00852 QT_END_HEADER
    00853
    00854 #endif