summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qsharedpointer_impl.h
diff options
context:
space:
mode:
authorAlexis Menard <alexis.menard@nokia.com>2009-04-17 10:40:52 (GMT)
committerAlexis Menard <alexis.menard@nokia.com>2009-04-17 10:40:52 (GMT)
commitbb2e4df9bee3148e819c98410aa36e22dad95d7a (patch)
treea6e6e8c070a72378d4b2e5f39ad3cc9c368b61ab /src/corelib/tools/qsharedpointer_impl.h
downloadQt-bb2e4df9bee3148e819c98410aa36e22dad95d7a.zip
Qt-bb2e4df9bee3148e819c98410aa36e22dad95d7a.tar.gz
Qt-bb2e4df9bee3148e819c98410aa36e22dad95d7a.tar.bz2
Initial import of kinetic-animations branch from the old kinetic
repository to the new repository
Diffstat (limited to 'src/corelib/tools/qsharedpointer_impl.h')
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h585
1 files changed, 585 insertions, 0 deletions
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
new file mode 100644
index 0000000..f1b35ee
--- /dev/null
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -0,0 +1,585 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q_QDOC
+
+#ifndef QSHAREDPOINTER_H
+#error Do not include qsharedpointer_impl.h directly
+#endif
+#if 0
+#pragma qt_sync_stop_processing
+#endif
+
+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);
+
+namespace QtSharedPointer {
+ template <class T> class InternalRefCount;
+ template <class T> class ExternalRefCount;
+
+ template <class X, class T> QSharedPointer<X> qStrongRefFromWeakHelper(const QWeakPointer<T> &, X*);
+ template <class X, class T> QSharedPointer<X> qSharedPointerCastHelper(const QSharedPointer<T> &src, X *);
+ template <class X, class T> QSharedPointer<X> qSharedPointerConstCastHelper(const QSharedPointer<T> &src, X *);
+
+ // used in debug mode to verify the reuse of pointers
+ Q_CORE_EXPORT void internalSafetyCheckAdd(const volatile void *);
+ Q_CORE_EXPORT void internalSafetyCheckRemove(const volatile 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); }
+
+ //
+ // Depending on its template parameter, QSharedPointer derives from either
+ // QtSharedPointer::InternalRefCount or from QtSharedPointer::ExternalRefCount.
+ // Both of these classes derive from QtSharedPointer::Basic, which provides common
+ // operations,
+ //
+ template <class T>
+ class Basic
+ {
+ typedef T *Basic:: *RestrictedBool;
+ public:
+ typedef T Type;
+
+ inline T *data() const { return value; }
+ inline bool isNull() const { return !data(); }
+ inline operator RestrictedBool() const { return isNull() ? 0 : &Basic::value; }
+ inline bool operator !() const { return isNull(); }
+ inline T &operator*() const { return *data(); }
+ inline T *operator->() const { return data(); }
+
+ protected:
+ inline Basic() : value(0 * sizeof(T)) { }
+ // ~Basic();
+
+ inline void verifyReconstruction(const T *ptr)
+ {
+ Q_ASSERT_X(!ptr || value != ptr, "QSharedPointer",
+ "QSharedPointer violation: you cannot create two QSharedPointer objects "
+ "from the same pointer");
+
+ // make use of the "ptr" variable in the no-op statement below
+ // since this function is in a public header, we don't
+ // want warnings on "unused variables" to show up everywhere
+ ptr = 0;
+ }
+
+ inline void internalConstruct(T *ptr)
+ {
+#ifndef QT_NO_DEBUG
+ if (ptr) internalSafetyCheckAdd(ptr);
+#endif
+ value = ptr;
+ }
+ inline void internalDestroy()
+ {
+#ifndef QT_NO_DEBUG
+ if (value) internalSafetyCheckRemove(value);
+#endif
+ }
+
+#if defined(Q_NO_TEMPLATE_FRIENDS)
+ public:
+#else
+ template <class X> friend class QWeakPointer;
+#endif
+
+ Type *value;
+ };
+
+ struct ExternalRefCountData
+ {
+ QAtomicInt weakref;
+ QAtomicInt strongref;
+
+ inline ExternalRefCountData() : weakref(1), strongref(1) { }
+ virtual inline ~ExternalRefCountData() { Q_ASSERT(!weakref); Q_ASSERT(!strongref); }
+
+ virtual inline bool destroy() { return false; }
+ };
+
+ template <class T, typename Deleter>
+ struct ExternalRefCountWithSpecializedDeleter: public ExternalRefCountData
+ {
+ T *ptr;
+ Deleter deleter;
+
+ inline ExternalRefCountWithSpecializedDeleter(T *p, Deleter d)
+ : ptr(p), deleter(d)
+ { }
+ inline bool destroy() { executeDeleter(ptr, deleter); return true; }
+ };
+
+ template <class T>
+ class ExternalRefCount: public Basic<T>
+ {
+ typedef ExternalRefCountData Data;
+ typedef void (*DeleterFunction)(T *);
+ protected:
+ inline void ref() const { d->weakref.ref(); d->strongref.ref(); }
+ inline bool deref()
+ {
+ if (!d->strongref.deref())
+ this->internalDestroy();
+ return d->weakref.deref();
+ }
+
+ inline void internalConstruct(T *ptr)
+ {
+ Basic<T>::internalConstruct(ptr);
+ Q_ASSERT(!d);
+ if (ptr)
+ d = new Data;
+ }
+
+ template <typename Deleter>
+ inline void internalConstruct(T *ptr, Deleter deleter)
+ {
+ Basic<T>::internalConstruct(ptr);
+ Q_ASSERT(!d);
+ if (ptr)
+ d = new ExternalRefCountWithSpecializedDeleter<T, Deleter>(ptr, deleter);
+ }
+
+ inline ExternalRefCount() : d(0) { }
+ inline ~ExternalRefCount() { if (d && !deref()) delete d; }
+ inline ExternalRefCount(const ExternalRefCount<T> &other) : Basic<T>(other), d(other.d)
+ { if (d) ref(); }
+
+ template <class X>
+ inline void internalCopy(const ExternalRefCount<X> &other)
+ {
+ internalSet(other.d, other.data());
+ }
+
+ inline void internalDestroy()
+ {
+ Basic<T>::internalDestroy();
+ if (!d->destroy())
+ delete this->value;
+ }
+
+ private:
+#if defined(Q_NO_TEMPLATE_FRIENDS)
+ public:
+#else
+ template <class X> friend class ExternalRefCount;
+ template <class X> friend class QWeakPointer;
+ template <class X, class Y> friend QSharedPointer<X> qSharedPointerCastHelper(const QSharedPointer<Y> &src, X *);
+ template <class X, class Y> friend QSharedPointer<X> qSharedPointerConstCastHelper(const QSharedPointer<Y> &src, X *);
+ template <class X, class Y> friend QSharedPointer<X> QtSharedPointer::qStrongRefFromWeakHelper(const QWeakPointer<Y> &src, X *);
+#endif
+
+ inline void internalSet(Data *o, T *actual)
+ {
+ if (d == o) return;
+ if (o && !o->strongref)
+ o = 0;
+ if (o) {
+ verifyReconstruction(actual);
+ o->weakref.ref();
+ o->strongref.ref();
+ }
+ if (d && !deref())
+ delete d;
+ d = o;
+ this->value = d && d->strongref ? actual : 0;
+ }
+
+#if defined(QT_BUILD_INTERNAL)
+ public:
+#endif
+ 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) { internalConstruct(ptr); }
+
+ template <typename Deleter>
+ inline QSharedPointer(T *ptr, Deleter d) { internalConstruct(ptr, d); }
+
+ inline QSharedPointer(const QSharedPointer<T> &other) : BaseClass(other) { }
+ inline QSharedPointer<T> &operator=(const QSharedPointer<T> &other)
+ {
+ internalCopy(other);
+ return *this;
+ }
+
+ inline QSharedPointer(const QWeakPointer<T> &other)
+ { *this = QtSharedPointer::qStrongRefFromWeakHelper(other, static_cast<T*>(0)); }
+ inline QSharedPointer<T> &operator=(const QWeakPointer<T> &other)
+ { *this = QtSharedPointer::qStrongRefFromWeakHelper(other, static_cast<T*>(0)); return *this; }
+
+ template <class X>
+ inline QSharedPointer(const QSharedPointer<X> &other) { *this = 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
+ internalCopy(other);
+ return *this;
+ }
+
+ template <class X>
+ inline QSharedPointer(const QWeakPointer<X> &other)
+ { *this = QtSharedPointer::qStrongRefFromWeakHelper(other, static_cast<T *>(0)); }
+
+ template <class X>
+ inline QSharedPointer<T> &operator=(const QWeakPointer<X> &other)
+ { *this = qStrongRefFromWeakHelper(other, static_cast<T *>(0)); return *this; }
+
+ 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);
+ }
+
+ inline void clear() { *this = QSharedPointer<T>(); }
+
+ QWeakPointer<T> toWeakRef() const;
+};
+
+template <class T>
+class QWeakPointer
+{
+ typedef T *QWeakPointer:: *RestrictedBool;
+ typedef QtSharedPointer::ExternalRefCountData Data;
+
+public:
+ inline bool isNull() const { return d == 0 || d->strongref == 0 || value == 0; }
+ inline operator RestrictedBool() const { return isNull() ? 0 : &QWeakPointer::value; }
+ inline bool operator !() const { return isNull(); }
+
+ inline QWeakPointer() : d(0), value(0) { }
+ inline ~QWeakPointer() { if (d && !d->weakref.deref()) delete d; }
+ 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 && value == static_cast<const T *>(o.data()); }
+
+ 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); }
+
+private:
+
+#if defined(Q_NO_TEMPLATE_FRIENDS)
+public:
+#else
+ template <class X, class Y> friend QSharedPointer<X> QtSharedPointer::qStrongRefFromWeakHelper(const QWeakPointer<Y> &src, X *);
+#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;
+};
+
+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;
+}
+
+template <class T>
+Q_INLINE_TEMPLATE QWeakPointer<T> QSharedPointer<T>::toWeakRef() const
+{
+ return QWeakPointer<T>(*this);
+}
+
+namespace QtSharedPointer {
+// helper functions:
+ template <class X, class T>
+ Q_INLINE_TEMPLATE X *qVerifyStaticCast(T *src, X *)
+ {
+ return static_cast<X *>(src); // if you get an error in this line, the cast is invalid
+ }
+ template <class X, class T>
+ Q_INLINE_TEMPLATE X *qVerifyDynamicCast(T *src, X *)
+ {
+ return dynamic_cast<X *>(src); // if you get an error in this line, the cast is invalid
+ }
+ template <class X, class T>
+ Q_INLINE_TEMPLATE X *qVerifyConstCast(T *src, X *)
+ {
+ return const_cast<X *>(src); // if you get an error in this line, the cast is invalid
+ }
+
+ template <class X, class T>
+ Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCastHelper(const QSharedPointer<T> &src, X *)
+ {
+ QSharedPointer<X> result;
+ register T *ptr = src.data();
+ result.internalSet(src.d, static_cast<X *>(ptr));
+ return result;
+ }
+ template <class X, class T>
+ Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCastHelper(const QSharedPointer<T> &src, X *)
+ {
+ QSharedPointer<X> result;
+ register T *ptr = src.data();
+ result.internalSet(src.d, const_cast<X *>(ptr));
+ return result;
+ }
+ template <class X, class T>
+ Q_INLINE_TEMPLATE QSharedPointer<X> qStrongRefFromWeakHelper
+ (const QT_PREPEND_NAMESPACE(QWeakPointer<T>) &src, X *)
+ {
+ QSharedPointer<X> result;
+ result.internalSet(src.d, src.value);
+ return result;
+ }
+}
+
+// cast operators
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &src)
+{
+ X *x = 0;
+ QtSharedPointer::qVerifyStaticCast(src.data(), x);
+ return QtSharedPointer::qSharedPointerCastHelper(src, x);
+}
+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)
+{
+ X *x = 0;
+ if (QtSharedPointer::qVerifyDynamicCast(src.data(), x))
+ return QtSharedPointer::qSharedPointerCastHelper(src, x);
+ return QSharedPointer<X>();
+}
+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)
+{
+ X *x = 0;
+ if (QtSharedPointer::qVerifyConstCast(src.data(), x))
+ return QtSharedPointer::qSharedPointerConstCastHelper(src, x);
+ return QSharedPointer<X>();
+}
+template <class X, class T>
+Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerConstCast(const QWeakPointer<T> &src)
+{
+ X *x = 0;
+ if (QtSharedPointer::qVerifyConstCast(src.data(), x))
+ return QtSharedPointer::qSharedPointerCastHelper(src, x);
+ return QSharedPointer<X>();
+}
+
+template <class X, class T>
+Q_INLINE_TEMPLATE
+QWeakPointer<X> qWeakPointerCast(const QSharedPointer<T> &src)
+{
+ return qSharedPointerCast<X, T>(src).toWeakRef();
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif