Add documentation for QTaggedPointer
The class remains \internal though, as it has a very narrow use-case for low-level code inside Qt. Change-Id: I9d2b6486ce29b290af7f930a0bfc78590a83cc01 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
4a702e580e
commit
044f730214
@ -80,7 +80,7 @@ public:
|
||||
static constexpr quintptr tagMask() { return QtPrivate::TagInfo<T>::alignment - 1; }
|
||||
static constexpr quintptr pointerMask() { return ~tagMask(); }
|
||||
|
||||
explicit QTaggedPointer(Type *pointer = nullptr, TagType tag = TagType()) noexcept
|
||||
explicit QTaggedPointer(T *pointer = nullptr, Tag tag = Tag()) noexcept
|
||||
: d(quintptr(pointer))
|
||||
{
|
||||
Q_STATIC_ASSERT(sizeof(Type*) == sizeof(QTaggedPointer<Type>));
|
||||
@ -91,7 +91,7 @@ public:
|
||||
setTag(tag);
|
||||
}
|
||||
|
||||
Type &operator*() const
|
||||
Type &operator*() const noexcept
|
||||
{
|
||||
Q_ASSERT(pointer());
|
||||
return *pointer();
|
||||
@ -102,7 +102,7 @@ public:
|
||||
return pointer();
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
explicit operator bool() const noexcept
|
||||
{
|
||||
return !isNull();
|
||||
}
|
||||
@ -119,12 +119,12 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
static constexpr TagType maximumTag() noexcept
|
||||
static constexpr Tag maximumTag() noexcept
|
||||
{
|
||||
return TagType(typename QtPrivate::TagInfo<T>::TagType(tagMask()));
|
||||
}
|
||||
|
||||
void setTag(TagType tag)
|
||||
void setTag(Tag tag)
|
||||
{
|
||||
Q_ASSERT_X((static_cast<typename QtPrivate::TagInfo<T>::TagType>(tag) & pointerMask()) == 0,
|
||||
"QTaggedPointer<T, Tag>::setTag", "Tag is larger than allowed by number of available tag bits");
|
||||
@ -132,12 +132,12 @@ public:
|
||||
d = (d & pointerMask()) | (static_cast<typename QtPrivate::TagInfo<T>::TagType>(tag) & tagMask());
|
||||
}
|
||||
|
||||
TagType tag() const noexcept
|
||||
Tag tag() const noexcept
|
||||
{
|
||||
return TagType(typename QtPrivate::TagInfo<T>::TagType(d & tagMask()));
|
||||
}
|
||||
|
||||
Type* pointer() const noexcept
|
||||
T* pointer() const noexcept
|
||||
{
|
||||
return reinterpret_cast<T*>(d & pointerMask());
|
||||
}
|
||||
@ -147,7 +147,7 @@ public:
|
||||
return !pointer();
|
||||
}
|
||||
|
||||
void swap(QTaggedPointer<Type, Tag> &other) noexcept
|
||||
void swap(QTaggedPointer<T, Tag> &other) noexcept
|
||||
{
|
||||
qSwap(d, other.d);
|
||||
}
|
||||
|
206
src/corelib/tools/qtaggedpointer.qdoc
Normal file
206
src/corelib/tools/qtaggedpointer.qdoc
Normal file
@ -0,0 +1,206 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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<LinkedListItem, MyFlag> 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 <typename T, typename Tag> explicit QTaggedPointer<T, Tag>::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 <typename T, typename Tag> T &QTaggedPointer<T, Tag>::operator*() const noexcept
|
||||
|
||||
Provides access to the pointer's members.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T, typename Tag> T *QTaggedPointer<T, Tag>::operator->() const noexcept
|
||||
|
||||
Provides access to the pointer's members.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T, typename Tag> bool QTaggedPointer<T, Tag>::operator!() const noexcept
|
||||
|
||||
Returns \c true if the pointer is \nullptr.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T, typename Tag> explicit QTaggedPointer<T, Tag>::operator bool() const noexcept
|
||||
|
||||
Returns \c true if the pointer is \e not null.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T, typename Tag> QTaggedPointer<T, Tag> &QTaggedPointer<T, Tag>::operator=(T *other) noexcept
|
||||
|
||||
Sets the pointer of this to \a other. The tag remains unchanged.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T, typename Tag> void QTaggedPointer<T, Tag>::setTag(Tag tag)
|
||||
|
||||
Sets the tag value to the specified \a tag. The pointer remains unchanged.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T, typename Tag> Tag QTaggedPointer<T, Tag>::tag() const noexcept
|
||||
|
||||
Returns the tag stored in the tagged pointer.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T, typename Tag> Tag QTaggedPointer<T, Tag>::pointer() const noexcept
|
||||
|
||||
Returns the pointer stored in the tagged pointer.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T, typename Tag> bool QTaggedPointer<T, Tag>::isNull() const noexcept
|
||||
|
||||
Returns \c true if the pointer is \nullptr; otherwise returns \c false.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T, typename Tag> void QTaggedPointer<T, Tag>::swap(QTaggedPointer<T, Tag> &other) noexcept
|
||||
|
||||
Swaps this instance's pointer and tag with the pointer and tag in \a other.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T, typename Tag> inline bool operator==(const QTaggedPointer<T, Tag> &lhs, const QTaggedPointer<T, Tag> &rhs) noexcept
|
||||
\relates QTaggedPointer
|
||||
|
||||
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 <typename T, typename Tag> inline bool operator!=(const QTaggedPointer<T, Tag> &lhs, const QTaggedPointer<T, Tag> &rhs) noexcept
|
||||
\relates QTaggedPointer
|
||||
|
||||
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 <typename T, typename Tag> inline bool operator==(const QTaggedPointer<T, Tag> &lhs, std::nullptr_t) noexcept
|
||||
\relates QTaggedPointer
|
||||
|
||||
Returns \c true if \a lhs refers to \c nullptr.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T, typename Tag> inline bool operator==(std::nullptr_t, const QTaggedPointer<T, Tag> &rhs) noexcept
|
||||
\relates QTaggedPointer
|
||||
|
||||
Returns \c true if \a rhs refers to \c nullptr.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T, typename Tag> inline bool operator!=(const QTaggedPointer<T, Tag> &lhs, std::nullptr_t) noexcept
|
||||
\relates QTaggedPointer
|
||||
|
||||
Returns \c true if \a lhs refers to a valid (i.e. non-null) pointer.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename T, typename Tag> inline bool operator!=(std::nullptr_t, const QTaggedPointer<T, Tag> &rhs) noexcept
|
||||
\relates QTaggedPointer
|
||||
|
||||
Returns \c true if \a rhs refers to a valid (i.e. non-null) pointer.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user