/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2020 Intel Corporation.
** Copyright (C) 2019 Klarälvdalens Datakonsult AB.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qsharedpointer.h"

// to be sure we aren't causing a namespace clash:
#include "qshareddata.h"

/*!
    \class QSharedPointer
    \inmodule QtCore
    \brief The QSharedPointer class holds a strong reference to a shared pointer.
    \since 4.5

    \reentrant

    The QSharedPointer is an automatic, shared pointer in C++. It
    behaves exactly like a normal pointer for normal purposes,
    including respect for constness.

    QSharedPointer will delete the pointer it is holding when it goes
    out of scope, provided no other QSharedPointer objects are
    referencing it.

    A QSharedPointer object can be created from a normal pointer,
    another QSharedPointer object or by promoting a
    QWeakPointer object to a strong reference.

    \section1 Thread-Safety

    QSharedPointer and QWeakPointer are reentrant classes. This means that, in
    general, a given QSharedPointer or QWeakPointer object \b{cannot} be
    accessed by multiple threads at the same time without synchronization.

    Different QSharedPointer and QWeakPointer objects can safely be accessed
    by multiple threads at the same time. This includes the case where they
    hold pointers to the same object; the reference counting mechanism
    is atomic, and no manual synchronization is required.

    It should be noted that, while the pointer value can be accessed in this
    manner (that is, by multiple threads at the same time, without
    synchronization), QSharedPointer and QWeakPointer provide no guarantee
    about the object being pointed to. The specific thread-safety and
    reentrancy rules for that object still apply.

    \section1 Other Pointer Classes

    Qt also provides two other pointer wrapper classes: QPointer and
    QSharedDataPointer. They are incompatible with one another, since
    each has its very different use case.

    QSharedPointer holds a shared pointer by means of an external
    reference count (i.e., a reference counter placed outside the
    object). Like its name indicates, the pointer value is shared
    among all instances of QSharedPointer and QWeakPointer. The
    contents of the object pointed to by the pointer should not be
    considered shared, however: there is only one object. For that
    reason, QSharedPointer does not provide a way to detach or make
    copies of the pointed object.

    QSharedDataPointer, on the other hand, holds a pointer to shared
    data (i.e., a class derived from QSharedData). It does so by means
    of an internal reference count, placed in the QSharedData base
    class. This class can, therefore, detach based on the type of
    access made to the data being guarded: if it's a non-const access,
    it creates a copy atomically for the operation to complete.

    QExplicitlySharedDataPointer is a variant of QSharedDataPointer, except
    that it only detaches if QExplicitlySharedDataPointer::detach() is
    explicitly called (hence the name).

    QScopedPointer simply holds a pointer to a heap allocated object and
    deletes it in its destructor. This class is useful when an object needs to
    be heap allocated and deleted, but no more. QScopedPointer is lightweight,
    it makes no use of additional structure or reference counting.

    Finally, QPointer holds a pointer to a QObject-derived object, but it
    does so weakly. QWeakPointer has the same functionality, but its use for
    that function is deprecated.

    \section1 Optional Pointer Tracking

    A feature of QSharedPointer that can be enabled at compile-time for
    debugging purposes is a pointer tracking mechanism. When enabled,
    QSharedPointer registers in a global set all the pointers that it tracks.
    This allows one to catch mistakes like assigning the same pointer to two
    QSharedPointer objects.

    This function is enabled by defining the \tt{QT_SHAREDPOINTER_TRACK_POINTERS}
    macro before including the QSharedPointer header.

    It is safe to use this feature even with code compiled without the
    feature. QSharedPointer will ensure that the pointer is removed from the
    tracker even from code compiled without pointer tracking.

    Note, however, that the pointer tracking feature has limitations on
    multiple- or virtual-inheritance (that is, in cases where two different
    pointer addresses can refer to the same object). In that case, if a
    pointer is cast to a different type and its value changes,
    QSharedPointer's pointer tracking mechanism may fail to detect that the
    object being tracked is the same.

    \omit
    \section1 QSharedPointer internals

    QSharedPointer has two "private" members: the pointer itself being tracked
    and a d-pointer. Those members are private to the class, but QSharedPointer
    is friends with QWeakPointer and other QSharedPointer with different
    template arguments. (On some compilers, template friends are not supported,
    so the members are technically public)

    The reason for keeping the pointer value itself outside the d-pointer is
    because of multiple inheritance needs. If you have two QSharedPointer
    objects of different pointer types, but pointing to the same object in
    memory, it could happen that the pointer values are different. The \tt
    differentPointers autotest exemplifies this problem. The same thing could
    happen in the case of virtual inheritance: a pointer of class matching
    the virtual base has different address compared to the pointer of the
    complete object. See the \tt virtualBaseDifferentPointers autotest for
    this problem.

    The d pointer is a pointer to QtSharedPointer::ExternalRefCountData, but it
    always points to one of the two classes derived from ExternalRefCountData.

    \section2 d-pointer
    \section3 QtSharedPointer::ExternalRefCountData

    It is basically a reference-counted reference-counter plus a pointer to the
    function to be used to delete the pointer. It has three members: \tt
    strongref, \tt weakref, and \tt destroyer. The strong reference counter is
    controlling the lifetime of the object tracked by QSharedPointer. A
    positive value indicates that the object is alive. It's also the number of
    QSharedObject instances that are attached to this Data.

    When the strong reference count decreases to zero, the object is deleted
    (see below for information on custom deleters). The strong reference count
    can also exceptionally be -1, indicating that there are no QSharedPointers
    attached to an object, which is tracked too. The only case where this is
    possible is that of QWeakPointers and QPointers tracking a QObject. Note
    that QWeakPointers tracking a QObject is a deprecated feature as of Qt 5.0,
    kept only for compatibility with Qt 4.x.

    The weak reference count controls the lifetime of the d-pointer itself.
    It can be thought of as an internal/intrusive reference count for
    ExternalRefCountData itself. This count is equal to the number of
    QSharedPointers and QWeakPointers that are tracking this object. In case
    the object is a QObject being tracked by QPointer, this number is increased
    by 1, since QObjectPrivate tracks it too.

    The third member is a pointer to the function that is used to delete the
    pointer being tracked. That happens when the destroy() function is called.

    The size of this class is the size of the two atomic ints plus the size of
    a pointer. On 32-bit architectures, that's 12 bytes, whereas on 64-bit ones
    it's 16 bytes. There is no padding.

    \section3 QtSharedPointer::ExternalRefCountWithCustomDeleter

    This class derives from ExternalRefCountData and is a template class. As
    template parameters, it has the type of the pointer being tracked (\tt T)
    and a \tt Deleter, which is anything. It adds two fields to its parent
    class, matching those template parameters: a member of type \tt Deleter and
    a member of type \tt T*. Those members are actually inside a template
    struct of type CustomDeleter, which is partially-specialized for normal
    deletion. See below for more details on that.

    The purpose of this class is to store the pointer to be deleted and the
    deleter code along with the d-pointer. This allows the last strong
    reference to call any arbitrary function that disposes of the object. For
    example, this allows calling QObject::deleteLater() on a given object.
    The pointer to the object is kept here because it needs to match the actual
    deleter function's parameters, regardless of what template argument the
    last QSharedPointer instance had.

    This class is never instantiated directly: the constructors and
    destructor are private and, in C++11, deleted. Only the create() function
    may be called to return an object of this type. See below for construction
    details.

    The size of this class depends on the size of \tt Deleter. If it's an empty
    functor (i.e., no members), ABIs generally assign it the size of 1. But
    given that it's followed by a pointer, padding bytes may be inserted so
    that the alignment of the class and of the pointer are correct. In that
    case, the size of this class is 12+4+4 = 20 bytes on 32-bit architectures,
    or 16+8+8 = 40 bytes on 64-bit architectures. If \tt Deleter is a function
    pointer, the size should be the same as the empty structure case. If \tt
    Deleter is a pointer to a member function (PMF), the size will be bigger
    and will depend on the ABI. For architectures using the Itanium C++ ABI, a
    PMF is twice the size of a normal pointer. In that case, the size of this
    structure will be 12+8+4 = 24 bytes on 32-bit architectures, 16+16+8 = 40
    bytes on 64-bit ones.

    If the deleter was not specified when creating the QSharedPointer object
    (i.e., if a standard \tt delete call is expected), then there's an
    optimization that avoids the need to store another function pointer in
    ExternalRefCountWithCustomDeleter. Instead, a template specialization makes
    a direct delete call. The size of the structure, in this case, is 12+4 = 16
    bytes on 32-bit architectures, 16+8 = 24 bytes on 64-bit ones.

    \section3 QtSharedPointer::ExternalRefCountWithContiguousData

    This class also derives from ExternalRefCountData and it is
    also a template class. The template parameter is the type \tt T of the
    class which QSharedPointer tracks. It adds only one member to its parent,
    which is of type \tt T (the actual type, not a pointer to it).

    The purpose of this class is to lay the \tt T object out next to the
    reference counts, saving one memory allocation per shared pointer. This
    is particularly interesting for small \tt T or for the cases when there
    are few if any QWeakPointer tracking the object. This class exists to
    implement the QSharedPointer::create() call.

    Like ExternalRefCountWithCustomDeleter, this class is never instantiated
    directly. This class also provides a create() member that returns the
    pointer, and hides its constructors and destructor. With C++11, they're
    deleted.

    The size of this class depends on the size of \tt T.

    \section3 Instantiating ExternalRefCountWithCustomDeleter and ExternalRefCountWithContiguousData

    Like explained above, these classes have private constructors. Moreover,
    they are not defined anywhere, so trying to call \tt{new ClassType} would
    result in a compilation or linker error. Instead, these classes must be
    constructed via their create() methods.

    Instead of instantiating the class by the normal way, the create() method
    calls \tt{operator new} directly with the size of the class, then calls
    the parent class's constructor only (that is, ExternalRefCountData's constructor).
    This ensures that the inherited members are initialised properly.

    After initialising the base class, the
    ExternalRefCountWithCustomDeleter::create() function initialises the new
    members directly, by using the placement \tt{operator new}. In the case
    of the ExternalRefCountWithContiguousData::create() function, the address
    to the still-uninitialised \tt T member is saved for the callee to use.
    The member is only initialised in QSharedPointer::create(), so that we
    avoid having many variants of the internal functions according to the
    arguments in use for calling the constructor.

    When initialising the parent class, the create() functions pass the
    address of the static deleter() member function. That is, when the
    destroy() function is called by QSharedPointer, the deleter() functions
    are called instead. These functions static_cast the ExternalRefCountData*
    parameter to their own type and execute their deletion: for the
    ExternalRefCountWithCustomDeleter::deleter() case, it runs the user's
    custom deleter, then destroys the deleter; for
    ExternalRefCountWithContiguousData::deleter, it simply calls the \tt T
    destructor directly.

    Only one non-inline function is required per template, which is
    the deleter() static member. All the other functions can be inlined.
    What's more, the address of deleter() is calculated only in code, which
    can be resolved at link-time if the linker can determine that the
    function lies in the current application or library module (since these
    classes are not exported, that is the case for Windows or for builds with
    \tt{-fvisibility=hidden}).

    \section3 Modifications due to pointer-tracking

    To ensure that pointers created with pointer-tracking enabled get
    un-tracked when destroyed, even if destroyed by code compiled without the
    feature, QSharedPointer modifies slightly the instructions of the
    previous sections.

    When ExternalRefCountWithCustomDeleter or
    ExternalRefCountWithContiguousData are used, their create() functions
    will set the ExternalRefCountData::destroyer function
    pointer to safetyCheckDeleter() instead. These static member functions
    simply call internalSafetyCheckRemove() before passing control to the
    normal deleter() function.

    If neither custom deleter nor QSharedPointer::create() are used, then
    QSharedPointer uses a custom deleter of its own: the normalDeleter()
    function, which simply calls \tt delete. By using a custom deleter, the
    safetyCheckDeleter() procedure described above kicks in.

    \endomit

    \sa QSharedDataPointer, QWeakPointer, QScopedPointer, QEnableSharedFromThis
*/

