diff options
Diffstat (limited to 'qtinterface/qt4/Qt/qsharedpointer_impl.h')
-rw-r--r-- | qtinterface/qt4/Qt/qsharedpointer_impl.h | 805 |
1 files changed, 805 insertions, 0 deletions
diff --git a/qtinterface/qt4/Qt/qsharedpointer_impl.h b/qtinterface/qt4/Qt/qsharedpointer_impl.h new file mode 100644 index 0000000..e25e0c1 --- /dev/null +++ b/qtinterface/qt4/Qt/qsharedpointer_impl.h @@ -0,0 +1,805 @@ +/**************************************************************************** +** +** 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 |