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
qssginvasivelinkedlist_p.h
Go to the documentation of this file.
1
// Copyright (C) 2008-2012 NVIDIA Corporation.
2
// Copyright (C) 2019 The Qt Company Ltd.
3
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4
// Qt-Security score:significant reason:default
5
6
7
#
ifndef
QSSGINVASIVELINKEDLIST_H
8
#
define
QSSGINVASIVELINKEDLIST_H
9
10
//
11
// W A R N I N G
12
// -------------
13
//
14
// This file is not part of the Qt API. It exists purely as an
15
// implementation detail. This header file may change from version to
16
// version without notice, or even be removed.
17
//
18
// We mean it.
19
//
20
21
#
include
<
QtQuick3DUtils
/
private
/
qtquick3dutilsglobal_p
.
h
>
22
23
QT_BEGIN_NAMESPACE
24
25
#
ifdef
QT_DEBUG
26
#
define
QSSG_VERIFY_NODE
(
X
)
if
(
!
(
X
)
)
qCritical
(
"Node links are not null!"
)
;
27
#
else
28
#
define
QSSG_VERIFY_NODE
(
X
)
Q_UNUSED
(
(
X
)
)
;
29
#
endif
30
31
// Used for singly linked list where
32
// items have either no head or tail ptr.
33
template
<
typename
T>
34
struct
QSSGNullOp
35
{
36
static
void
set(T &, T *) {}
37
static
T *get(
const
T &) {
return
nullptr
; }
38
};
39
40
template
<
typename
T, T *T::*n>
41
struct
QSSGListAccessorNext
42
{
43
static
inline
T *
get
(T &o) {
return
o.*n; }
44
static
inline
const
T *
get
(
const
T &o) {
return
o.*n; }
45
static
inline
void
set
(T &o, T *next) { o.*n = next; }
46
};
47
48
template
<
typename
T, T *T::*p>
49
struct
QSSGListAccessorPrevious
50
{
51
static
inline
T *
get
(T &o) {
return
o.*p; }
52
static
inline
const
T *
get
(
const
T &o) {
return
o.*p; }
53
static
inline
void
set
(T &o, T *prev) { o.*p = prev; }
54
};
55
56
// Base linked list without an included head or tail member.
57
template
<
typename
T,
typename
HeadOp,
typename
TailOp>
58
struct
QSSGInvasiveLinkListBase
59
{
60
inline
T *
tail
(T *inObj) {
return
inObj ? TailOp::get(inObj) :
nullptr
; }
61
inline
T *
head
(T *inObj) {
return
inObj ? HeadOp::get(inObj) :
nullptr
; }
62
inline
const
T *
tail
(
const
T *inObj) {
return
inObj ? TailOp::get(inObj) :
nullptr
; }
63
inline
const
T *
head
(
const
T *inObj) {
return
inObj ? HeadOp::get(inObj) :
nullptr
; }
64
65
void
remove
(T &inObj)
66
{
67
T *theHead = HeadOp::get(inObj);
68
T *theTail = TailOp::get(inObj);
69
if
(theHead)
70
TailOp::set(*theHead, theTail);
71
if
(theTail)
72
HeadOp::set(*theTail, theHead);
73
HeadOp::set(inObj,
nullptr
);
74
TailOp::set(inObj,
nullptr
);
75
}
76
77
void
insert_after
(T &inPosition, T &inObj)
78
{
79
T *theHead = &inPosition;
80
T *theTail = TailOp::get(inPosition);
81
insert_unsafe
(
theHead
,
theTail
,
inObj
)
;
82
}
83
84
void
insert_before
(T &inPosition, T &inObj)
85
{
86
T *theHead = HeadOp::get(inPosition);
87
T *theTail = &inPosition;
88
insert_unsafe
(
theHead
,
theTail
,
inObj
)
;
89
}
90
91
// The name here is intentionally named "unsafe" to discourage use
92
// with out knowing what it implies to call this function.
93
// In most cases this will be used to insert before and after a neighboring pair
94
// (see: insert_before()/_after), but it can also be convenient if you want to split
95
// up a list and retain the chain for the removed section.
96
void
insert_unsafe
(T *inHead, T *inTail, T &inObj)
97
{
98
if
(inHead)
99
TailOp::set(*inHead, &inObj);
100
if
(inTail)
101
HeadOp::set(*inTail, &inObj);
102
HeadOp::set(inObj, inHead);
103
TailOp::set(inObj, inTail);
104
}
105
};
106
107
template
<
typename
T,
typename
TailOp>
108
struct
QSSGLinkedListIterator
109
{
110
using
Iterator
=
QSSGLinkedListIterator
<T, TailOp>;
111
T *
m_obj
;
112
explicit
QSSGLinkedListIterator
(T *inObj =
nullptr
) :
m_obj
(inObj) {}
113
114
inline
bool
operator
!=(
const
Iterator
&inIter)
const
{
return
m_obj
!= inIter
.
m_obj
; }
115
inline
bool
operator
==(
const
Iterator
&inIter)
const
{
return
m_obj
== inIter
.
m_obj
; }
116
117
Iterator
&
operator
++()
118
{
119
if
(
m_obj
)
120
m_obj
= TailOp::get(*
m_obj
);
121
return
*
this
;
122
}
123
124
Iterator
operator
++(
int
)
125
{
126
Iterator
retval(*
this
);
127
++(*
this
);
128
return
retval;
129
}
130
131
T &
operator
*() {
return
*
m_obj
; }
132
T *
operator
->() {
return
m_obj
; }
133
};
134
135
template
<
typename
T, T *T::*Next>
136
struct
QSSGInvasiveSingleLinkedList
:
public
QSSGInvasiveLinkListBase
<
T
,
QSSGNullOp
<
T
>,
QSSGListAccessorNext
<
T
,
Next
>>
137
{
138
using
TailOp
=
QSSGListAccessorNext
<
T
,
Next
>;
139
using
List
=
QSSGInvasiveSingleLinkedList
<
T
,
Next
>;
140
using
BaseList
=
QSSGInvasiveLinkListBase
<
T
,
QSSGNullOp
<
T
>,
TailOp
>;
141
using
iterator
=
QSSGLinkedListIterator
<
T
,
TailOp
>;
142
using
const_iterator
=
iterator
;
143
T *
m_head
=
nullptr
;
144
145
inline
T &
front
()
const
{
return
*
m_head
; }
146
147
void
push_front
(T &inObj)
148
{
149
if
(m_head !=
nullptr
)
150
BaseList::insert_before(*m_head, inObj);
151
m_head
= &inObj;
152
}
153
154
void
push_back
(T &inObj)
155
{
156
// The next pointer of the tail must be null.
157
// We assert because if the inObj actually points somewhere then it's
158
// likely that we: Crash at some later point, we loop, or we broke the links
159
// in another list.
160
QSSG_VERIFY_NODE
(TailOp::get(inObj) ==
nullptr
);
161
162
if
(
m_head
==
nullptr
) {
163
m_head
= &inObj;
164
}
else
{
165
T *lastObj =
nullptr
;
166
for
(iterator iter = begin(), endIter = end(); iter != endIter; ++iter)
167
lastObj = &(*iter);
168
169
Q_ASSERT(lastObj);
170
if
(lastObj)
171
TailOp::set(*lastObj, &inObj);
172
}
173
TailOp::set(inObj,
nullptr
);
174
}
175
176
void
remove
(T &inObj)
177
{
178
if
(
m_head
== &inObj) {
179
m_head
= TailOp::get(inObj);
180
BaseList::remove(inObj);
181
}
else
if
(
m_head
) {
182
// We need to find the node pointing to inObj
183
T *head =
m_head
;
184
T *tail = TailOp::get(*head);
185
while
(head && tail != &inObj) {
186
head = TailOp::get(*head);
187
tail = head ? TailOp::get(*head) :
nullptr
;
188
}
189
190
if
(head && tail == &inObj) {
191
T *oldTail = TailOp::get(inObj);
192
TailOp::set(inObj,
nullptr
);
// deteach from the list
193
TailOp::set(*head, oldTail);
// insert old tail to head of inObj
194
}
195
}
196
}
197
198
/*!
199
* \brief removeAll removes all nodes and re-sets their tail to null.
200
*/
201
void
removeAll
()
202
{
203
for
(
auto
it = begin(), e = end(); it != e;)
204
remove
(
*(it++)
)
;
205
}
206
207
/*!
208
* \brief clear will set the head of the list to null.
209
* Note that the nodes are not updated in this case!
210
*/
211
void
clear
()
212
{
213
m_head
=
nullptr
;
214
}
215
216
inline
bool
isEmpty
()
const
{
return
m_head
==
nullptr
; }
217
218
inline
iterator
begin
() {
return
iterator(
m_head
); }
219
inline
iterator
end
() {
return
iterator(
nullptr
); }
220
inline
const_iterator
begin
()
const
{
return
iterator(
m_head
); }
221
inline
const_iterator
end
()
const
{
return
iterator(
nullptr
); }
222
};
223
224
template
<
typename
T, T *T::*Previous, T *T::*Next>
225
struct
QSSGInvasiveLinkedList
:
public
QSSGInvasiveLinkListBase
<
T
,
QSSGListAccessorPrevious
<
T
,
Previous
>,
QSSGListAccessorNext
<
T
,
Next
>>
226
{
227
using
HeadOp
=
QSSGListAccessorPrevious
<
T
,
Previous
>;
228
using
TailOp
=
QSSGListAccessorNext
<
T
,
Next
>;
229
using
List
=
QSSGInvasiveLinkedList
<
T
,
Previous
,
Next
>;
230
using
BaseList
=
QSSGInvasiveLinkListBase
<
T
,
HeadOp
,
TailOp
>;
231
using
iterator
=
QSSGLinkedListIterator
<
T
,
TailOp
>;
232
using
const_iterator
=
iterator
;
233
using
reverse_iterator
=
QSSGLinkedListIterator
<
T
,
HeadOp
>;
234
using
const_reverse_iterator
=
reverse_iterator
;
235
236
T *
m_head
=
nullptr
;
237
T *
m_tail
=
nullptr
;
238
239
inline
T &
front
()
const
240
{
241
Q_ASSERT(
m_head
);
242
return
*
m_head
;
243
}
244
inline
T &
back
()
const
245
{
246
Q_ASSERT(
m_tail
);
247
return
*
m_tail
;
248
}
249
250
inline
T *
front_ptr
()
const
{
return
m_head
; }
251
inline
T *
back_ptr
()
const
{
return
m_tail
; }
252
253
void
push_front
(T &inObj)
254
{
255
// The prev pointer of the head must be null.
256
// If the inObj actually points somewhere then it's likely that we're going to:
257
// Crash at some later point, loop, or that the we just broke the another list.
258
QSSG_VERIFY_NODE
(HeadOp::get(inObj) ==
nullptr
);
259
260
if
(m_head !=
nullptr
)
261
BaseList::insert_before(*m_head, inObj);
262
else
263
HeadOp::set(inObj,
nullptr
);
264
265
m_head
= &inObj;
266
267
if
(
m_tail
==
nullptr
)
268
m_tail
= &inObj;
269
}
270
271
void
push_back
(T &inObj)
272
{
273
// The next pointer of the tail must be null.
274
// We assert because if the inObj actually points somewhere then it's
275
// likely that we: Crash at some later point, we loop, or we broke the links
276
// in another list.
277
QSSG_VERIFY_NODE
(TailOp::get(inObj) ==
nullptr
);
278
279
if
(m_tail !=
nullptr
)
280
BaseList::insert_after(*m_tail, inObj);
281
else
282
TailOp::set(inObj,
nullptr
);
283
284
m_tail
= &inObj;
285
286
if
(
m_head
==
nullptr
)
287
m_head
= &inObj;
288
}
289
290
void
remove
(T &inObj)
291
{
292
if
(
m_head
== &inObj)
293
m_head
= TailOp::get(inObj);
294
if
(
m_tail
== &inObj)
295
m_tail
= HeadOp::get(inObj);
296
297
BaseList::remove(inObj);
298
}
299
300
/*!
301
* \brief removeAll removes all nodes and re-sets their head and tail to null.
302
*/
303
void
removeAll
()
304
{
305
for
(
auto
it = begin(), e = end(); it != e;)
306
remove
(
*(it++)
)
;
307
}
308
309
/*!
310
* \brief clear will set the head and tail of the list to null.
311
* Note that the nodes are not updated in this case!
312
*/
313
void
clear
()
314
{
315
m_head
=
m_tail
=
nullptr
;
316
}
317
318
inline
bool
isEmpty
()
const
{
return
m_head
==
nullptr
; }
319
320
inline
iterator
begin
() {
return
iterator(
m_head
); }
321
inline
iterator
end
() {
return
iterator(
nullptr
); }
322
323
inline
const_iterator
begin
()
const
{
return
iterator(
m_head
); }
324
inline
const_iterator
end
()
const
{
return
iterator(
nullptr
); }
325
326
inline
reverse_iterator
rbegin
() {
return
reverse_iterator(
m_tail
); }
327
inline
reverse_iterator
rend
() {
return
reverse_iterator(
nullptr
); }
328
329
inline
const_reverse_iterator
rbegin
()
const
{
return
reverse_iterator(
m_tail
); }
330
inline
const_reverse_iterator
rend
()
const
{
return
reverse_iterator(
nullptr
); }
331
};
332
333
QT_END_NAMESPACE
334
335
#
endif
// QSSGINVASIVELINKEDLIST_H
QSSG_VERIFY_NODE
#define QSSG_VERIFY_NODE(X)
Definition
qssginvasivelinkedlist_p.h:28
QSSGInvasiveLinkListBase
Definition
qssginvasivelinkedlist_p.h:59
QSSGInvasiveLinkListBase::insert_before
void insert_before(T &inPosition, T &inObj)
Definition
qssginvasivelinkedlist_p.h:84
QSSGInvasiveLinkListBase::head
const T * head(const T *inObj)
Definition
qssginvasivelinkedlist_p.h:63
QSSGInvasiveLinkListBase::tail
const T * tail(const T *inObj)
Definition
qssginvasivelinkedlist_p.h:62
QSSGInvasiveLinkListBase::remove
void remove(T &inObj)
Definition
qssginvasivelinkedlist_p.h:65
QSSGInvasiveLinkListBase::tail
T * tail(T *inObj)
Definition
qssginvasivelinkedlist_p.h:60
QSSGInvasiveLinkListBase::insert_after
void insert_after(T &inPosition, T &inObj)
Definition
qssginvasivelinkedlist_p.h:77
QSSGInvasiveLinkListBase::head
T * head(T *inObj)
Definition
qssginvasivelinkedlist_p.h:61
QSSGInvasiveLinkListBase::insert_unsafe
void insert_unsafe(T *inHead, T *inTail, T &inObj)
Definition
qssginvasivelinkedlist_p.h:96
QSSGInvasiveLinkedList
Definition
qssginvasivelinkedlist_p.h:226
QSSGInvasiveLinkedList::front
T & front() const
Definition
qssginvasivelinkedlist_p.h:239
QSSGInvasiveLinkedList::rbegin
const_reverse_iterator rbegin() const
Definition
qssginvasivelinkedlist_p.h:329
QSSGInvasiveLinkedList::begin
const_iterator begin() const
Definition
qssginvasivelinkedlist_p.h:323
QSSGInvasiveLinkedList::end
iterator end()
Definition
qssginvasivelinkedlist_p.h:321
QSSGInvasiveLinkedList::push_front
void push_front(T &inObj)
Definition
qssginvasivelinkedlist_p.h:253
QSSGInvasiveLinkedList::front_ptr
T * front_ptr() const
Definition
qssginvasivelinkedlist_p.h:250
QSSGInvasiveLinkedList::back
T & back() const
Definition
qssginvasivelinkedlist_p.h:244
QSSGInvasiveLinkedList::end
const_iterator end() const
Definition
qssginvasivelinkedlist_p.h:324
QSSGInvasiveLinkedList::rend
reverse_iterator rend()
Definition
qssginvasivelinkedlist_p.h:327
QSSGInvasiveLinkedList::clear
void clear()
clear will set the head and tail of the list to null.
Definition
qssginvasivelinkedlist_p.h:313
QSSGInvasiveLinkedList::removeAll
void removeAll()
removeAll removes all nodes and re-sets their head and tail to null.
Definition
qssginvasivelinkedlist_p.h:303
QSSGInvasiveLinkedList::m_tail
T * m_tail
Definition
qssginvasivelinkedlist_p.h:237
QSSGInvasiveLinkedList::push_back
void push_back(T &inObj)
Definition
qssginvasivelinkedlist_p.h:271
QSSGInvasiveLinkedList::begin
iterator begin()
Definition
qssginvasivelinkedlist_p.h:320
QSSGInvasiveLinkedList::isEmpty
bool isEmpty() const
Definition
qssginvasivelinkedlist_p.h:318
QSSGInvasiveLinkedList::rbegin
reverse_iterator rbegin()
Definition
qssginvasivelinkedlist_p.h:326
QSSGInvasiveLinkedList::m_head
T * m_head
Definition
qssginvasivelinkedlist_p.h:236
QSSGInvasiveLinkedList::rend
const_reverse_iterator rend() const
Definition
qssginvasivelinkedlist_p.h:330
QSSGInvasiveLinkedList::back_ptr
T * back_ptr() const
Definition
qssginvasivelinkedlist_p.h:251
QSSGInvasiveLinkedList::remove
void remove(T &inObj)
Definition
qssginvasivelinkedlist_p.h:290
QSSGInvasiveSingleLinkedList
Definition
qssginvasivelinkedlist_p.h:137
QSSGInvasiveSingleLinkedList::end
iterator end()
Definition
qssginvasivelinkedlist_p.h:219
QSSGInvasiveSingleLinkedList::push_front
void push_front(T &inObj)
Definition
qssginvasivelinkedlist_p.h:147
QSSGInvasiveSingleLinkedList::clear
void clear()
clear will set the head of the list to null.
Definition
qssginvasivelinkedlist_p.h:211
QSSGInvasiveSingleLinkedList::remove
void remove(T &inObj)
Definition
qssginvasivelinkedlist_p.h:176
QSSGInvasiveSingleLinkedList::m_head
T * m_head
Definition
qssginvasivelinkedlist_p.h:143
QSSGInvasiveSingleLinkedList::begin
const_iterator begin() const
Definition
qssginvasivelinkedlist_p.h:220
QSSGInvasiveSingleLinkedList::begin
iterator begin()
Definition
qssginvasivelinkedlist_p.h:218
QSSGInvasiveSingleLinkedList::end
const_iterator end() const
Definition
qssginvasivelinkedlist_p.h:221
QSSGInvasiveSingleLinkedList::push_back
void push_back(T &inObj)
Definition
qssginvasivelinkedlist_p.h:154
QSSGInvasiveSingleLinkedList::isEmpty
bool isEmpty() const
Definition
qssginvasivelinkedlist_p.h:216
QSSGInvasiveSingleLinkedList::removeAll
void removeAll()
removeAll removes all nodes and re-sets their tail to null.
Definition
qssginvasivelinkedlist_p.h:201
QSSGInvasiveSingleLinkedList::front
T & front() const
Definition
qssginvasivelinkedlist_p.h:145
QSSGLinkedListIterator
Definition
qssginvasivelinkedlist_p.h:109
QSSGLinkedListIterator::m_obj
T * m_obj
Definition
qssginvasivelinkedlist_p.h:111
QSSGLinkedListIterator::operator*
T & operator*()
Definition
qssginvasivelinkedlist_p.h:131
QSSGLinkedListIterator::operator==
bool operator==(const Iterator &inIter) const
Definition
qssginvasivelinkedlist_p.h:115
QSSGLinkedListIterator::QSSGLinkedListIterator
QSSGLinkedListIterator(T *inObj=nullptr)
Definition
qssginvasivelinkedlist_p.h:112
QSSGLinkedListIterator::operator!=
bool operator!=(const Iterator &inIter) const
Definition
qssginvasivelinkedlist_p.h:114
QSSGLinkedListIterator::operator++
Iterator & operator++()
Definition
qssginvasivelinkedlist_p.h:117
QSSGLinkedListIterator::operator++
Iterator operator++(int)
Definition
qssginvasivelinkedlist_p.h:124
QSSGLinkedListIterator::operator->
T * operator->()
Definition
qssginvasivelinkedlist_p.h:132
QSSGLinkedListIterator::Iterator
QSSGLinkedListIterator< T, TailOp > Iterator
Definition
qssginvasivelinkedlist_p.h:110
QSSGListAccessorNext
Definition
qssginvasivelinkedlist_p.h:42
QSSGListAccessorNext::set
static void set(T &o, T *next)
Definition
qssginvasivelinkedlist_p.h:45
QSSGListAccessorNext::get
static T * get(T &o)
Definition
qssginvasivelinkedlist_p.h:43
QSSGListAccessorNext::get
static const T * get(const T &o)
Definition
qssginvasivelinkedlist_p.h:44
QSSGListAccessorPrevious
Definition
qssginvasivelinkedlist_p.h:50
QSSGListAccessorPrevious::get
static const T * get(const T &o)
Definition
qssginvasivelinkedlist_p.h:52
QSSGListAccessorPrevious::set
static void set(T &o, T *prev)
Definition
qssginvasivelinkedlist_p.h:53
QSSGListAccessorPrevious::get
static T * get(T &o)
Definition
qssginvasivelinkedlist_p.h:51
qtquick3d
src
utils
qssginvasivelinkedlist_p.h
Generated on
for Qt by
1.18.0