You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tqtinterface/qtinterface/qt4/Qt/qsharedpointer_impl.h

806 lines
25 KiB

/****************************************************************************
**
** Copyright (C) 2010 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$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** 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 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
#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
// 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; };
// 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 ptrdiff_t 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 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); }
};
// 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 ref() const { d->weakref.ref(); d->strongref.ref(); }
inline bool deref()
{
if (!d->strongref.deref()) {
internalDestroy();
}
return d->weakref.deref();
}
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(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)
{
internalSet(other.d, other.data());
}
inline void internalDestroy()
{
if (!d->destroy())
delete this->value;
}
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 QWeakPointer;
template <class X, class Y> friend QSharedPointer<X> copyAndSetPointer(X * ptr, const QSharedPointer<Y> &src);
#endif
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;
}
if (d && !deref())
delete d;
d = o;
this->value = d && d->strongref ? actual : 0;
}
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(Qt::Uninitialized)
{ BaseClass::internalConstruct(ptr); }
template <typename Deleter>
inline QSharedPointer(T *ptr, Deleter d) { BaseClass::internalConstruct(ptr, d); }
inline QSharedPointer(const QSharedPointer<T> &other) : BaseClass(other) { }
inline QSharedPointer<T> &operator=(const QSharedPointer<T> &other)
{
BaseClass::internalCopy(other);
return *this;
}
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 ptrdiff_t 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;
};
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, class X>
Q_INLINE_TEMPLATE typename T::difference_type operator-(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
{
return ptr1.data() - ptr2.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);
}
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
QT_END_NAMESPACE
QT_END_HEADER
#endif