/*!
    \class QWeakPointer
    \inmodule QtCore
    \brief The QWeakPointer class holds a weak reference to a shared pointer.
    \since 4.5
    \reentrant

    The QWeakPointer is an automatic weak reference to a
    pointer in C++. It cannot be used to dereference the pointer
    directly, but it can be used to verify if the pointer has been
    deleted or not in another context.

    QWeakPointer objects can only be created by assignment from a
    QSharedPointer.

    It's important to note that QWeakPointer provides no automatic casting
    operators to prevent mistakes from happening. Even though QWeakPointer
    tracks a pointer, it should not be considered a pointer itself, since it
    doesn't guarantee that the pointed object remains valid.

    Therefore, to access the pointer that QWeakPointer is tracking, you must
    first promote it to QSharedPointer and verify if the resulting object is
    null or not. QSharedPointer guarantees that the object isn't deleted, so
    if you obtain a non-null object, you may use the pointer. See
    QWeakPointer::toStrongRef() for an example.

    \omit
    \section1 QWeakPointer internals

    QWeakPointer shares most of its internal functionality with
    \l{QSharedPointer#qsharedpointer-internals}{QSharedPointer}, so see that
    class's internal documentation for more information.

    QWeakPointer requires an external reference counter in order to operate.
    Therefore, it is incompatible by design with \l QSharedData-derived
    classes.

    It has a special QObject constructor, which works by calling
    QtSharedPointer::ExternalRefCountData::getAndRef, which retrieves the
    d-pointer from QObjectPrivate. If one isn't set yet, that function
    creates the d-pointer and atomically sets it.

    If getAndRef needs to create a d-pointer, it sets the strongref to -1,
    indicating that the QObject is not shared: QWeakPointer is used only to
    determine whether the QObject has been deleted. In that case, it cannot
    be upgraded to QSharedPointer (see the previous section).

    \endomit

    \sa QSharedPointer, QScopedPointer
*/

