7#ifndef QSSGINVASIVELINKEDLIST_H
8#define QSSGINVASIVELINKEDLIST_H
21#include <QtQuick3DUtils/private/qtquick3dutilsglobal_p.h>
26#define QSSG_VERIFY_NODE(X) if (!(X)) qCritical("Node links are not null!");
28#define QSSG_VERIFY_NODE(X) Q_UNUSED((X));
36 static void set(T &, T *) {}
37 static T *get(
const T &) {
return nullptr; }
40template <
typename T, T *T::*n>
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; }
48template <
typename T, T *T::*p>
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; }
57template<
typename T,
typename HeadOp,
typename TailOp>
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; }
67 T *theHead = HeadOp::get(inObj);
68 T *theTail = TailOp::get(inObj);
70 TailOp::set(*theHead, theTail);
72 HeadOp::set(*theTail, theHead);
73 HeadOp::set(inObj,
nullptr);
74 TailOp::set(inObj,
nullptr);
79 T *theHead = &inPosition;
80 T *theTail = TailOp::get(inPosition);
86 T *theHead = HeadOp::get(inPosition);
87 T *theTail = &inPosition;
99 TailOp::set(*inHead, &inObj);
101 HeadOp::set(*inTail, &inObj);
102 HeadOp::set(inObj, inHead);
103 TailOp::set(inObj, inTail);
107template<
typename T,
typename TailOp>
135template<
typename T, T *T::*Next>
149 if (m_head !=
nullptr)
150 BaseList::insert_before(*m_head, inObj);
165 T *lastObj =
nullptr;
166 for (iterator iter = begin(), endIter = end(); iter != endIter; ++iter)
171 TailOp::set(*lastObj, &inObj);
173 TailOp::set(inObj,
nullptr);
179 m_head = TailOp::get(inObj);
180 BaseList::remove(inObj);
184 T *tail = TailOp::get(*head);
185 while (head && tail != &inObj) {
186 head = TailOp::get(*head);
187 tail = head ? TailOp::get(*head) :
nullptr;
190 if (head && tail == &inObj) {
191 T *oldTail = TailOp::get(inObj);
192 TailOp::set(inObj,
nullptr);
193 TailOp::set(*head, oldTail);
199
200
203 for (
auto it = begin(), e = end(); it != e;)
208
209
210
224template<
typename T, T *T::*Previous, T *T::*Next>
260 if (m_head !=
nullptr)
261 BaseList::insert_before(*m_head, inObj);
263 HeadOp::set(inObj,
nullptr);
279 if (m_tail !=
nullptr)
280 BaseList::insert_after(*m_tail, inObj);
282 TailOp::set(inObj,
nullptr);
292 if (m_head == &inObj)
293 m_head = TailOp::get(inObj);
294 if (m_tail == &inObj)
295 m_tail = HeadOp::get(inObj);
297 BaseList::remove(inObj);
301
302
305 for (
auto it = begin(), e = end(); it != e;)
310
311
312
#define QSSG_VERIFY_NODE(X)
void insert_before(T &inPosition, T &inObj)
const T * head(const T *inObj)
const T * tail(const T *inObj)
void insert_after(T &inPosition, T &inObj)
void insert_unsafe(T *inHead, T *inTail, T &inObj)
const_reverse_iterator rbegin() const
const_iterator begin() const
void push_front(T &inObj)
const_iterator end() const
void clear()
clear will set the head and tail of the list to null.
void removeAll()
removeAll removes all nodes and re-sets their head and tail to null.
reverse_iterator rbegin()
const_reverse_iterator rend() const
void push_front(T &inObj)
void clear()
clear will set the head of the list to null.
const_iterator begin() const
const_iterator end() const
void removeAll()
removeAll removes all nodes and re-sets their tail to null.
bool operator==(const Iterator &inIter) const
QSSGLinkedListIterator(T *inObj=nullptr)
bool operator!=(const Iterator &inIter) const
QSSGLinkedListIterator< T, TailOp > Iterator
static void set(T &o, T *next)
static const T * get(const T &o)
static const T * get(const T &o)
static void set(T &o, T *prev)