1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
8 \brief The QTaggedPointer class provides a low-level wrapper around raw
9 pointers that makes it possible to store additional information in otherwise unused bits.
15 Data structures in C++ tend to have a natural alignment in memory, based on
16 the alignment requirements of the members fields. For example a structure
17 containing an integer tends to be aligned to a 4-byte boundary in memory. That
18 means a pointer holding the address of an instance will always have the lower
19 two bits set to zero. QTaggedPointer makes it possible to store information
20 in these bits, such as a user provided enum. This is called a tag. The API allows
21 reading and writing the tag. When asked for the raw pointer, it will always return
22 a valid address with the bits used for the tag set to zero.
24 This pattern may be useful when creating low-level data structures that
25 need to be as dense as possible.
27 The first template parameter is the type the tagged pointer should point
28 to. The second template parameter is the type of the tag. If not specified it will
29 default to an unsigned integral. A more powerful pattern though is to define a
30 flag enum and use that as a tag type:
40 Q_DECLARE_FLAGS(MyFlags, MyFlag)
42 QTaggedPointer<LinkedListItem, MyFlag> next;
47 Q_DECLARE_OPERATORS_FOR_FLAGS(LinkedListItem::MyFlags)
49 LinkedListItem &listItem = ...
50 listItem.next = new LinkedListItem;
51 listItem.next.setTag(LinkedListItem::SomeOption | LinkedListItem::ThirdWay);
54 \note QTaggedPointer does not provide ownership. You are responsible for deleting
55 the data the pointer points to.
59 \typedef QTaggedPointer::Type
65 \typedef QTaggedPointer::TagType
72 \fn template <typename T, typename Tag> QTaggedPointer<T, Tag>::QTaggedPointer()
74 Creates a tagged pointer that contains nullptr and stores no tag.
78 \fn template <typename T, typename Tag> QTaggedPointer<T, Tag>::QTaggedPointer(std::nullptr_t)
80 Creates a tagged pointer that contains nullptr and stores no tag.
84 \fn template <typename T, typename Tag> explicit QTaggedPointer<T, Tag>::QTaggedPointer(T *pointer = nullptr, Tag tag = Tag()) noexcept
86 Creates a tagged pointer that points to \a pointer and stores the specified \a tag.
90 \fn template <typename T, typename Tag> T &QTaggedPointer<T, Tag>::operator*() const noexcept
92 Provides access to the pointer's members.
96 \fn template <typename T, typename Tag> T *QTaggedPointer<T, Tag>::operator->() const noexcept
98 Provides access to the pointer's members.
102 \fn template <typename T, typename Tag> bool QTaggedPointer<T, Tag>::operator!(QTaggedPointer<T, Tag> pointer) noexcept
104 Returns \c true if \a pointer is \nullptr.
108 \fn template <typename T, typename Tag> explicit QTaggedPointer<T, Tag>::operator bool() const noexcept
110 Returns \c true if the pointer is \e not null.
114 \fn template <typename T, typename Tag> QTaggedPointer<T, Tag> &QTaggedPointer<T, Tag>::operator=(T *other) noexcept
116 Sets the pointer of this to \a other. The tag remains unchanged.
120 \fn template <typename T, typename Tag> void QTaggedPointer<T, Tag>::setTag(Tag tag)
122 Sets the tag value to the specified \a tag. The pointer remains unchanged.
126 \fn template <typename T, typename Tag> Tag QTaggedPointer<T, Tag>::tag() const noexcept
128 Returns the tag stored in the tagged pointer.
132 \fn template <typename T, typename Tag> T *QTaggedPointer<T, Tag>::data() const noexcept
134 Returns the pointer stored in the tagged pointer.
138 \fn template <typename T, typename Tag> bool QTaggedPointer<T, Tag>::isNull() const noexcept
140 Returns \c true if the pointer is \nullptr; otherwise returns \c false.
144 \fn template <typename T, typename Tag> void QTaggedPointer<T, Tag>::swap(QTaggedPointer<T, Tag> &other) noexcept
146 Swaps this instance's pointer and tag with the pointer and tag in \a other.
150 \fn template <typename T, typename Tag> bool QTaggedPointer<T, Tag>::operator==(QTaggedPointer<T, Tag> lhs, QTaggedPointer<T, Tag> rhs) noexcept
152 Returns \c true if \a lhs is equal to \a rhs; otherwise returns \c false.
154 Two tagged pointers are considered equal if they point to the same object. Their tags are not compared.
158 \fn template <typename T, typename Tag> bool QTaggedPointer<T, Tag>::operator!=(QTaggedPointer<T, Tag> lhs, QTaggedPointer<T, Tag> rhs) noexcept
160 Returns \c true if \a lhs is not equal to \a rhs; otherwise returns \c false.
162 Two tagged pointers are considered equal if they point to the same object. Their tags are not compared.
166 \fn template <typename T, typename Tag> bool QTaggedPointer<T, Tag>::operator==(QTaggedPointer<T, Tag> lhs, std::nullptr_t) noexcept
168 Returns \c true if \a lhs refers to \c nullptr.
172 \fn template <typename T, typename Tag> bool QTaggedPointer<T, Tag>::operator==(std::nullptr_t, QTaggedPointer<T, Tag> rhs) noexcept
174 Returns \c true if \a rhs refers to \c nullptr.
178 \fn template <typename T, typename Tag> bool QTaggedPointer<T, Tag>::operator!=(QTaggedPointer<T, Tag> lhs, std::nullptr_t) noexcept
180 Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer.
184 \fn template <typename T, typename Tag> bool QTaggedPointer<T, Tag>::operator!=(std::nullptr_t, QTaggedPointer<T, Tag> rhs) noexcept
186 Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer.
190 \fn template <typename T, typename Tag> qHash(QTaggedPointer<T, Tag> key, std::size_t seed = 0)
191 \relates QTaggedPointer
193 Returns the hash value for the \a key, using \a seed to seed the calculation.