/*!
    \class QEnableSharedFromThis
    \inmodule QtCore
    \brief A base class that allows obtaining a QSharedPointer for an object already managed by a shared pointer.
    \since 5.4

    You can inherit this class when you need to create a QSharedPointer
    from any instance of a class; for instance, from within the
    object itself. The key point is that the technique of
    just returning QSharedPointer<T>(this) cannot be used, because
    this winds up creating multiple distinct QSharedPointer objects
    with separate reference counts. For this reason you must never
    create more than one QSharedPointer from the same raw pointer.

    QEnableSharedFromThis defines two member functions called
    sharedFromThis() that return a QSharedPointer<T> and
    QSharedPointer<const T>, depending on constness, to \c this:

    \snippet code/src_corelib_tools_qsharedpointer.cpp 0

    It is also possible to get a shared pointer from an object outside of
    the class itself. This is especially useful in code that provides an
    interface to scripts, where it is currently not possible to use shared
    pointers. For example:

    \snippet code/src_corelib_tools_qsharedpointer.cpp 1
*/

/*!
    \fn template <class T> QSharedPointer<T>::QSharedPointer()

    Creates a QSharedPointer that is null (the object is holding
    a reference to \nullptr).
*/

/*!
    \fn template <class T> QSharedPointer<T>::~QSharedPointer()

    Destroys this QSharedPointer object. If it is the last reference to
    the pointer stored, this will delete the pointer as well.
*/

/*!
    \fn template <class T> template <typename X> QSharedPointer<T>::QSharedPointer(X *ptr)

    Creates a QSharedPointer that points to \a ptr. The pointer \a ptr
    becomes managed by this QSharedPointer and must not be passed to
    another QSharedPointer object or deleted outside this object.

    Since Qt 5.8, when the last reference to this QSharedPointer gets
    destroyed, \a ptr will be deleted by calling \c X's destructor (even if \c
    X is not the same as QSharedPointer's template parameter \c T). Previously,
    the destructor for \c T was called.
*/

/*!
  \fn template <class T> template <typename X, typename Deleter> QSharedPointer<T>::QSharedPointer(X *ptr, Deleter d)

    Creates a QSharedPointer that points to \a ptr. The pointer \a ptr
    becomes managed by this QSharedPointer and must not be passed to
    another QSharedPointer object or deleted outside this object.

    The deleter parameter \a d specifies the custom deleter for this
    object. The custom deleter is called, instead of the operator delete(),
    when the strong reference count drops to 0. This is useful,
    for instance, for calling \l {QObject::}{deleteLater()} on a QObject instead:

    \snippet code/src_corelib_tools_qsharedpointer.cpp 2

    Note that the custom deleter function will be called with a pointer to type
    \c X, even if the QSharedPointer template parameter \c T is not the same.

    It is also possible to specify a member function directly, as in:
    \snippet code/src_corelib_tools_qsharedpointer.cpp 3

    \sa clear()
*/

/*!
    \fn template <class T> QSharedPointer<T>::QSharedPointer(std::nullptr_t)
    \since 5.8

    Creates a QSharedPointer that is null. This is equivalent to the
    QSharedPointer default constructor.
*/

/*!
  \fn template <class T> template <typename Deleter> QSharedPointer<T>::QSharedPointer(std::nullptr_t, Deleter d)
    \since 5.8

    Creates a QSharedPointer that is null. This is equivalent to the
    QSharedPointer default constructor.

    The deleter parameter \a d specifies the custom deleter for this
    object. The custom deleter is called, instead of the operator
    delete(), when the strong reference count drops to 0.
*/

/*!
    \fn template <class T> QSharedPointer<T>::QSharedPointer(const QSharedPointer<T> &other)

    Creates a QSharedPointer object that shares \a other's pointer.

    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.
*/

/*!
    \fn template <class T> QSharedPointer<T>::QSharedPointer(const QWeakPointer<T> &other)

    Creates a QSharedPointer by promoting the weak reference \a other
    to strong reference and sharing its pointer.

    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()
*/

/*!
    \fn template <class T> QSharedPointer &QSharedPointer<T>::operator=(const QSharedPointer<T> &other)

    Makes this object share \a other's pointer. The current pointer
    reference is discarded and, if it was the last, the pointer will
    be deleted.

    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.
*/

/*!
    \fn template <class T> QSharedPointer &QSharedPointer<T>::operator=(const QWeakPointer<T> &other)

    Promotes \a other to a strong reference and makes this object
    share a reference to the pointer referenced by it. The current pointer
    reference is discarded and, if it was the last, the pointer will
    be deleted.

    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.
*/

/*!
    \fn template <class T> void QSharedPointer<T>::swap(QSharedPointer<T> &other);
    \since 5.3

    Swaps this shared pointer instance with \a other. This function is
    very fast and never fails.
*/

/*!
    \fn template <class T> T *QSharedPointer<T>::data() const

    Returns the value of the pointer referenced by this object.

    Note: do not delete the pointer returned by this function or pass
    it to another function that could delete it, including creating
    QSharedPointer or QWeakPointer objects.
*/

/*!
    \fn template <class T> T *QSharedPointer<T>::get() const
    \since 5.11

    Same as data().

    This function is provided for API compatibility with \c{std::shared_ptr}.
*/

/*!
    \fn template <class T> T &QSharedPointer<T>::operator *() const

    Provides access to the shared pointer's members.

    If the contained pointer is \nullptr, behavior is undefined.
    \sa isNull()
*/

/*!
    \fn template <class T> T *QSharedPointer<T>::operator ->() const

    Provides access to the shared pointer's members.

    If the contained pointer is \nullptr, behavior is undefined.
    \sa isNull()
*/

/*!
    \fn template <class T> bool QSharedPointer<T>::isNull() const

    Returns \c true if this object refers to \nullptr.
*/

