QTaggedPointer Class

template <typename T, typename Tag> class QTaggedPointer

The 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
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

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