QTaggedPointer Class
template <typename T, typename Tag> class QTaggedPointerThe QTaggedPointer class provides a low-level wrapper around raw pointers that makes it possible to store additional information in otherwise unused bits. More...
Header: | #include <QTaggedPointer> |
Public Types
Public Functions
QTaggedPointer() | |
QTaggedPointer(T *pointer = nullptr, Tag tag = Tag()) | |
T * | data() const |
bool | isNull() const |
void | setTag(Tag tag) |
void | swap(QTaggedPointer<T, Tag> &other) |
Tag | tag() const |
Related Non-Members
int | qHash(QTaggedPointer<T, Tag> key, int seed = 0) |
bool | operator!(QTaggedPointer<T, Tag> pointer) |
bool | operator!=(QTaggedPointer<T, Tag> lhs, QTaggedPointer<T, Tag> rhs) |
bool | operator!=(QTaggedPointer<T, Tag> lhs, int) |
bool | operator!=(int, QTaggedPointer<T, Tag> rhs) |
bool | operator==(QTaggedPointer<T, Tag> lhs, QTaggedPointer<T, Tag> rhs) |
bool | operator==(QTaggedPointer<T, Tag> lhs, int) |
bool | operator==(int, QTaggedPointer<T, Tag> rhs) |
Detailed Description
\internal
\inmodule
QtCore
\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:
struct LinkedListItem { enum MyFlag { NoOption = 0x0, SomeOption = 0x1, ThirdWay = 0x2 }; Q_DECLARE_FLAGS(MyFlags, MyFlag) QTaggedPointer<LinkedListItem, MyFlag> next; ... }; Q_DECLARE_OPERATORS_FOR_FLAGS(LinkedListItem::MyFlags) LinkedListItem &listItem = ... listItem.next = new LinkedListItem; listItem.next.setTag(LinkedListItem::SomeOption | LinkedListItem::ThirdWay);
Note: QTaggedPointer does not provide ownership. You are responsible for deleting the data the pointer points to.
Member Type Documentation
[alias]
QTaggedPointer::TagType
Typedef for Tag.
[alias]
QTaggedPointer::Type
Typedef for T.
Member Function Documentation
[constexpr noexcept]
QTaggedPointer::QTaggedPointer()
Creates a tagged pointer that contains nullptr and stores no tag.
[explicit noexcept default]
QTaggedPointer::QTaggedPointer(T *pointer = nullptr, Tag tag = Tag())
Creates a tagged pointer that points to pointer and stores the specified tag.
[noexcept]
T *QTaggedPointer::data() const
Returns the pointer stored in the tagged pointer.
[noexcept]
bool QTaggedPointer::isNull() const
Returns true
if the pointer is nullptr
; otherwise returns false
.
void QTaggedPointer::setTag(Tag tag)
Sets the tag value to the specified tag. The pointer remains unchanged.
See also tag().
[noexcept]
void QTaggedPointer::swap(QTaggedPointer<T, Tag> &other)
Swaps this instance's pointer and tag with the pointer and tag in other.
[noexcept]
Tag QTaggedPointer::tag() const
Returns the tag stored in the tagged pointer.
See also setTag().
Related Non-Members
[constexpr noexcept]
template <typename T, typename Tag> int qHash(QTaggedPointer<T, Tag> key, int seed = 0)
Returns the hash value for the key, using seed to seed the calculation.
[noexcept]
bool operator!(QTaggedPointer<T, Tag> pointer)
Returns true
if pointer is nullptr
.
[noexcept]
bool operator!=(QTaggedPointer<T, Tag> lhs, QTaggedPointer<T, Tag> rhs)
Returns true
if lhs is not equal to rhs; otherwise returns false
.
Two tagged pointers are considered equal if they point to the same object. Their tags are not compared.
[noexcept]
bool operator!=(QTaggedPointer<T, Tag> lhs, int)
Returns true
if lhs refers to a valid (i.e. non-null) pointer.
[noexcept]
bool operator!=(int, QTaggedPointer<T, Tag> rhs)
Returns true
if rhs refers to a valid (i.e. non-null) pointer.
[noexcept]
bool operator==(QTaggedPointer<T, Tag> lhs, QTaggedPointer<T, Tag> rhs)
Returns true
if lhs is equal to rhs; otherwise returns false
.
Two tagged pointers are considered equal if they point to the same object. Their tags are not compared.
[noexcept]
bool operator==(QTaggedPointer<T, Tag> lhs, int)
Returns true
if lhs refers to nullptr
.
[noexcept]
bool operator==(int, QTaggedPointer<T, Tag> rhs)
Returns true
if rhs refers to nullptr
.