/*!
    \fn template <class T> QSharedPointer<T>::operator bool() const

    Returns \c true if the contained pointer is not \nullptr.
    This function is suitable for use in \tt if-constructs, like:

    \snippet code/src_corelib_tools_qsharedpointer.cpp 4

    \sa isNull()
*/

/*!
    \fn template <class T> bool QSharedPointer<T>::operator !() const

    Returns \c true if this object refers to \nullptr.
    This function is suitable for use in \tt if-constructs, like:

    \snippet code/src_corelib_tools_qsharedpointer.cpp 5

    \sa isNull()
*/

/*!
  \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::staticCast() const

    Performs a static cast from this pointer's type to \tt X and returns
    a QSharedPointer that shares the reference. This function can be
    used for up- and for down-casting, but is more useful for
    up-casting.

    Note: the template type \c X must have the same const and volatile
    qualifiers as the template of this object, or the cast will
    fail. Use constCast() if you need to drop those qualifiers.

    \sa dynamicCast(), constCast(), qSharedPointerCast()
*/

/*!
    \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::dynamicCast() const

    Performs a dynamic cast from this pointer's type to \tt X and
    returns a QSharedPointer that shares the reference. If this
    function is used to up-cast, then QSharedPointer will perform a \tt
    dynamic_cast, which means that if the object being pointed by this
    QSharedPointer is not of type \tt X, the returned object will be
    null.

    Note: the template type \c X must have the same const and volatile
    qualifiers as the template of this object, or the cast will
    fail. Use constCast() if you need to drop those qualifiers.

    \sa qSharedPointerDynamicCast()
*/

/*!
    \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::constCast() const

    Performs a \tt const_cast from this pointer's type to \tt X and returns
    a QSharedPointer that shares the reference. This function can be
    used for up- and for down-casting, but is more useful for
    up-casting.

    \sa isNull(), qSharedPointerConstCast()
*/

/*!
    \fn template <class T> template <class X> QSharedPointer<X> QSharedPointer<T>::objectCast() const
    \since 4.6

    Performs a \l qobject_cast() from this pointer's type to \tt X and
    returns a QSharedPointer that shares the reference. If this
    function is used to up-cast, then QSharedPointer will perform a \tt
    qobject_cast, which means that if the object being pointed by this
    QSharedPointer is not of type \tt X, the returned object will be
    null.

    Note: the template type \c X must have the same const and volatile
    qualifiers as the template of this object, or the cast will
    fail. Use constCast() if you need to drop those qualifiers.

    \sa qSharedPointerObjectCast()
*/

/*!
    \fn template <class T> template <typename... Args> QSharedPointer<T> QSharedPointer<T>::create(Args &&... args)
    \overload
    \since 5.1

    Creates a QSharedPointer object and allocates a new item of type \tt T. The
    QSharedPointer internals and the object are allocated in one single memory
    allocation, which could help reduce memory fragmentation in a long-running
    application.

    This function will attempt to call a constructor for type \tt T that can
    accept all the arguments passed (\a args). Arguments will be perfectly-forwarded.
*/

/*!
    \fn template <class T> QWeakPointer<T> QSharedPointer<T>::toWeakRef() const

    Returns a weak reference object that shares the pointer referenced
    by this object.

    \sa QWeakPointer::QWeakPointer()
*/

/*!
    \fn template <class T> void QSharedPointer<T>::clear()

    Clears this QSharedPointer object, dropping the reference that it
    may have had to the pointer. If this was the last reference, then
    the pointer itself will be deleted.
*/

/*!
    \fn template <class T> void QSharedPointer<T>::reset()
    \since 5.0

    Same as clear(). For std::shared_ptr compatibility.
*/

/*!
    \fn template <class T> void QSharedPointer<T>::reset(T *t)
    \since 5.0

    Resets this QSharedPointer object to point to \a t
    instead. Equivalent to:
    \snippet code/src_corelib_tools_qsharedpointer.cpp 6
*/

/*!
  \fn template <class T> template <typename Deleter> void QSharedPointer<T>::reset(T *t, Deleter deleter)
    \since 5.0

    Resets this QSharedPointer object to point to \a t
    instead, with the Deleter \a deleter. Equivalent to:
    \snippet code/src_corelib_tools_qsharedpointer.cpp 7
*/

/*!
    \fn template <class T> QWeakPointer<T>::QWeakPointer()

    Creates a QWeakPointer that points to nothing.
*/

/*!
    \fn template <class T> QWeakPointer<T>::~QWeakPointer()

    Destroys this QWeakPointer object. The pointer referenced
    by this object will not be deleted.
*/

/*!
    \fn template <class T> QWeakPointer<T>::QWeakPointer(const QWeakPointer<T> &other)

    Creates a QWeakPointer that holds a weak reference to the
    pointer referenced by \a other.

    If \tt T is a derived type of the template parameter of this
    class, QWeakPointer will perform an automatic cast. Otherwise,
    you will get a compiler error.
*/

/*!
    \fn template <class T> QWeakPointer<T>::QWeakPointer(const QSharedPointer<T> &other)

    Creates a QWeakPointer that holds a weak reference to the
    pointer referenced by \a other.

    If \tt T is a derived type of the template parameter of this
    class, QWeakPointer will perform an automatic cast. Otherwise,
    you will get a compiler error.
*/

/*!
    \fn template <class T> QWeakPointer<T>::QWeakPointer(const QObject *other)
    \since 4.6
    \deprecated

    Creates a QWeakPointer that holds a weak reference directly to the
    QObject \a other. This constructor is only available if the template type
    \tt T is QObject or derives from it (otherwise a compilation error will
    result).

    You can use this constructor with any QObject, even if they were not
    created with \l QSharedPointer.

    Note that QWeakPointers created this way on arbitrary QObjects usually
    cannot be promoted to QSharedPointer.

    \sa QSharedPointer, QPointer
*/

/*!
    \fn template <class T> QWeakPointer &QWeakPointer<T>::operator=(const QObject *other)
    \since 4.6
    \deprecated

    Makes this QWeakPointer hold a weak reference directly to the QObject
    \a other. This function is only available if the template type \tt T is
    QObject or derives from it.

    \sa QPointer
*/

/*!
    \fn template <class T> QWeakPointer &QWeakPointer<T>::operator=(const QWeakPointer<T> &other)

    Makes this object share \a other's pointer. The current pointer
    reference is discarded but is not deleted.

    If \tt T is a derived type of the template parameter of this
    class, QWeakPointer will perform an automatic cast. Otherwise,
    you will get a compiler error.
*/

