summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
authorKent Hansen <khansen@trolltech.com>2009-08-05 14:10:47 (GMT)
committerKent Hansen <khansen@trolltech.com>2009-08-05 14:10:47 (GMT)
commit1d7d5436eea09a232187836e59d2a937a752dee4 (patch)
tree6bd9ae61abb1467aceddc5a828fc2e65d93b2534 /src/corelib/tools
parent791bddfcd5cc7540219835ef5d91486acd833c4b (diff)
parentfb8bb148affec842e8fa1a70616c64c7d3066ee8 (diff)
downloadQt-1d7d5436eea09a232187836e59d2a937a752dee4.zip
Qt-1d7d5436eea09a232187836e59d2a937a752dee4.tar.gz
Qt-1d7d5436eea09a232187836e59d2a937a752dee4.tar.bz2
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt into qtscript-jsc-backend
Conflicts: src/script/qscriptextqobject.cpp
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qbytedata_p.h12
-rw-r--r--src/corelib/tools/qcontiguouscache.h7
-rw-r--r--src/corelib/tools/qshareddata.cpp2
-rw-r--r--src/corelib/tools/qsharedpointer.cpp149
-rw-r--r--src/corelib/tools/qsharedpointer.h1
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h192
6 files changed, 277 insertions, 86 deletions
diff --git a/src/corelib/tools/qbytedata_p.h b/src/corelib/tools/qbytedata_p.h
index cc10ea2..f3724f6 100644
--- a/src/corelib/tools/qbytedata_p.h
+++ b/src/corelib/tools/qbytedata_p.h
@@ -42,8 +42,18 @@
#ifndef QBYTEDATA_H
#define QBYTEDATA_H
-#include <qbytearray.h>
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+#include <qbytearray.h>
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h
index 0020d22..7221925 100644
--- a/src/corelib/tools/qcontiguouscache.h
+++ b/src/corelib/tools/qcontiguouscache.h
@@ -44,6 +44,7 @@
#include <QtCore/qatomic.h>
#include <limits.h>
+#include <new>
QT_BEGIN_HEADER
@@ -76,6 +77,12 @@ struct QContiguousCacheTypedData
int start;
int offset;
uint sharable : 1;
+ // uint unused : 31;
+
+ // total is 24 bytes (HP-UX aCC: 40 bytes)
+ // the next entry is already aligned to 8 bytes
+ // there will be an 8 byte gap here if T requires 16-byte alignment
+ // (such as long double on 64-bit platforms, __int128, __float128)
T array[1];
};
diff --git a/src/corelib/tools/qshareddata.cpp b/src/corelib/tools/qshareddata.cpp
index 3cd37a7..6cd220c 100644
--- a/src/corelib/tools/qshareddata.cpp
+++ b/src/corelib/tools/qshareddata.cpp
@@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE
QSharedData is designed to be used with QSharedDataPointer or
QExplicitlySharedDataPointer to implement custom \l{implicitly
- shared} or \l {explicitly shared} classes. QSharedData provides
+ shared} or explicitly shared classes. QSharedData provides
\l{thread-safe} reference counting.
See QSharedDataPointer and QExplicitlySharedDataPointer for details.
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp
index 59dfffe..f18dee8 100644
--- a/src/corelib/tools/qsharedpointer.cpp
+++ b/src/corelib/tools/qsharedpointer.cpp
@@ -128,7 +128,7 @@
To access the pointer that QWeakPointer is tracking, you
must first create a QSharedPointer object and verify if the pointer
- is null or not.
+ is null or not. See QWeakPointer::toStrongRef() for more information.
\sa QSharedPointer
*/
@@ -210,6 +210,8 @@
If \tt T is a derived type of the template parameter of this
class, QSharedPointer will perform an automatic cast. Otherwise,
you will get a compiler error.
+
+ \sa QWeakPointer::toStrongRef()
*/
/*!
@@ -362,6 +364,8 @@
Returns a weak reference object that shares the pointer referenced
by this object.
+
+ \sa QWeakPointer::QWeakPointer()
*/
/*!
@@ -478,10 +482,78 @@
*/
/*!
+ \fn T *QWeakPointer::data() const
+ \since 4.6
+
+ Returns the value of the pointer being tracked by this QWeakPointer,
+ \b without ensuring that it cannot get deleted. To have that guarantee,
+ use toStrongRef(), which returns a QSharedPointer object. If this
+ function can determine that the pointer has already been deleted, it
+ returns 0.
+
+ It is ok to obtain the value of the pointer and using that value itself,
+ like for example in debugging statements:
+
+ \code
+ qDebug("Tracking %p", weakref.data());
+ \endcode
+
+ However, dereferencing the pointer is only allowed if you can guarantee
+ by external means that the pointer does not get deleted. For example,
+ if you can be certain that no other thread can delete it, nor the
+ functions that you may call.
+
+ If that is the case, then the following code is valid:
+
+ \code
+ // this pointer cannot be used in another thread
+ // so other threads cannot delete it
+ QWeakPointer<int> weakref = obtainReference();
+
+ Object *obj = weakref.data();
+ if (obj) {
+ // if the pointer wasn't deleted yet, we know it can't get
+ // deleted by our own code here nor the functions we call
+ otherFunction(obj);
+ }
+ \endcode
+
+ Use this function with care.
+
+ \sa isNull(), toStrongRef()
+*/
+
+/*!
\fn QSharedPointer<T> QWeakPointer::toStrongRef() const
Promotes this weak reference to a strong one and returns a
- QSharedPointer object holding that reference.
+ QSharedPointer object holding that reference. When promoting to
+ QSharedPointer, this function verifies if the object has been deleted
+ already or not. If it hasn't, this function increases the reference
+ count to the shared object, thus ensuring that it will not get
+ deleted.
+
+ Since this function can fail to obtain a valid strong reference to the
+ shared object, you should always verify if the conversion succeeded,
+ by calling QSharedPointer::isNull() on the returned object.
+
+ For example, the following code promotes a QWeakPointer that was held
+ to a strong reference and, if it succeeded, it prints the value of the
+ integer that was held:
+
+ \code
+ QWeakPointer<int> weakref;
+
+ // ...
+
+ QSharedPointer<int> strong = weakref.toStrongRef();
+ if (strong)
+ qDebug() << "The value is:" << *strong;
+ else
+ qDebug() << "The value has already been deleted";
+ \endcode
+
+ \sa QSharedPointer::QSharedPointer()
*/
/*!
@@ -792,6 +864,56 @@
#include <qset.h>
#include <qmutex.h>
+#if !defined(QT_NO_QOBJECT)
+#include "../kernel/qobject_p.h"
+
+/*!
+ \internal
+ This function is called for a just-created QObject \a obj, to enable
+ the use of QSharedPointer and QWeakPointer.
+
+ When QSharedPointer is active in a QObject, the object must not be deleted
+ directly: the lifetime is managed by the QSharedPointer object. In that case,
+ the deleteLater() and parent-child relationship in QObject only decrease
+ the strong reference count, instead of deleting the object.
+*/
+void QtSharedPointer::ExternalRefCountData::setQObjectShared(const QObject *obj, bool)
+{
+ Q_ASSERT(obj);
+ QObjectPrivate *d = QObjectPrivate::get(const_cast<QObject *>(obj));
+
+ if (d->sharedRefcount)
+ qFatal("QSharedPointer: pointer %p already has reference counting", obj);
+ d->sharedRefcount = this;
+
+ // QObject decreases the refcount too, so increase it up
+ weakref.ref();
+}
+
+QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::getAndRef(const QObject *obj)
+{
+ Q_ASSERT(obj);
+ QObjectPrivate *d = QObjectPrivate::get(const_cast<QObject *>(obj));
+ ExternalRefCountData *that = d->sharedRefcount;
+ if (that) {
+ that->weakref.ref();
+ return that;
+ }
+
+ // we can create the refcount data because it doesn't exist
+ ExternalRefCountData *x = new ExternalRefCountData(Qt::Uninitialized);
+ x->strongref = -1;
+ x->weakref = 2; // the QWeakPointer that called us plus the QObject itself
+ if (!d->sharedRefcount.testAndSetRelease(0, x)) {
+ delete x;
+ d->sharedRefcount->weakref.ref();
+ }
+ return d->sharedRefcount;
+}
+#endif
+
+
+
#if !defined(QT_NO_MEMBER_TEMPLATES)
//# define QT_SHARED_POINTER_BACKTRACE_SUPPORT
@@ -897,6 +1019,7 @@ QT_BEGIN_NAMESPACE
namespace QtSharedPointer {
Q_CORE_EXPORT void internalSafetyCheckAdd(const volatile void *);
Q_CORE_EXPORT void internalSafetyCheckRemove(const volatile void *);
+ Q_AUTOTEST_EXPORT void internalSafetyCheckCleanCheck();
}
/*!
@@ -961,6 +1084,7 @@ void QtSharedPointer::internalSafetyCheckAdd2(const void *d_ptr, const volatile
kp->dPointers.insert(d_ptr, data);
kp->dataPointers.insert(ptr, d_ptr);
+ Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
}
/*!
@@ -985,10 +1109,29 @@ void QtSharedPointer::internalSafetyCheckRemove2(const void *d_ptr)
Q_ASSERT(it2 != kp->dataPointers.end());
//qDebug("Removing d=%p value=%p", d_ptr, it->pointer);
-
+
// remove entries
kp->dataPointers.erase(it2);
kp->dPointers.erase(it);
+ Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
+}
+
+/*!
+ \internal
+ Called by the QSharedPointer autotest
+*/
+void QtSharedPointer::internalSafetyCheckCleanCheck()
+{
+# ifdef QT_BUILD_INTERNAL
+ KnownPointers *const kp = knownPointers();
+ Q_ASSERT_X(kp, "internalSafetyCheckSelfCheck()", "Called after global statics deletion!");
+
+ if (kp->dPointers.size() != kp->dataPointers.size())
+ qFatal("Internal consistency error: the number of pointers is not equal!");
+
+ if (!kp->dPointers.isEmpty())
+ qFatal("Pointer cleaning failed: %d entries remaining", kp->dPointers.size());
+# endif
}
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qsharedpointer.h b/src/corelib/tools/qsharedpointer.h
index abd83ad..2f86ce7 100644
--- a/src/corelib/tools/qsharedpointer.h
+++ b/src/corelib/tools/qsharedpointer.h
@@ -115,6 +115,7 @@ public:
QWeakPointer<T> operator=(const QWeakPointer<T> &other);
QWeakPointer<T> operator=(const QSharedPointer<T> &other);
+ T *data() const;
void clear();
QSharedPointer<T> toStrongRef() const;
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index b8f4139..8a34362 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -94,26 +94,27 @@ namespace QtSharedPointer {
template <class T> class InternalRefCount;
template <class T> class ExternalRefCount;
- template <class X, class T> QSharedPointer<X> strongRefFromWeakHelper(const QWeakPointer<T> &, X*);
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
+ // the only compilers that didn't support this were MSVC 6.0 and 2002
+ 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; };
- //
- // 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
{
@@ -129,21 +130,10 @@ namespace QtSharedPointer {
inline T *operator->() const { return data(); }
protected:
- inline Basic() : value(0) { }
+ inline Basic(T *ptr = 0) : value(ptr) { }
+ inline Basic(Qt::Initialization) { }
// ~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)
{
value = ptr;
@@ -160,14 +150,26 @@ namespace QtSharedPointer {
struct ExternalRefCountData
{
- QAtomicInt weakref;
- QAtomicInt strongref;
+ QBasicAtomicInt weakref;
+ QBasicAtomicInt strongref;
- inline ExternalRefCountData() : weakref(1), strongref(1) { }
- virtual inline ~ExternalRefCountData() { Q_ASSERT(!weakref); Q_ASSERT(!strongref); }
+ inline ExternalRefCountData()
+ {
+ QBasicAtomicInt proto = Q_BASIC_ATOMIC_INITIALIZER(1);
+ weakref = strongref = proto;
+ }
+ inline ExternalRefCountData(Qt::Initialization) { }
+ virtual inline ~ExternalRefCountData() { Q_ASSERT(!weakref); Q_ASSERT(strongref <= 0); }
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)
template <class T, typename Deleter>
struct CustomDeleter
@@ -177,6 +179,9 @@ namespace QtSharedPointer {
inline CustomDeleter(T *p, Deleter d) : deleter(d), ptr(p) {}
};
+ // 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)
struct ExternalRefCountWithDestroyFn: public ExternalRefCountData
{
@@ -190,6 +195,7 @@ namespace QtSharedPointer {
inline bool destroy() { destroyer(this); return true; }
inline void operator delete(void *ptr) { ::operator delete(ptr); }
};
+ // sizeof(ExternalRefCountWithDestroyFn) = 16 (32-bit) / 24 (64-bit)
template <class T, typename Deleter>
struct ExternalRefCountWithCustomDeleter: public ExternalRefCountWithDestroyFn
@@ -203,11 +209,23 @@ namespace QtSharedPointer {
{
Self *realself = static_cast<Self *>(self);
executeDeleter(realself->extra.ptr, realself->extra.deleter);
+
+ // delete the deleter too
+ realself->extra.~Next();
+ }
+ 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
@@ -234,10 +252,19 @@ namespace QtSharedPointer {
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)));
@@ -258,9 +285,9 @@ namespace QtSharedPointer {
template <class T>
class ExternalRefCount: public Basic<T>
{
- typedef ExternalRefCountData Data;
- typedef void (*DeleterFunction)(T *);
protected:
+ typedef ExternalRefCountData Data;
+
inline void ref() const { d->weakref.ref(); d->strongref.ref(); }
inline bool deref()
{
@@ -272,42 +299,51 @@ namespace QtSharedPointer {
inline void internalConstruct(T *ptr)
{
- Basic<T>::internalConstruct(ptr);
- Q_ASSERT(!d);
+#ifdef QT_SHAREDPOINTER_TRACK_POINTERS
+ internalConstruct<void (*)(T *)>(ptr, normalDeleter);
+#else
if (ptr)
d = new Data;
-#ifdef QT_SHAREDPOINTER_TRACK_POINTERS
- if (ptr) internalSafetyCheckAdd2(d, ptr);
+ else
+ d = 0;
+ internalFinishConstruction(ptr);
#endif
}
template <typename Deleter>
inline void internalConstruct(T *ptr, Deleter deleter)
{
- Basic<T>::internalConstruct(ptr);
- Q_ASSERT(!d);
if (ptr)
d = ExternalRefCountWithCustomDeleter<T, Deleter>::create(ptr, deleter);
-#ifdef QT_SHAREDPOINTER_TRACK_POINTERS
- if (ptr) internalSafetyCheckAdd2(d, ptr);
-#endif
+ 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() { if (d && !deref()) delete d; }
+ inline ExternalRefCount(Qt::Initialization i) : Basic<T>(i) { }
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() { if (d && !deref()) delete d; }
template <class X>
inline void internalCopy(const ExternalRefCount<X> &other)
@@ -317,32 +353,35 @@ namespace QtSharedPointer {
inline void internalDestroy()
{
-#ifdef QT_SHAREDPOINTER_TRACK_POINTERS
- internalSafetyCheckRemove2(d);
-#endif
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> copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
- template <class X, class Y> friend QSharedPointer<X> QtSharedPointer::strongRefFromWeakHelper(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();
+ // 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;
}
if (d && !deref())
delete d;
@@ -350,9 +389,6 @@ namespace QtSharedPointer {
this->value = d && d->strongref ? actual : 0;
}
-#if defined(QT_BUILD_INTERNAL)
- public:
-#endif
Data *d;
private:
@@ -368,7 +404,8 @@ public:
inline QSharedPointer() { }
// inline ~QSharedPointer() { }
- inline explicit QSharedPointer(T *ptr) { internalConstruct(ptr); }
+ inline explicit QSharedPointer(T *ptr) : BaseClass(Qt::Uninitialized)
+ { internalConstruct(ptr); }
template <typename Deleter>
inline QSharedPointer(T *ptr, Deleter d) { internalConstruct(ptr, d); }
@@ -380,13 +417,9 @@ public:
return *this;
}
- inline QSharedPointer(const QWeakPointer<T> &other)
- { *this = QtSharedPointer::strongRefFromWeakHelper(other, static_cast<T*>(0)); }
- inline QSharedPointer<T> &operator=(const QWeakPointer<T> &other)
- { *this = QtSharedPointer::strongRefFromWeakHelper(other, static_cast<T*>(0)); return *this; }
-
template <class X>
- inline QSharedPointer(const QSharedPointer<X> &other) { *this = other; }
+ inline QSharedPointer(const QSharedPointer<X> &other) : BaseClass(other)
+ { }
template <class X>
inline QSharedPointer<T> &operator=(const QSharedPointer<X> &other)
@@ -397,12 +430,12 @@ public:
}
template <class X>
- inline QSharedPointer(const QWeakPointer<X> &other)
- { *this = QtSharedPointer::strongRefFromWeakHelper(other, static_cast<T *>(0)); }
+ 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)
- { *this = strongRefFromWeakHelper(other, static_cast<T *>(0)); return *this; }
+ { internalSet(other.d, other.value); return *this; }
template <class X>
QSharedPointer<X> staticCast() const
@@ -434,14 +467,18 @@ public:
QWeakPointer<T> toWeakRef() const;
+protected:
+ inline QSharedPointer(Qt::Initialization i) : BaseClass(i) {}
+
public:
static inline QSharedPointer<T> create()
{
- QSharedPointer<T> result;
+ QSharedPointer<T> result(Qt::Uninitialized);
result.internalCreate();
// now initialize the data
new (result.data()) T();
+ result.internalFinishConstruction(result.data());
return result;
}
};
@@ -456,9 +493,19 @@ 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 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; }
+
+ // 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)
+ { }
+ 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)
@@ -510,7 +557,7 @@ public:
template <class X>
inline bool operator==(const QSharedPointer<X> &o) const
- { return d == o.d && value == static_cast<const T *>(o.data()); }
+ { return d == o.d; }
template <class X>
inline bool operator!=(const QSharedPointer<X> &o) const
@@ -525,7 +572,7 @@ private:
#if defined(Q_NO_TEMPLATE_FRIENDS)
public:
#else
- template <class X, class Y> friend QSharedPointer<X> QtSharedPointer::strongRefFromWeakHelper(const QWeakPointer<Y> &src, X *);
+ template <class X> friend class QSharedPointer;
#endif
inline void internalSet(Data *o, T *actual)
@@ -602,14 +649,6 @@ namespace QtSharedPointer {
result.internalSet(src.d, ptr);
return result;
}
- template <class X, class T>
- Q_INLINE_TEMPLATE QSharedPointer<X> strongRefFromWeakHelper
- (const QT_PREPEND_NAMESPACE(QWeakPointer<T>) &src, X *)
- {
- QSharedPointer<X> result;
- result.internalSet(src.d, src.value);
- return result;
- }
}
// cast operators
@@ -669,14 +708,6 @@ Q_INLINE_TEMPLATE QSharedPointer<X> qSharedPointerObjectCast(const QWeakPointer<
return qSharedPointerObjectCast<X>(src.toStrongRef());
}
-# ifndef QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION
-namespace QtSharedPointer {
- 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; };
-}
-
template <class X, class T>
inline QSharedPointer<typename QtSharedPointer::RemovePointer<X>::Type>
qobject_cast(const QSharedPointer<T> &src)
@@ -689,7 +720,6 @@ qobject_cast(const QWeakPointer<T> &src)
{
return qSharedPointerObjectCast<typename QtSharedPointer::RemovePointer<X>::Type, T>(src);
}
-# endif
#endif