/**************************************************************************** ** ** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:FDL$ ** 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 Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free ** Documentation License version 1.3 as published by the Free Software ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements ** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ /*! \class QTaggedPointer \internal \inmodule QtCore \brief The QTaggedPointer class provides a low-level wrapper around raw pointers that makes it possible to store additional information in otherwise unused bits. \ingroup tools \reentrant Data structures in C++ tend to have a natural alignment in memory, based on the alignment requirements of the members fields. For example a structure containing an integer tends to be aligned to a 4-byte boundary in memory. That means a pointer holding the address of an instance will always have the lower two bits set to zero. QTaggedPointer makes it possible to store information in these bits, such as a user provided enum. This is called a tag. The API allows reading and writing the tag. When asked for the raw pointer, it will always return a valid address with the bits used for the tag set to zero. This pattern may be useful when creating low-level data structures that need to be as dense as possible. The first template parameter is the type the tagged pointer should point to. The second template parameter is the type of the tag. If not specified it will default to an unsigned integral. A more powerful pattern though is to define a flag enum and use that as a tag type: \code struct LinkedListItem { enum MyFlag { NoOption = 0x0, SomeOption = 0x1, ThirdWay = 0x2 }; Q_DECLARE_FLAGS(MyFlags, MyFlag) QTaggedPointer next; ... }; Q_DECLARE_OPERATORS_FOR_FLAGS(LinkedListItem::MyFlags) LinkedListItem &listItem = ... listItem.next = new LinkedListItem; listItem.next.setTag(LinkedListItem::SomeOption | LinkedListItem::ThirdWay); \endcode \note QTaggedPointer does not provide ownership. You are responsible for deleting the data the pointer points to. */ /*! \typedef QTaggedPointer::Type Typedef for T. */ /*! \typedef QTaggedPointer::TagType Typedef for Tag. */ /*! \fn template QTaggedPointer::QTaggedPointer() Creates a tagged pointer that contains nullptr and stores no tag. */ /*! \fn template QTaggedPointer::QTaggedPointer(std::nullptr_t) Creates a tagged pointer that contains nullptr and stores no tag. */ /*! \fn template explicit QTaggedPointer::QTaggedPointer(T *pointer = nullptr, Tag tag = Tag()) noexcept Creates a tagged pointer that points to \a pointer and stores the specified \a tag. */ /*! \fn template T &QTaggedPointer::operator*() const noexcept Provides access to the pointer's members. */ /*! \fn template T *QTaggedPointer::operator->() const noexcept Provides access to the pointer's members. */ /*! \fn template bool QTaggedPointer::operator!(QTaggedPointer pointer) noexcept Returns \c true if \a pointer is \nullptr. */ /*! \fn template explicit QTaggedPointer::operator bool() const noexcept Returns \c true if the pointer is \e not null. */ /*! \fn template QTaggedPointer &QTaggedPointer::operator=(T *other) noexcept Sets the pointer of this to \a other. The tag remains unchanged. */ /*! \fn template void QTaggedPointer::setTag(Tag tag) Sets the tag value to the specified \a tag. The pointer remains unchanged. */ /*! \fn template Tag QTaggedPointer::tag() const noexcept Returns the tag stored in the tagged pointer. */ /*! \fn template T *QTaggedPointer::data() const noexcept Returns the pointer stored in the tagged pointer. */ /*! \fn template bool QTaggedPointer::isNull() const noexcept Returns \c true if the pointer is \nullptr; otherwise returns \c false. */ /*! \fn template void QTaggedPointer::swap(QTaggedPointer &other) noexcept Swaps this instance's pointer and tag with the pointer and tag in \a other. */ /*! \fn template bool QTaggedPointer::operator==(QTaggedPointer lhs, QTaggedPointer rhs) noexcept Returns \c true if \a lhs is equal to \a rhs; otherwise returns \c false. Two tagged pointers are considered equal if they point to the same object. Their tags are not compared. */ /*! \fn template bool QTaggedPointer::operator!=(QTaggedPointer lhs, QTaggedPointer rhs) noexcept Returns \c true if \a lhs is not equal to \a rhs; otherwise returns \c false. Two tagged pointers are considered equal if they point to the same object. Their tags are not compared. */ /*! \fn template bool QTaggedPointer::operator==(QTaggedPointer lhs, std::nullptr_t) noexcept Returns \c true if \a lhs refers to \c nullptr. */ /*! \fn template bool QTaggedPointer::operator==(std::nullptr_t, QTaggedPointer rhs) noexcept Returns \c true if \a rhs refers to \c nullptr. */ /*! \fn template bool QTaggedPointer::operator!=(QTaggedPointer lhs, std::nullptr_t) noexcept Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer. */ /*! \fn template bool QTaggedPointer::operator!=(std::nullptr_t, QTaggedPointer rhs) noexcept Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer. */ /*! \fn template qHash(QTaggedPointer key, std::size_t seed) \relates QTaggedPointer Returns the hash value for the \a key, using \a seed to seed the calculation. */