/*!
    \fn template <class T> QWeakPointer &QWeakPointer<T>::operator=(const QSharedPointer<T> &other)

    Makes this object share \a other's pointer. The current pointer
    reference is discarded but is not deleted.

    If \tt T is a derived type of the template parameter of this
    class, QWeakPointer will perform an automatic cast. Otherwise,
    you will get a compiler error.
*/

/*!
    \fn template <class T> void QWeakPointer<T>::swap(QWeakPointer<T> &other)
    \since 5.4

    Swaps this weak pointer instance with \a other. This function is
    very fast and never fails.
*/

/*!
    \fn template <class T> bool QWeakPointer<T>::isNull() const

    Returns \c true if this object refers to \nullptr.

    Note that, due to the nature of weak references, the pointer that
    QWeakPointer references can become \nullptr at any moment, so
    the value returned from this function can change from false to
    true from one call to the next.
*/

/*!
    \fn template <class T> QWeakPointer<T>::operator bool() const

    Returns \c true if the contained pointer is not \nullptr.
    This function is suitable for use in \tt if-constructs, like:

    \snippet code/src_corelib_tools_qsharedpointer.cpp 8

    Note that, due to the nature of weak references, the pointer that
    QWeakPointer references can become \nullptr at any moment, so
    the value returned from this function can change from true to
    false from one call to the next.

    \sa isNull()
*/

/*!
    \fn template <class T> bool QWeakPointer<T>::operator !() const

    Returns \c true if this object refers to \nullptr.
    This function is suitable for use in \tt if-constructs, like:

    \snippet code/src_corelib_tools_qsharedpointer.cpp 9

    Note that, due to the nature of weak references, the pointer that
    QWeakPointer references can become \nullptr at any moment, so
    the value returned from this function can change from false to
    true from one call to the next.

    \sa isNull()
*/

/*!
    \fn template <class T> T *QWeakPointer<T>::data() const
    \since 4.6
    \obsolete Use toStrongRef() instead, and data() on the returned QSharedPointer.

    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 \nullptr.

    It is ok to obtain the value of the pointer and using that value itself,
    like for example in debugging statements:

    \snippet code/src_corelib_tools_qsharedpointer.cpp 10

    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:

    \snippet code/src_corelib_tools_qsharedpointer.cpp 11

    Use this function with care.

    \sa isNull(), toStrongRef()
*/

/*!
    \fn template <class T> QSharedPointer<T> QWeakPointer<T>::toStrongRef() const

    Promotes this weak reference to a strong one and returns a
    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:

    \snippet code/src_corelib_tools_qsharedpointer.cpp 12

    \sa QSharedPointer::QSharedPointer()
*/

/*!
    \fn template <class T> QSharedPointer<T> QWeakPointer<T>::lock() const
    \since 5.4

    Same as toStrongRef().

    This function is provided for API compatibility with std::weak_ptr.
*/

/*!
    \fn template <class T> void QWeakPointer<T>::clear()

    Clears this QWeakPointer object, dropping the reference that it
    may have had to the pointer.
*/

/*!
    \fn template <class T> QSharedPointer<T> QEnableSharedFromThis<T>::sharedFromThis()
    \since 5.4

    If \c this (that is, the subclass instance invoking this method) is being
    managed by a QSharedPointer, returns a shared pointer instance pointing to
    \c this; otherwise returns a null QSharedPointer.
*/

/*!
    \fn template <class T> QSharedPointer<const T> QEnableSharedFromThis<T>::sharedFromThis() const
    \overload
    \since 5.4

    Const overload of sharedFromThis().
*/

/*!
    \fn template <class T> template <class X> bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
    \relates QSharedPointer

    Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.

    If \a ptr2's template parameter is different from \a ptr1's,
    QSharedPointer will attempt to perform an automatic \tt static_cast
    to ensure that the pointers being compared are equal. If \a ptr2's
    template parameter is not a base or a derived type from
    \a ptr1's, you will get a compiler error.
*/

/*!
    \fn template <class T> template <class X> bool operator!=(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
    \relates QSharedPointer

    Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.

    If \a ptr2's template parameter is different from \a ptr1's,
    QSharedPointer will attempt to perform an automatic \tt static_cast
    to ensure that the pointers being compared are equal. If \a ptr2's
    template parameter is not a base or a derived type from
    \a ptr1's, you will get a compiler error.
*/

/*!
    \fn template <class T> template <class X> bool operator==(const QSharedPointer<T> &ptr1, const X *ptr2)
    \relates QSharedPointer

    Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.

    If \a ptr2's type is different from \a ptr1's,
    QSharedPointer will attempt to perform an automatic \tt static_cast
    to ensure that the pointers being compared are equal. If \a ptr2's
    type is not a base or a derived type from this
    \a ptr1's, you will get a compiler error.
*/

/*!
    \fn template <class T> template <class X> bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2)
    \relates QSharedPointer

    Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.

    If \a ptr2's type is different from \a ptr1's,
    QSharedPointer will attempt to perform an automatic \tt static_cast
    to ensure that the pointers being compared are equal. If \a ptr2's
    type is not a base or a derived type from this
    \a ptr1's, you will get a compiler error.
*/

/*!
    \fn template <class T> template <class X> bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2)
    \relates QSharedPointer

    Returns \c true if the pointer \a ptr1 is the
    same pointer as that referenced by \a ptr2.

    If \a ptr2's template parameter is different from \a ptr1's type,
    QSharedPointer will attempt to perform an automatic \tt static_cast
    to ensure that the pointers being compared are equal. If \a ptr2's
    template parameter is not a base or a derived type from
    \a ptr1's type, you will get a compiler error.
*/

/*!
    \fn template <class T> template <class X> bool operator!=(const T *ptr1, const QSharedPointer<X> &ptr2)
    \relates QSharedPointer

    Returns \c true if the pointer \a ptr1 is not the
    same pointer as that referenced by \a ptr2.

    If \a ptr2's template parameter is different from \a ptr1's type,
    QSharedPointer will attempt to perform an automatic \tt static_cast
    to ensure that the pointers being compared are equal. If \a ptr2's
    template parameter is not a base or a derived type from
    \a ptr1's type, you will get a compiler error.
*/

/*!
    \fn template <class T> template <class X> bool operator==(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
    \relates QWeakPointer

    Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.

    If \a ptr2's template parameter is different from \a ptr1's,
    QSharedPointer will attempt to perform an automatic \tt static_cast
    to ensure that the pointers being compared are equal. If \a ptr2's
    template parameter is not a base or a derived type from
    \a ptr1's, you will get a compiler error.
*/

