Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qtaggedpointer.h
Go to the documentation of this file.
1
// Copyright (C) 2020 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#
ifndef
QTAGGEDPOINTER_H
6
#
define
QTAGGEDPOINTER_H
7
8
#
include
<
QtCore
/
qglobal
.
h
>
9
#
include
<
QtCore
/
qalgorithms
.
h
>
10
#
include
<
QtCore
/
qmath
.
h
>
11
#
include
<
QtCore
/
qtypeinfo
.
h
>
12
13
QT_BEGIN_NAMESPACE
14
15
namespace
QtPrivate
{
16
constexpr
quint8
nextByteSize
(quint8 bits) {
return
quint8((bits + 7) / 8); }
17
18
template
<
typename
T>
19
struct
TagInfo
20
{
21
static
constexpr
size_t
alignment
=
alignof
(T);
22
static_assert
((alignment & (alignment - 1)) == 0,
23
"Alignment of template parameter must be power of two"
);
24
25
static
constexpr
quint8
tagBits
= quint8(qCountTrailingZeroBits(alignment));
26
static_assert
(tagBits > 0,
27
"Alignment of template parameter does not allow any tags"
);
28
29
static
constexpr
size_t
tagSize
= qNextPowerOfTwo(nextByteSize(tagBits));
30
static_assert
(
tagSize
<
sizeof
(
quintptr
),
31
"Alignment of template parameter allows tags masking away pointer"
);
32
33
using
TagType
=
typename
QIntegerForSize
<
tagSize
>::
Unsigned
;
34
};
35
}
36
37
template
<
typename
T,
typename
Tag =
typename
QtPrivate
::
TagInfo
<T>::TagType>
38
class
QTaggedPointer
39
{
40
public
:
41
using
Type
= T;
42
using
TagType
= Tag;
43
44
static
constexpr
quintptr
tagMask
() {
return
QtPrivate
::
TagInfo
<T>::alignment - 1; }
45
static
constexpr
quintptr
pointerMask
() {
return
~tagMask(); }
46
47
Q_NODISCARD_CTOR
constexpr
QTaggedPointer
()
noexcept
:
d
(0) {}
48
Q_NODISCARD_CTOR
constexpr
QTaggedPointer
(
std
::
nullptr_t
)
noexcept
:
QTaggedPointer
() {}
49
50
Q_NODISCARD_CTOR
explicit
QTaggedPointer
(
T
*
pointer
,
Tag
tag
=
Tag
())
noexcept
51
:
d
(
quintptr
(
pointer
) |
quintptr
(
tag
))
52
{
53
static_assert
(
sizeof
(
Type
*) ==
sizeof
(
QTaggedPointer
));
54
55
Q_ASSERT_X
((
quintptr
(
pointer
) &
tagMask
()) == 0,
"QTaggedPointer<T, Tag>"
,
"Pointer is not aligned"
);
56
Q_ASSERT_X
((
static_cast
<
typename
QtPrivate
::
TagInfo
<
T
>::
TagType
>(
tag
) &
pointerMask
()) == 0,
57
"QTaggedPointer<T, Tag>::setTag"
,
"Tag is larger than allowed by number of available tag bits"
);
58
}
59
60
Type
&
operator
*()
const
noexcept
61
{
62
Q_ASSERT(data());
63
return
*data();
64
}
65
66
Type
*
operator
->()
const
noexcept
67
{
68
return
data();
69
}
70
71
explicit
operator
bool
()
const
noexcept
72
{
73
return
!isNull();
74
}
75
76
#
ifdef
Q_QDOC
77
QTaggedPointer
&
operator
=(
T
*
other
)
noexcept
;
78
#
else
79
// Disables the usage of `ptr = {}`, which would go through this operator
80
// (rather than using the implicitly-generated assignment operator).
81
// The operators have different semantics: the ones here leave the tag intact,
82
// the implicitly-generated one overwrites it.
83
template
<
typename
U
,
84
std
::
enable_if_t
<
std
::
is_convertible_v
<
U
*,
T
*>,
bool
> =
false
>
85
QTaggedPointer
&
operator
=(
U
*
other
)
noexcept
86
{
87
T
*
otherT
=
other
;
88
d
=
reinterpret_cast
<
quintptr
>(
otherT
) | (
d
&
tagMask
());
89
return
*
this
;
90
}
91
92
template
<
typename
U
,
93
std
::
enable_if_t
<
std
::
is_null_pointer_v
<
U
>,
bool
> =
false
>
94
QTaggedPointer
&
operator
=(
U
)
noexcept
95
{
96
d
=
reinterpret_cast
<
quintptr
>(
static_cast
<
T
*>(
nullptr
)) | (
d
&
tagMask
());
97
return
*
this
;
98
}
99
#
endif
100
101
static
constexpr
Tag
maximumTag
()
noexcept
102
{
103
return
TagType
(
typename
QtPrivate
::
TagInfo
<
T
>::
TagType
(
tagMask
()));
104
}
105
106
void
setTag
(
Tag
tag
)
107
{
108
Q_ASSERT_X
(
109
(
static_cast
<
quintptr
>(
tag
) &
pointerMask
()) == 0,
110
"QTaggedPointer<T, Tag>::setTag"
,
111
"Tag is larger than allowed by number of available tag bits"
);
112
113
d
= (
d
&
pointerMask
()) |
static_cast
<
quintptr
>(
tag
);
114
}
115
116
Tag
tag
()
const
noexcept
117
{
118
return
TagType
(
typename
QtPrivate
::
TagInfo
<
T
>::
TagType
(
d
&
tagMask
()));
119
}
120
121
T
*
data
()
const
noexcept
122
{
123
return
reinterpret_cast
<
T
*>(
d
&
pointerMask
());
124
}
125
126
bool
isNull
()
const
noexcept
127
{
128
return
!
data
();
129
}
130
131
void
swap
(
QTaggedPointer
&
other
)
noexcept
132
{
133
std
::
swap
(
d
,
other
.
d
);
134
}
135
136
friend
inline
bool
operator
==(
QTaggedPointer
lhs
,
QTaggedPointer
rhs
)
noexcept
137
{
138
return
lhs
.
data
() ==
rhs
.
data
();
139
}
140
141
friend
inline
bool
operator
!=(
QTaggedPointer
lhs
,
QTaggedPointer
rhs
)
noexcept
142
{
143
return
lhs
.
data
() !=
rhs
.
data
();
144
}
145
146
friend
inline
bool
operator
==(
QTaggedPointer
lhs
,
std
::
nullptr_t
)
noexcept
147
{
148
return
lhs
.
isNull
();
149
}
150
151
friend
inline
bool
operator
==(
std
::
nullptr_t
,
QTaggedPointer
rhs
)
noexcept
152
{
153
return
rhs
.
isNull
();
154
}
155
156
friend
inline
bool
operator
!=(
QTaggedPointer
lhs
,
std
::
nullptr_t
)
noexcept
157
{
158
return
!
lhs
.
isNull
();
159
}
160
161
friend
inline
bool
operator
!=(
std
::
nullptr_t
,
QTaggedPointer
rhs
)
noexcept
162
{
163
return
!
rhs
.
isNull
();
164
}
165
166
friend
inline
bool
operator
!(
QTaggedPointer
ptr
)
noexcept
167
{
168
return
!
ptr
.
data
();
169
}
170
171
friend
inline
void
swap
(
QTaggedPointer
&
p1
,
QTaggedPointer
&
p2
)
noexcept
172
{
173
p1
.
swap
(
p2
);
174
}
175
176
protected
:
177
quintptr
d
;
178
};
179
180
template
<
typename
T,
typename
Tag>
181
constexpr
inline
std
::
size_t
qHash
(
QTaggedPointer
<T, Tag> p, std::size_t seed = 0)
noexcept
182
{
return
qHash(p.data(), seed); }
183
184
template
<
typename
T,
typename
Tag>
185
class
QTypeInfo
<
QTaggedPointer
<
T
,
Tag
>>
186
:
public
QTypeInfoMerger
<
QTaggedPointer
<
T
,
Tag
>,
quintptr
> {};
187
188
QT_END_NAMESPACE
189
190
#
endif
// QTAGGEDPOINTER_H
QTaggedPointer
Definition
qtaggedpointer.h:39
QTaggedPointer::operator->
Type * operator->() const noexcept
Definition
qtaggedpointer.h:66
QTaggedPointer::TagType
Tag TagType
Definition
qtaggedpointer.h:42
QTaggedPointer::pointerMask
static constexpr quintptr pointerMask()
Definition
qtaggedpointer.h:45
QTaggedPointer::Type
T Type
Definition
qtaggedpointer.h:41
QTaggedPointer::tagMask
static constexpr quintptr tagMask()
Definition
qtaggedpointer.h:44
QTaggedPointer::operator bool
operator bool() const noexcept
Definition
qtaggedpointer.h:71
QTaggedPointer::operator*
Type & operator*() const noexcept
Definition
qtaggedpointer.h:60
QTypeInfo< QUrlTwoFlags< E1, E2 > >
Definition
qurl.h:88
QtPrivate
Definition
qalloc.h:29
QtPrivate::nextByteSize
constexpr quint8 nextByteSize(quint8 bits)
Definition
qtaggedpointer.h:16
qHash
constexpr std::size_t qHash(QTaggedPointer< T, Tag > p, std::size_t seed=0) noexcept
Definition
qtaggedpointer.h:181
QtPrivate::TagInfo
Definition
qtaggedpointer.h:20
QtPrivate::TagInfo::tagSize
static constexpr size_t tagSize
Definition
qtaggedpointer.h:29
QtPrivate::TagInfo::alignment
static constexpr size_t alignment
Definition
qtaggedpointer.h:21
QtPrivate::TagInfo::tagBits
static constexpr quint8 tagBits
Definition
qtaggedpointer.h:25
qtbase
src
corelib
tools
qtaggedpointer.h
Generated on
for Qt by
1.18.0