/****************************************************************************
**
** 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$
** GNU Lesser General Public License Usage
** 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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $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
    // 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 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 ref() const { d->weakref.ref(); d->strongref.ref(); }
        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)
        {
            internalSet(other.d, other.data());
        }

        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 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;
    }

    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);
}

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