/*!
    \fn template <class T> template <class X> bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
    \relates QWeakPointer

    Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.

    If \a ptr2's template parameter is different from \a ptr1's,
    QSharedPointer will attempt to perform an automatic \tt static_cast
    to ensure that the pointers being compared are equal. If \a ptr2's
    template parameter is not a base or a derived type from
    \a ptr1's, you will get a compiler error.
*/

/*!
    \fn template <class T> template <class X> bool operator==(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
    \relates QWeakPointer

    Returns \c true if \a ptr1 and \a ptr2 refer to the same pointer.

    If \a ptr2's template parameter is different from \a ptr1's,
    QSharedPointer will attempt to perform an automatic \tt static_cast
    to ensure that the pointers being compared are equal. If \a ptr2's
    template parameter is not a base or a derived type from
    \a ptr1's, you will get a compiler error.
*/

/*!
    \fn template <class T> bool operator==(const QSharedPointer<T> &lhs, std::nullptr_t)
    \relates QSharedPointer
    \since 5.8

    Returns \c true if \a lhs refers to \nullptr.

    \sa QSharedPointer::isNull()
*/

/*!
    \fn template <class T> bool operator==(std::nullptr_t, const QSharedPointer<T> &rhs)
    \relates QSharedPointer
    \since 5.8

    Returns \c true if \a rhs refers to \nullptr.

    \sa QSharedPointer::isNull()
*/

/*!
    \fn template <class T> bool operator!=(const QSharedPointer<T> &lhs, std::nullptr_t)
    \relates QSharedPointer
    \since 5.8

    Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer.

    \sa QSharedPointer::isNull()
*/

/*!
    \fn template <class T> bool operator!=(std::nullptr_t, const QSharedPointer<T> &rhs)
    \relates QSharedPointer
    \since 5.8

    Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer.

    \sa QSharedPointer::isNull()
*/

/*!
    \fn template <class T> bool operator==(const QWeakPointer<T> &lhs, std::nullptr_t)
    \relates QWeakPointer
    \since 5.8

    Returns \c true if \a lhs refers to \nullptr.

    \sa QWeakPointer::isNull()
*/

/*!
    \fn template <class T> bool operator==(std::nullptr_t, const QWeakPointer<T> &rhs)
    \relates QWeakPointer
    \since 5.8

    Returns \c true if \a rhs refers to \nullptr.

    \sa QWeakPointer::isNull()
*/

/*!
    \fn template <class T> bool operator!=(const QWeakPointer<T> &lhs, std::nullptr_t)
    \relates QWeakPointer
    \since 5.8

    Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer.

    \sa QWeakPointer::isNull()
*/

/*!
    \fn template <class T> bool operator!=(std::nullptr_t, const QWeakPointer<T> &rhs)
    \relates QWeakPointer
    \since 5.8

    Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer.

    \sa QWeakPointer::isNull()
*/

/*!
    \fn template <class T> template <class X> bool operator!=(const QWeakPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
    \relates QWeakPointer

    Returns \c true if \a ptr1 and \a ptr2 refer to distinct pointers.

    If \a ptr2's template parameter is different from \a ptr1's,
    QSharedPointer will attempt to perform an automatic \tt static_cast
    to ensure that the pointers being compared are equal. If \a ptr2's
    template parameter is not a base or a derived type from
    \a ptr1's, you will get a compiler error.
*/

/*!
    \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &other)
    \relates QSharedPointer

    Returns a shared pointer to the pointer held by \a other, cast to
    type \tt X.  The types \tt T and \tt X must belong to one
    hierarchy for the \tt static_cast to succeed.

    Note that \tt X must have the same cv-qualifiers (\tt const and
    \tt volatile) that \tt T has, or the code will fail to
    compile. Use qSharedPointerConstCast to cast away the constness.

    \sa QSharedPointer::staticCast(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
*/

/*!
    \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerCast(const QWeakPointer<T> &other)
    \relates QSharedPointer
    \relates QWeakPointer

    Returns a shared pointer to the pointer held by \a other, cast to
    type \tt X.  The types \tt T and \tt X must belong to one
    hierarchy for the \tt static_cast to succeed.

    The \a other object is converted first to a strong reference. If
    that conversion fails (because the object it's pointing to has
    already been deleted), this function returns a null
    QSharedPointer.

    Note that \tt X must have the same cv-qualifiers (\tt const and
    \tt volatile) that \tt T has, or the code will fail to
    compile. Use qSharedPointerConstCast to cast away the constness.

    \sa QWeakPointer::toStrongRef(), qSharedPointerDynamicCast(), qSharedPointerConstCast()
*/

/*!
    \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerDynamicCast(const QSharedPointer<T> &src)
    \relates QSharedPointer

    Returns a shared pointer to the pointer held by \a src, using a
    dynamic cast to type \tt X to obtain an internal pointer of the
    appropriate type. If the \tt dynamic_cast fails, the object
    returned will be null.

    Note that \tt X must have the same cv-qualifiers (\tt const and
    \tt volatile) that \tt T has, or the code will fail to
    compile. Use qSharedPointerConstCast to cast away the constness.

    \sa QSharedPointer::dynamicCast(), qSharedPointerCast(), qSharedPointerConstCast()
*/

/*!
    \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerDynamicCast(const QWeakPointer<T> &src)
    \relates QSharedPointer
    \relates QWeakPointer

    Returns a shared pointer to the pointer held by \a src, using a
    dynamic cast to type \tt X to obtain an internal pointer of the
    appropriate type. If the \tt dynamic_cast fails, the object
    returned will be null.

    The \a src object is converted first to a strong reference. If
    that conversion fails (because the object it's pointing to has
    already been deleted), this function also returns a null
    QSharedPointer.

    Note that \tt X must have the same cv-qualifiers (\tt const and
    \tt volatile) that \tt T has, or the code will fail to
    compile. Use qSharedPointerConstCast to cast away the constness.

    \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerConstCast()
*/

/*!
    \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerConstCast(const QSharedPointer<T> &src)
    \relates QSharedPointer

    Returns a shared pointer to the pointer held by \a src, cast to
    type \tt X.  The types \tt T and \tt X must belong to one
    hierarchy for the \tt const_cast to succeed. The \tt const and \tt
    volatile differences between \tt T and \tt X are ignored.

    \sa QSharedPointer::constCast(), qSharedPointerCast(), qSharedPointerDynamicCast()
*/

/*!
    \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerConstCast(const QWeakPointer<T> &src)
    \relates QSharedPointer
    \relates QWeakPointer

    Returns a shared pointer to the pointer held by \a src, cast to
    type \tt X. The types \tt T and \tt X must belong to one
    hierarchy for the \tt const_cast to succeed. The \tt const and
    \tt volatile differences between \tt T and \tt X are ignored.

    The \a src object is converted first to a strong reference. If
    that conversion fails (because the object it's pointing to has
    already been deleted), this function returns a null
    QSharedPointer.

    \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerDynamicCast()
*/

