summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qsharedpointer_impl.h
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /src/corelib/tools/qsharedpointer_impl.h
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/corelib/tools/qsharedpointer_impl.h')
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h898
1 files changed, 898 insertions, 0 deletions
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
new file mode 100644
index 0000000000..b29e5b69e3
--- /dev/null
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -0,0 +1,898 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q_QDOC
+
+#ifndef QSHAREDPOINTER_H
+#error Do not include qsharedpointer_impl.h directly
+#endif
+
+#if 0
+// These macros are duplicated here to make syncqt not complain a about
+// this header, as we have a "qt_sync_stop_processing" below, which in turn
+// is here because this file contains a template mess and duplicates the
+// classes found in qsharedpointer.h
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+QT_MODULE(Core)
+QT_END_NAMESPACE
+QT_END_HEADER
+#pragma qt_sync_stop_processing
+#endif
+
+#include <new>
+#include <QtCore/qatomic.h>
+#include <QtCore/qobject.h> // for qobject_cast
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+// Macro QSHAREDPOINTER_VERIFY_AUTO_CAST
+// generates a compiler error if the following construct isn't valid:
+// T *ptr1;
+// X *ptr2 = ptr1;
+//
+#ifdef QT_NO_DEBUG
+# define QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X) qt_noop()
+#else
+
+template<typename T> inline void qt_sharedpointer_cast_check(T *) { }
+# define QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X) \
+ qt_sharedpointer_cast_check<T>(static_cast<X *>(0))
+#endif
+
+//
+// forward declarations
+//
+template <class T> class QWeakPointer;
+template <class T> class QSharedPointer;
+
+template <class X, class T>
+QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &ptr);
+template <class X, class T>
+QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &ptr);
+template <class X, class T>
+QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &ptr);
+
+#ifndef QT_NO_QOBJECT
+template <class X, class T>
+QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &ptr);
+#endif
+
+namespace QtSharedPointer {
+ template <class T> class InternalRefCount;
+ template <class T> class ExternalRefCount;
+
+ template <class X, class Y> QSharedPointer<X> copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
+
+ // used in debug mode to verify the reuse of pointers
+ Q_CORE_EXPORT void internalSafetyCheckAdd2(const void *, const volatile void *);
+ Q_CORE_EXPORT void internalSafetyCheckRemove2(const void *);
+
+ template <class T, typename Klass, typename RetVal>
+ inline void executeDeleter(T *t, RetVal (Klass:: *memberDeleter)())
+ { (t->*memberDeleter)(); }
+ template <class T, typename Deleter>
+ inline void executeDeleter(T *t, Deleter d)
+ { d(t); }
+ template <class T> inline void normalDeleter(T *t) { delete t; }
+
+ // this uses partial template specialization
+ template <class T> struct RemovePointer;
+ template <class T> struct RemovePointer<T *> { typedef T Type; };
+ template <class T> struct RemovePointer<QSharedPointer<T> > { typedef T Type; };
+ template <class T> struct RemovePointer<QWeakPointer<T> > { typedef T Type; };
+
+ // This class provides the basic functionality of a pointer wrapper.
+ // Its existence is mostly legacy, since originally QSharedPointer
+ // could also be used for internally-refcounted objects.
+ template <class T>
+ class Basic
+ {
+#ifndef Q_CC_NOKIAX86
+ typedef T *Basic:: *RestrictedBool;
+#endif
+ public:
+ typedef T Type;
+ typedef T element_type;
+ typedef T value_type;
+ typedef value_type *pointer;
+ typedef const value_type *const_pointer;
+ typedef value_type &reference;
+ typedef const value_type &const_reference;
+ typedef qptrdiff difference_type;
+
+ inline T *data() const { return value; }
+ inline bool isNull() const { return !data(); }
+#ifndef Q_CC_NOKIAX86
+ inline operator RestrictedBool() const { return isNull() ? 0 : &Basic::value; }
+#else
+ inline operator bool() const { return isNull() ? 0 : &Basic::value; }
+#endif
+ inline bool operator !() const { return isNull(); }
+ inline T &operator*() const { return *data(); }
+ inline T *operator->() const { return data(); }
+
+ protected:
+ inline Basic(T *ptr = 0) : value(ptr) { }
+ inline Basic(Qt::Initialization) { }
+ // ~Basic();
+
+ inline void internalConstruct(T *ptr)
+ {
+ value = ptr;
+ }
+
+#if defined(Q_NO_TEMPLATE_FRIENDS)
+ public:
+#else
+ template <class X> friend class QT_PREPEND_NAMESPACE(QWeakPointer);
+#endif
+
+ Type *value;
+ };
+
+ // This class is the d-pointer of QSharedPointer and QWeakPointer.
+ //
+ // It is a reference-counted reference counter. "strongref" is the inner
+ // reference counter, and it tracks the lifetime of the pointer itself.
+ // "weakref" is the outer reference counter and it tracks the lifetime of
+ // the ExternalRefCountData object.
+ struct ExternalRefCountData
+ {
+ QBasicAtomicInt weakref;
+ QBasicAtomicInt strongref;
+
+ inline ExternalRefCountData()
+ {
+ strongref = 1;
+ weakref = 1;
+ }
+ inline ExternalRefCountData(Qt::Initialization) { }
+ virtual inline ~ExternalRefCountData() { Q_ASSERT(!weakref); Q_ASSERT(strongref <= 0); }
+
+ // overridden by derived classes
+ // returns false to indicate caller should delete the pointer
+ // returns true in case it has already done so
+ virtual inline bool destroy() { return false; }
+
+#ifndef QT_NO_QOBJECT
+ Q_CORE_EXPORT static ExternalRefCountData *getAndRef(const QObject *);
+ Q_CORE_EXPORT void setQObjectShared(const QObject *, bool enable);
+#endif
+ inline void setQObjectShared(...) { }
+ };
+ // sizeof(ExternalRefCount) = 12 (32-bit) / 16 (64-bit)
+
+ // This class extends ExternalRefCountData with a pointer
+ // to a function, which is called by the destroy() function.
+ struct ExternalRefCountWithDestroyFn: public ExternalRefCountData
+ {
+ typedef void (*DestroyerFn)(ExternalRefCountData *);
+ DestroyerFn destroyer;
+
+ inline ExternalRefCountWithDestroyFn(DestroyerFn d)
+ : destroyer(d)
+ { }
+
+ inline bool destroy() { destroyer(this); return true; }
+ inline void operator delete(void *ptr) { ::operator delete(ptr); }
+ inline void operator delete(void *, void *) { }
+ };
+ // sizeof(ExternalRefCountWithDestroyFn) = 16 (32-bit) / 24 (64-bit)
+
+ // This class extends ExternalRefCountWithDestroyFn and implements
+ // the static function that deletes the object. The pointer and the
+ // custom deleter are kept in the "extra" member.
+ template <class T, typename Deleter>
+ struct ExternalRefCountWithCustomDeleter: public ExternalRefCountWithDestroyFn
+ {
+ typedef ExternalRefCountWithCustomDeleter Self;
+ typedef ExternalRefCountWithDestroyFn BaseClass;
+
+ struct CustomDeleter
+ {
+ Deleter deleter;
+ T *ptr;
+
+ inline CustomDeleter(T *p, Deleter d) : deleter(d), ptr(p) {}
+ };
+ CustomDeleter extra;
+ // sizeof(CustomDeleter) = sizeof(Deleter) + sizeof(void*)
+ // for Deleter = function pointer: 8 (32-bit) / 16 (64-bit)
+ // for Deleter = PMF: 12 (32-bit) / 24 (64-bit) (GCC)
+
+ static inline void deleter(ExternalRefCountData *self)
+ {
+ Self *realself = static_cast<Self *>(self);
+ executeDeleter(realself->extra.ptr, realself->extra.deleter);
+
+ // delete the deleter too
+ realself->extra.~CustomDeleter();
+ }
+ static void safetyCheckDeleter(ExternalRefCountData *self)
+ {
+ internalSafetyCheckRemove2(self);
+ deleter(self);
+ }
+
+ static inline Self *create(T *ptr, Deleter userDeleter)
+ {
+# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
+ DestroyerFn destroy = &safetyCheckDeleter;
+# else
+ DestroyerFn destroy = &deleter;
+# endif
+ Self *d = static_cast<Self *>(::operator new(sizeof(Self)));
+
+ // initialize the two sub-objects
+ new (&d->extra) CustomDeleter(ptr, userDeleter);
+ new (d) BaseClass(destroy); // can't throw
+
+ return d;
+ }
+ private:
+ // prevent construction and the emission of virtual symbols
+ ExternalRefCountWithCustomDeleter();
+ ~ExternalRefCountWithCustomDeleter();
+ };
+
+ // This class extends ExternalRefCountWithDestroyFn and adds a "T"
+ // member. That way, when the create() function is called, we allocate
+ // memory for both QSharedPointer's d-pointer and the actual object being
+ // tracked.
+ template <class T>
+ struct ExternalRefCountWithContiguousData: public ExternalRefCountWithDestroyFn
+ {
+ typedef ExternalRefCountWithDestroyFn Parent;
+ T data;
+
+ static void deleter(ExternalRefCountData *self)
+ {
+ ExternalRefCountWithContiguousData *that =
+ static_cast<ExternalRefCountWithContiguousData *>(self);
+ that->data.~T();
+ }
+ static void safetyCheckDeleter(ExternalRefCountData *self)
+ {
+ internalSafetyCheckRemove2(self);
+ deleter(self);
+ }
+
+ static inline ExternalRefCountData *create(T **ptr)
+ {
+# ifdef QT_SHAREDPOINTER_TRACK_POINTERS
+ DestroyerFn destroy = &safetyCheckDeleter;
+# else
+ DestroyerFn destroy = &deleter;
+# endif
+ ExternalRefCountWithContiguousData *d =
+ static_cast<ExternalRefCountWithContiguousData *>(::operator new(sizeof(ExternalRefCountWithContiguousData)));
+
+ // initialize the d-pointer sub-object
+ // leave d->data uninitialized
+ new (d) Parent(destroy); // can't throw
+
+ *ptr = &d->data;
+ return d;
+ }
+
+ private:
+ // prevent construction and the emission of virtual symbols
+ ExternalRefCountWithContiguousData();
+ ~ExternalRefCountWithContiguousData();
+ };
+
+ // This is the main body of QSharedPointer. It implements the
+ // external reference counting functionality.
+ template <class T>
+ class ExternalRefCount: public Basic<T>
+ {
+ protected:
+ typedef ExternalRefCountData Data;
+
+ inline void deref()
+ { deref(d, this->value); }
+ static inline void deref(Data *d, T *value)
+ {
+ if (!d) return;
+ if (!d->strongref.deref()) {
+ if (!d->destroy())
+ delete value;
+ }
+ if (!d->weakref.deref())
+ delete d;
+ }
+
+ inline void internalConstruct(T *ptr)
+ {
+#ifdef QT_SHAREDPOINTER_TRACK_POINTERS
+ internalConstruct<void (*)(T *)>(ptr, normalDeleter);
+#else
+ if (ptr)
+ d = new Data;
+ else
+ d = 0;
+ internalFinishConstruction(ptr);
+#endif
+ }
+
+ template <typename Deleter>
+ inline void internalConstruct(T *ptr, Deleter deleter)
+ {
+ if (ptr)
+ d = ExternalRefCountWithCustomDeleter<T, Deleter>::create(ptr, deleter);
+ else
+ d = 0;
+ internalFinishConstruction(ptr);
+ }
+
+ inline void internalCreate()
+ {
+ T *ptr;
+ d = ExternalRefCountWithContiguousData<T>::create(&ptr);
+ Basic<T>::internalConstruct(ptr);
+ }
+
+ inline void internalFinishConstruction(T *ptr)
+ {
+ Basic<T>::internalConstruct(ptr);
+ if (ptr) d->setQObjectShared(ptr, true);
+#ifdef QT_SHAREDPOINTER_TRACK_POINTERS
+ if (ptr) internalSafetyCheckAdd2(d, ptr);
+#endif
+ }
+
+ inline ExternalRefCount() : d(0) { }
+ inline ExternalRefCount(Qt::Initialization i) : Basic<T>(i) { }
+
+ inline ExternalRefCount(T *ptr) : Basic<T>(Qt::Uninitialized) // throws
+ { internalConstruct(ptr); }
+ template <typename Deleter>
+ inline ExternalRefCount(T *ptr, Deleter deleter) : Basic<T>(Qt::Uninitialized) // throws
+ { internalConstruct(ptr, deleter); }
+
+ inline ExternalRefCount(const ExternalRefCount<T> &other) : Basic<T>(other), d(other.d)
+ { if (d) ref(); }
+ template <class X>
+ inline ExternalRefCount(const ExternalRefCount<X> &other) : Basic<T>(other.value), d(other.d)
+ { if (d) ref(); }
+ inline ~ExternalRefCount() { deref(); }
+
+ template <class X>
+ inline void internalCopy(const ExternalRefCount<X> &other)
+ {
+ Data *o = other.d;
+ T *actual = other.value;
+ if (o)
+ other.ref();
+ qSwap(d, o);
+ qSwap(this->value, actual);
+ deref(o, actual);
+ }
+
+ inline void internalSwap(ExternalRefCount &other)
+ {
+ qSwap(d, other.d);
+ qSwap(this->value, other.value);
+ }
+
+#if defined(Q_NO_TEMPLATE_FRIENDS)
+ public:
+#else
+ template <class X> friend class ExternalRefCount;
+ template <class X> friend class QT_PREPEND_NAMESPACE(QWeakPointer);
+ template <class X, class Y> friend QSharedPointer<X> copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
+#endif
+ inline void ref() const { d->weakref.ref(); d->strongref.ref(); }
+
+ inline void internalSet(Data *o, T *actual)
+ {
+ if (o) {
+ // increase the strongref, but never up from zero
+ // or less (-1 is used by QWeakPointer on untracked QObject)
+ register int tmp = o->strongref;
+ while (tmp > 0) {
+ // try to increment from "tmp" to "tmp + 1"
+ if (o->strongref.testAndSetRelaxed(tmp, tmp + 1))
+ break; // succeeded
+ tmp = o->strongref; // failed, try again
+ }
+
+ if (tmp > 0)
+ o->weakref.ref();
+ else
+ o = 0;
+ }
+
+ qSwap(d, o);
+ qSwap(this->value, actual);
+ if (!d || d->strongref == 0)
+ this->value = 0;
+
+ // dereference saved data
+ deref(o, actual);
+ }
+
+ Data *d;
+
+ private:
+ template<class X> ExternalRefCount(const InternalRefCount<X> &);
+ };
+} // namespace QtSharedPointer
+
+template <class T>
+class QSharedPointer: public QtSharedPointer::ExternalRefCount<T>
+{
+ typedef typename QtSharedPointer::ExternalRefCount<T> BaseClass;
+public:
+ inline QSharedPointer() { }
+ // inline ~QSharedPointer() { }
+
+ inline explicit QSharedPointer(T *ptr) : BaseClass(ptr) // throws
+ { }
+
+ template <typename Deleter>
+ inline QSharedPointer(T *ptr, Deleter d) : BaseClass(ptr, d) // throws
+ { }
+
+ inline QSharedPointer(const QSharedPointer<T> &other) : BaseClass(other) { }
+ inline QSharedPointer<T> &operator=(const QSharedPointer<T> &other)
+ {
+ BaseClass::internalCopy(other);
+ return *this;
+ }
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QSharedPointer<T> &operator=(QSharedPointer<T> &&other)
+ {
+ QSharedPointer<T>::internalSwap(other);
+ return *this;
+ }
+#endif
+
+ template <class X>
+ inline QSharedPointer(const QSharedPointer<X> &other) : BaseClass(other)
+ { }
+
+ template <class X>
+ inline QSharedPointer<T> &operator=(const QSharedPointer<X> &other)
+ {
+ QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X); // if you get an error in this line, the cast is invalid
+ BaseClass::internalCopy(other);
+ return *this;
+ }
+
+ template <class X>
+ inline QSharedPointer(const QWeakPointer<X> &other) : BaseClass(Qt::Uninitialized)
+ { this->d = 0; *this = other; }
+
+ template <class X>
+ inline QSharedPointer<T> &operator=(const QWeakPointer<X> &other)
+ { BaseClass::internalSet(other.d, other.value); return *this; }
+
+ inline void swap(QSharedPointer &other)
+ { QSharedPointer<T>::internalSwap(other); }
+
+ template <class X>
+ QSharedPointer<X> staticCast() const
+ {
+ return qSharedPointerCast<X, T>(*this);
+ }
+
+ template <class X>
+ QSharedPointer<X> dynamicCast() const
+ {
+ return qSharedPointerDynamicCast<X, T>(*this);
+ }
+
+ template <class X>
+ QSharedPointer<X> constCast() const
+ {
+ return qSharedPointerConstCast<X, T>(*this);
+ }
+
+#ifndef QT_NO_QOBJECT
+ template <class X>
+ QSharedPointer<X> objectCast() const
+ {
+ return qSharedPointerObjectCast<X, T>(*this);
+ }
+#endif
+
+ inline void clear() { *this = QSharedPointer<T>(); }
+
+ QWeakPointer<T> toWeakRef() const;
+
+protected:
+ inline explicit QSharedPointer(Qt::Initialization i) : BaseClass(i) {}
+
+public:
+ static inline QSharedPointer<T> create()
+ {
+ QSharedPointer<T> result(Qt::Uninitialized);
+ result.internalCreate();
+
+ // now initialize the data
+ new (result.data()) T();
+ result.internalFinishConstruction(result.data());
+ return result;
+ }
+};
+
+template <class T>
+class QWeakPointer
+{
+#ifndef Q_CC_NOKIAX86
+ typedef T *QWeakPointer:: *RestrictedBool;
+#endif
+ typedef QtSharedPointer::ExternalRefCountData Data;
+
+public:
+ typedef T element_type;
+ typedef T value_type;
+ typedef value_type *pointer;
+ typedef const value_type *const_pointer;
+ typedef value_type &reference;
+ typedef const value_type &const_reference;
+ typedef qptrdiff difference_type;
+
+ inline bool isNull() const { return d == 0 || d->strongref == 0 || value == 0; }
+#ifndef Q_CC_NOKIAX86
+ inline operator RestrictedBool() const { return isNull() ? 0 : &QWeakPointer::value; }
+#else
+ inline operator bool() const { return isNull() ? 0 : &QWeakPointer::value; }
+#endif
+ inline bool operator !() const { return isNull(); }
+ inline T *data() const { return d == 0 || d->strongref == 0 ? 0 : value; }
+
+ inline QWeakPointer() : d(0), value(0) { }
+ inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; }
+
+#ifndef QT_NO_QOBJECT
+ // special constructor that is enabled only if X derives from QObject
+ template <class X>
+ inline QWeakPointer(X *ptr) : d(ptr ? d->getAndRef(ptr) : 0), value(ptr)
+ { }
+#endif
+ template <class X>
+ inline QWeakPointer &operator=(X *ptr)
+ { return *this = QWeakPointer(ptr); }
+
+ inline QWeakPointer(const QWeakPointer<T> &o) : d(o.d), value(o.value)
+ { if (d) d->weakref.ref(); }
+ inline QWeakPointer<T> &operator=(const QWeakPointer<T> &o)
+ {
+ internalSet(o.d, o.value);
+ return *this;
+ }
+
+ inline QWeakPointer(const QSharedPointer<T> &o) : d(o.d), value(o.data())
+ { if (d) d->weakref.ref();}
+ inline QWeakPointer<T> &operator=(const QSharedPointer<T> &o)
+ {
+ internalSet(o.d, o.value);
+ return *this;
+ }
+
+ template <class X>
+ inline QWeakPointer(const QWeakPointer<X> &o) : d(0), value(0)
+ { *this = o; }
+
+ template <class X>
+ inline QWeakPointer<T> &operator=(const QWeakPointer<X> &o)
+ {
+ // conversion between X and T could require access to the virtual table
+ // so force the operation to go through QSharedPointer
+ *this = o.toStrongRef();
+ return *this;
+ }
+
+ template <class X>
+ inline bool operator==(const QWeakPointer<X> &o) const
+ { return d == o.d && value == static_cast<const T *>(o.value); }
+
+ template <class X>
+ inline bool operator!=(const QWeakPointer<X> &o) const
+ { return !(*this == o); }
+
+ template <class X>
+ inline QWeakPointer(const QSharedPointer<X> &o) : d(0), value(0)
+ { *this = o; }
+
+ template <class X>
+ inline QWeakPointer<T> &operator=(const QSharedPointer<X> &o)
+ {
+ QSHAREDPOINTER_VERIFY_AUTO_CAST(T, X); // if you get an error in this line, the cast is invalid
+ internalSet(o.d, o.data());
+ return *this;
+ }
+
+ template <class X>
+ inline bool operator==(const QSharedPointer<X> &o) const
+ { return d == o.d; }
+
+ template <class X>
+ inline bool operator!=(const QSharedPointer<X> &o) const
+ { return !(*this == o); }
+
+ inline void clear() { *this = QWeakPointer<T>(); }
+
+ inline QSharedPointer<T> toStrongRef() const { return QSharedPointer<T>(*this); }
+
+#if defined(QWEAKPOINTER_ENABLE_ARROW)
+ inline T *operator->() const { return data(); }
+#endif
+
+private:
+
+#if defined(Q_NO_TEMPLATE_FRIENDS)
+public:
+#else
+ template <class X> friend class QSharedPointer;
+#endif
+
+ inline void internalSet(Data *o, T *actual)
+ {
+ if (d == o) return;
+ if (o)
+ o->weakref.ref();
+ if (d && !d->weakref.deref())
+ delete d;
+ d = o;
+ value = actual;
+ }
+
+ Data *d;
+ T *value;
+};
+
+//
+// operator== and operator!=
+//
+template <class T, class X>
+bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
+{
+ return ptr1.data() == ptr2.data();
+}
+template <class T, class X>
+bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
+{
+ return ptr1.data() != ptr2.data();
+}
+
+template <class T, class X>
+bool operator==(const QSharedPointer<T> &ptr1, const X *ptr2)
+{
+ return ptr1.data() == ptr2;
+}
+template <class T, class X>
+bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2)
+{
+ return ptr1 == ptr2.data();
+}
+template <class T, class X>
+bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2)
+{
+ return !(ptr1 == ptr2);
+}
+template <class T, class X>
+bool operator!=(const T *ptr1, const QSharedPointer<X> &ptr2)
+{
+ return !(ptr2 == ptr1);
+}
+
+template <class T, class X>
+bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
+{
+ return ptr2 == ptr1;
+}
+template <class T, class X>
+bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
+{
+ return ptr2 != ptr1;
+}
+
+//
+// operator-
+//
+template <class T, class X>
+Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
+{
+ return ptr1.data() - ptr2.data();
+}
+template <class T, class X>
+Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, X *ptr2)
+{
+ return ptr1.data() - ptr2;
+}
+template <class T, class X>
+Q_INLINE_TEMPLATE typename QSharedPointer<X>::difference_type operator-(T *ptr1, const QSharedPointer<X> &ptr2)
+{
+ return ptr1 - ptr2.data();
+}
+
+//
+// operator<
+//
+template <class T, class X>
+Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
+{
+ return ptr1.data() < ptr2.data();
+}
+template <class T, class X>
+Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, X *ptr2)
+{
+ return ptr1.data() < ptr2;
+}
+template <class T, class X>
+Q_INLINE_TEMPLATE bool operator<(T *ptr1, const QSharedPointer<X> &ptr2)
+{
+ return ptr1 < ptr2.data();
+}
+
+//
+// qHash
+//
+template <class T> inline uint qHash(const T *key); // defined in qhash.h
+template <class T>
+Q_INLINE_TEMPLATE uint qHash(const QSharedPointer<T> &ptr)
+{
+ return QT_PREPEND_NAMESPACE(qHash)<T>(ptr.data());
+}
+
+
+template <class T>
+Q_INLINE_TEMPLATE QWeakPointer<T> QSharedPointer<T>::toWeakRef() const
+{
+ return QWeakPointer<T>(*this);
+}
+
+template <class T>
+inline void qSwap(QSharedPointer<T> &p1, QSharedPointer<T> &p2)
+{
+ p1.swap(p2);
+}
+
+#ifndef QT_NO_STL
+QT_END_NAMESPACE
+namespace std {
+ template <class T>
+ inline void swap(QT_PREPEND_NAMESPACE(QSharedPointer)<T> &p1, QT_PREPEND_NAMESPACE(QSharedPointer)<T> &p2)
+ { p1.swap(p2); }
+}
+QT_BEGIN_NAMESPACE
+#endif
+
+namespace QtSharedPointer {
+// helper functions:
+ template <class X, class T>
+ Q_INLINE_TEMPLATE QSharedPointer<X> copyAndSetPointer(X *ptr, const QSharedPointer<T> &src)
+ {
+ QSharedPointer<X> result;
+ result.internalSet(src.d, ptr);
+ return result;
+ }
+}
+
+// cast operators
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &src)
+{
+ register X *ptr = static_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
+ return QtSharedPointer::copyAndSetPointer(ptr, src);
+}
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &src)
+{
+ return qSharedPointerCast<X, T>(src.toStrongRef());
+}
+
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &src)
+{
+ register X *ptr = dynamic_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
+ return QtSharedPointer::copyAndSetPointer(ptr, src);
+}
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer<T> &src)
+{
+ return qSharedPointerDynamicCast<X, T>(src.toStrongRef());
+}
+
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &src)
+{
+ register X *ptr = const_cast<X *>(src.data()); // if you get an error in this line, the cast is invalid
+ return QtSharedPointer::copyAndSetPointer(ptr, src);
+}
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(const QWeakPointer<T> &src)
+{
+ return qSharedPointerConstCast<X, T>(src.toStrongRef());
+}
+
+template <class X, class T>
+Q_INLINE_TEMPLATE
+QWeakPointer<X> qWeakPointerCast(const QSharedPointer<T> &src)
+{
+ return qSharedPointerCast<X, T>(src).toWeakRef();
+}
+
+#ifndef QT_NO_QOBJECT
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &src)
+{
+ register X *ptr = qobject_cast<X *>(src.data());
+ return QtSharedPointer::copyAndSetPointer(ptr, src);
+}
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(const QWeakPointer<T> &src)
+{
+ return qSharedPointerObjectCast<X>(src.toStrongRef());
+}
+
+template <class X, class T>
+inline QSharedPointer<typename QtSharedPointer::RemovePointer<X>::Type>
+qobject_cast(const QSharedPointer<T> &src)
+{
+ return qSharedPointerObjectCast<typename QtSharedPointer::RemovePointer<X>::Type, T>(src);
+}
+template <class X, class T>
+inline QSharedPointer<typename QtSharedPointer::RemovePointer<X>::Type>
+qobject_cast(const QWeakPointer<T> &src)
+{
+ return qSharedPointerObjectCast<typename QtSharedPointer::RemovePointer<X>::Type, T>(src);
+}
+#endif
+
+
+template<typename T> Q_DECLARE_TYPEINFO_BODY(QWeakPointer<T>, Q_MOVABLE_TYPE);
+template<typename T> Q_DECLARE_TYPEINFO_BODY(QSharedPointer<T>, Q_MOVABLE_TYPE);
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif