summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qtaggedpointer.h
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2020-02-26 16:48:13 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2020-03-17 17:55:27 +0100
commit733ae8a04b4785961b85befc1c4ea6ecc7936a75 (patch)
tree8c244e8b4e2ad63c643584f64703912b6e456819 /src/corelib/tools/qtaggedpointer.h
parent749e37efc5dd9eaa693c4f86253c48c37737aa09 (diff)
Make it possible to use QTaggedPointer within classes
A common pattern in declarative is to use the unused bits in linked list next pointers for additional information storage. The "next" pointer is typically then a tagged pointer of the containing class, which is not fully defined yet. Therefore alignof() can't be used at tagged pointer instantiation time. This patch delays the calls to alignment, etc. until the corresponding functions are used, as in principle the tagged pointer is just a quintptr and no additional information should be needed until operating on it. Change-Id: I87a3578ee921d471e1b60ed5903b549ef0610b97 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/corelib/tools/qtaggedpointer.h')
-rw-r--r--src/corelib/tools/qtaggedpointer.h22
1 files changed, 10 insertions, 12 deletions
diff --git a/src/corelib/tools/qtaggedpointer.h b/src/corelib/tools/qtaggedpointer.h
index 7d631a5e0c..6fa1e67acb 100644
--- a/src/corelib/tools/qtaggedpointer.h
+++ b/src/corelib/tools/qtaggedpointer.h
@@ -73,10 +73,8 @@ namespace QtPrivate {
template <typename T, typename Tag = typename QtPrivate::TagInfo<T>::TagType>
class QTaggedPointer
{
- static constexpr quintptr tagMask = QtPrivate::TagInfo<T>::alignment - 1;
- static constexpr quintptr pointerMask = ~tagMask;
-
- using TagInternalType = typename QtPrivate::TagInfo<T>::TagType;
+ static constexpr quintptr tagMask() { return QtPrivate::TagInfo<T>::alignment - 1; }
+ static constexpr quintptr pointerMask() { return ~tagMask(); }
public:
using Type = T;
@@ -87,7 +85,7 @@ public:
{
Q_STATIC_ASSERT(sizeof(Type*) == sizeof(QTaggedPointer<Type>));
- Q_ASSERT_X((quintptr(pointer) & tagMask) == 0,
+ Q_ASSERT_X((quintptr(pointer) & tagMask()) == 0,
"QTaggedPointer<T, Tag>", "Pointer is not aligned");
setTag(tag);
@@ -111,37 +109,37 @@ public:
QTaggedPointer<T, Tag> &operator=(T *other) noexcept
{
- d = reinterpret_cast<quintptr>(other) | (d & tagMask);
+ d = reinterpret_cast<quintptr>(other) | (d & tagMask());
return *this;
}
QTaggedPointer<T, Tag> &operator=(std::nullptr_t) noexcept
{
- d &= tagMask;
+ d &= tagMask();
return *this;
}
static constexpr TagType maximumTag() noexcept
{
- return TagType(TagInternalType(tagMask));
+ return TagType(typename QtPrivate::TagInfo<T>::TagType(tagMask()));
}
void setTag(TagType tag)
{
- Q_ASSERT_X((static_cast<TagInternalType>(tag) & pointerMask) == 0,
+ 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");
- d = (d & pointerMask) | (static_cast<TagInternalType>(tag) & tagMask);
+ d = (d & pointerMask()) | (static_cast<typename QtPrivate::TagInfo<T>::TagType>(tag) & tagMask());
}
TagType tag() const noexcept
{
- return TagType(TagInternalType(d & tagMask));
+ return TagType(typename QtPrivate::TagInfo<T>::TagType(d & tagMask()));
}
Type* pointer() const noexcept
{
- return reinterpret_cast<T*>(d & pointerMask);
+ return reinterpret_cast<T*>(d & pointerMask());
}
bool isNull() const noexcept