/*!
    \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &src)
    \relates QSharedPointer
    \since 4.6

    \brief The qSharedPointerObjectCast function is for casting a shared pointer.

    Returns a shared pointer to the pointer held by \a src, using a
    \l qobject_cast() to type \tt X to obtain an internal pointer of the
    appropriate type. If the \tt qobject_cast fails, the object
    returned will be null.

    Note that \tt X must have the same cv-qualifiers (\tt const and
    \tt volatile) that \tt T has, or the code will fail to
    compile. Use qSharedPointerConstCast to cast away the constness.

    \sa QSharedPointer::objectCast(), qSharedPointerCast(), qSharedPointerConstCast()
*/

/*!
    \fn template <class X, class T> std::shared_ptr<X> qSharedPointerObjectCast(const std::shared_ptr<T> &src)
    \relates QSharedPointer
    \since 5.14

    Returns a shared pointer to the pointer held by \a src, using a
    \l qobject_cast() to type \tt X to obtain an internal pointer of the
    appropriate type. If the \tt qobject_cast fails, the object
    returned will be null.

    Note that \tt X must have the same cv-qualifiers (\tt const and
    \tt volatile) that \tt T has, or the code will fail to
    compile. Use const_pointer_cast to cast away the constness.
*/

/*!
    \fn template <class X, class T> std::shared_ptr<X> qobject_pointer_cast(const std::shared_ptr<T> &src)
    \relates QSharedPointer
    \since 5.14

    Returns a shared pointer to the pointer held by \a src.

    Same as qSharedPointerObjectCast(). This function is provided for STL
    compatibility.
*/

/*!
    \fn template <class X, class T> std::shared_ptr<X> qSharedPointerObjectCast(std::shared_ptr<T> &&src)
    \relates QSharedPointer
    \since 5.14

    Returns a shared pointer to the pointer held by \a src, using a
    \l qobject_cast() to type \tt X to obtain an internal pointer of the
    appropriate type.

    If the \tt qobject_cast succeeds, the function will return a valid shared
    pointer, and \a src is reset to null. If the \tt qobject_cast fails, the
    object returned will be null, and \a src will not be modified.

    Note that \tt X must have the same cv-qualifiers (\tt const and
    \tt volatile) that \tt T has, or the code will fail to
    compile. Use const_pointer_cast to cast away the constness.
*/

/*!
    \fn template <class X, class T> std::shared_ptr<X> qobject_pointer_cast(std::shared_ptr<T> &&src)
    \relates QSharedPointer
    \since 5.14

    Same as qSharedPointerObjectCast(). This function is provided for STL
    compatibility.
*/

/*!
    \fn template <class X> template <class T> QSharedPointer<X> qSharedPointerObjectCast(const QWeakPointer<T> &src)
    \relates QSharedPointer
    \relates QWeakPointer
    \since 4.6

    \brief The qSharedPointerObjectCast function is for casting a shared pointer.

    Returns a shared pointer to the pointer held by \a src, using a
    \l qobject_cast() to type \tt X to obtain an internal pointer of the
    appropriate type. If the \tt qobject_cast fails, the object
    returned will be null.

    The \a src object is converted first to a strong reference. If
    that conversion fails (because the object it's pointing to has
    already been deleted), this function also returns a null
    QSharedPointer.

    Note that \tt X must have the same cv-qualifiers (\tt const and
    \tt volatile) that \tt T has, or the code will fail to
    compile. Use qSharedPointerConstCast to cast away the constness.

    \sa QWeakPointer::toStrongRef(), qSharedPointerCast(), qSharedPointerConstCast()
*/


/*!
    \fn template <class X> template <class T> QWeakPointer<X> qWeakPointerCast(const QWeakPointer<T> &src)
    \relates QWeakPointer

    Returns a weak pointer to the pointer held by \a src, cast to
    type \tt X. The types \tt T and \tt X must belong to one
    hierarchy for the \tt static_cast to succeed.

    Note that \tt X must have the same cv-qualifiers (\tt const and
    \tt volatile) that \tt T has, or the code will fail to
    compile. Use qSharedPointerConstCast to cast away the constness.
*/

#include <qset.h>
#include <qmutex.h>

#if !defined(QT_NO_QOBJECT)
#include "private/qobject_p.h"

QT_BEGIN_NAMESPACE

/*!
    \internal
    This function is called for a just-created QObject \a obj, to enable
    the use of QSharedPointer and QWeakPointer in the future.
 */
void QtSharedPointer::ExternalRefCountData::setQObjectShared(const QObject *, bool)
{}

/*!
    \internal
    This function is called when a QSharedPointer is created from a QWeakPointer

    We check that the QWeakPointer was really created from a QSharedPointer, and
    not from a QObject.
*/
void QtSharedPointer::ExternalRefCountData::checkQObjectShared(const QObject *)
{
    if (strongref.loadRelaxed() < 0)
        qWarning("QSharedPointer: cannot create a QSharedPointer from a QObject-tracking QWeakPointer");
}

QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::getAndRef(const QObject *obj)
{
    Q_ASSERT(obj);
    QObjectPrivate *d = QObjectPrivate::get(const_cast<QObject *>(obj));
    Q_ASSERT_X(!d->wasDeleted, "QWeakPointer", "Detected QWeakPointer creation in a QObject being deleted");

    ExternalRefCountData *that = d->sharedRefcount.loadRelaxed();
    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.storeRelaxed(-1);
    x->weakref.storeRelaxed(2);  // the QWeakPointer that called us plus the QObject itself

    ExternalRefCountData *ret;
    if (d->sharedRefcount.testAndSetOrdered(nullptr, x, ret)) {     // ought to be release+acquire; this is acq_rel+acquire
        ret = x;
    } else {
        // ~ExternalRefCountData has a Q_ASSERT, so we use this trick to
        // only execute this if Q_ASSERTs are enabled
        Q_ASSERT((x->weakref.storeRelaxed(0), true));
        delete x;
        ret->weakref.ref();
    }
    return ret;
}

/**
    \internal
    Returns a QSharedPointer<QObject> if the variant contains
    a QSharedPointer<T> where T inherits QObject. Otherwise the behaviour is undefined.
*/
QSharedPointer<QObject> QtSharedPointer::sharedPointerFromVariant_internal(const QVariant &variant)
{
    Q_ASSERT(QMetaType::typeFlags(variant.userType()) & QMetaType::SharedPointerToQObject);
    return *reinterpret_cast<const QSharedPointer<QObject>*>(variant.constData());
}

/**
    \internal
    Returns a QWeakPointer<QObject> if the variant contains
    a QWeakPointer<T> where T inherits QObject. Otherwise the behaviour is undefined.
*/
QWeakPointer<QObject> QtSharedPointer::weakPointerFromVariant_internal(const QVariant &variant)
{
    Q_ASSERT(QMetaType::typeFlags(variant.userType()) & QMetaType::WeakPointerToQObject || QMetaType::typeFlags(variant.userType()) & QMetaType::TrackingPointerToQObject);
    return *reinterpret_cast<const QWeakPointer<QObject>*>(variant.constData());
}

QT_END_NAMESPACE

#endif



//#  define QT_SHARED_POINTER_BACKTRACE_SUPPORT
#  ifdef QT_SHARED_POINTER_BACKTRACE_SUPPORT
#    if defined(__GLIBC__) && (__GLIBC__ >= 2) && !defined(__UCLIBC__) && !defined(QT_LINUXBASE)
#      define BACKTRACE_SUPPORTED
#    elif defined(Q_OS_MAC)
#      define BACKTRACE_SUPPORTED
#    endif
#  endif

#  if defined(BACKTRACE_SUPPORTED)
#    include <sys/types.h>
#    include <execinfo.h>
#    include <stdio.h>
#    include <unistd.h>
#    include <sys/wait.h>

QT_BEGIN_NAMESPACE

static inline QByteArray saveBacktrace() __attribute__((always_inline));
static inline QByteArray saveBacktrace()
{
    static const int maxFrames = 32;

    QByteArray stacktrace;
    stacktrace.resize(sizeof(void*) * maxFrames);
    int stack_size = backtrace((void**)stacktrace.data(), maxFrames);
    stacktrace.resize(sizeof(void*) * stack_size);

    return stacktrace;
}

static void printBacktrace(QByteArray stacktrace)
{
    void *const *stack = (void *const *)stacktrace.constData();
    int stack_size = stacktrace.size() / sizeof(void*);
    char **stack_symbols = backtrace_symbols(stack, stack_size);

    int filter[2];
    pid_t child = -1;
    if (pipe(filter) != -1)
        child = fork();
    if (child == 0) {
        // child process
        dup2(fileno(stderr), fileno(stdout));
        dup2(filter[0], fileno(stdin));
        close(filter[0]);
        close(filter[1]);
        execlp("c++filt", "c++filt", "-n", NULL);

        // execlp failed
        execl("/bin/cat", "/bin/cat", NULL);
        _exit(127);
    }

    // parent process
    close(filter[0]);
    FILE *output;
    if (child == -1) {
        // failed forking
        close(filter[1]);
        output = stderr;
    } else {
        output = fdopen(filter[1], "w");
    }

    fprintf(stderr, "Backtrace of the first creation (most recent frame first):\n");
    for (int i = 0; i < stack_size; ++i) {
        if (strlen(stack_symbols[i]))
            fprintf(output, "#%-2d %s\n", i, stack_symbols[i]);
        else
            fprintf(output, "#%-2d %p\n", i, stack[i]);
    }

    if (child != -1) {
        fclose(output);
        waitpid(child, 0, 0);
    }
}

QT_END_NAMESPACE

#  endif  // BACKTRACE_SUPPORTED

namespace {
    QT_USE_NAMESPACE
    struct Data {
        const volatile void *pointer;
#  ifdef BACKTRACE_SUPPORTED
        QByteArray backtrace;
#  endif
    };

    class KnownPointers
    {
    public:
        QMutex mutex;
        QHash<const void *, Data> dPointers;
        QHash<const volatile void *, const void *> dataPointers;
    };
}

Q_GLOBAL_STATIC(KnownPointers, knownPointers)

QT_BEGIN_NAMESPACE

namespace QtSharedPointer {
    Q_AUTOTEST_EXPORT void internalSafetyCheckCleanCheck();
}

/*!
    \internal
*/
void QtSharedPointer::internalSafetyCheckAdd(const void *d_ptr, const volatile void *ptr)
{
    KnownPointers *const kp = knownPointers();
    if (!kp)
        return;                 // end-game: the application is being destroyed already

    if (!ptr) {
        // nullptr is allowed to be tracked by more than one QSharedPointer, so we
        // need something else to put in our tracking structures
        ptr = d_ptr;
    }

    QMutexLocker lock(&kp->mutex);
    Q_ASSERT(!kp->dPointers.contains(d_ptr));

    //qDebug("Adding d=%p value=%p", d_ptr, ptr);

    const void *other_d_ptr = kp->dataPointers.value(ptr, 0);
    if (Q_UNLIKELY(other_d_ptr)) {
#  ifdef BACKTRACE_SUPPORTED
        printBacktrace(knownPointers()->dPointers.value(other_d_ptr).backtrace);
#  endif
        qFatal("QSharedPointer: internal self-check failed: pointer %p was already tracked "
               "by another QSharedPointer object %p", ptr, other_d_ptr);
    }

    Data data;
    data.pointer = ptr;
#  ifdef BACKTRACE_SUPPORTED
    data.backtrace = saveBacktrace();
#  endif

    kp->dPointers.insert(d_ptr, data);
    kp->dataPointers.insert(ptr, d_ptr);
    Q_ASSERT(kp->dPointers.size() == kp->dataPointers.size());
}

/*!
    \internal
*/
void QtSharedPointer::internalSafetyCheckRemove(const void *d_ptr)
{
    KnownPointers *const kp = knownPointers();
    if (!kp)
        return;                 // end-game: the application is being destroyed already

    QMutexLocker lock(&kp->mutex);

    const auto it = kp->dPointers.constFind(d_ptr);
    if (Q_UNLIKELY(it == kp->dPointers.cend())) {
        qFatal("QSharedPointer: internal self-check inconsistency: pointer %p was not tracked. "
               "To use QT_SHAREDPOINTER_TRACK_POINTERS, you have to enable it throughout "
               "in your code.", d_ptr);
    }

    const auto it2 = kp->dataPointers.constFind(it->pointer);
    Q_ASSERT(it2 != kp->dataPointers.cend());

    //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 (Q_UNLIKELY(kp->dPointers.size() != kp->dataPointers.size()))
        qFatal("Internal consistency error: the number of pointers is not equal!");

    if (Q_UNLIKELY(!kp->dPointers.isEmpty()))
        qFatal("Pointer cleaning failed: %d entries remaining", kp->dPointers.size());
#  endif
}

QT_END_NAMESPACE
