5#ifndef QSSGINVASIVELINKEDLIST_H
6#define QSSGINVASIVELINKEDLIST_H
19#include <QtQuick3DUtils/private/qtquick3dutilsglobal_p.h>
24#define QSSG_VERIFY_NODE(X) if (!(X)) qCritical("Node links are not null!");
26#define QSSG_VERIFY_NODE(X) Q_UNUSED((X));
34 static void set(T &, T *) {}
35 static T *get(
const T &) {
return nullptr; }
38template <
typename T, T *T::*n>
41 static inline T *
get(T &o) {
return o.*n; }
42 static inline const T *
get(
const T &o) {
return o.*n; }
43 static inline void set(T &o, T *next) { o.*n = next; }
46template <
typename T, T *T::*p>
49 static inline T *
get(T &o) {
return o.*p; }
50 static inline const T *
get(
const T &o) {
return o.*p; }
51 static inline void set(T &o, T *prev) { o.*p = prev; }
55template<
typename T,
typename HeadOp,
typename TailOp>
58 inline T *
tail(T *inObj) {
return inObj ? TailOp::get(inObj) :
nullptr; }
59 inline T *
head(T *inObj) {
return inObj ? HeadOp::get(inObj) :
nullptr; }
60 inline const T *
tail(
const T *inObj) {
return inObj ? TailOp::get(inObj) :
nullptr; }
61 inline const T *
head(
const T *inObj) {
return inObj ? HeadOp::get(inObj) :
nullptr; }
65 T *theHead = HeadOp::get(inObj);
66 T *theTail = TailOp::get(inObj);
68 TailOp::set(*theHead, theTail);
70 HeadOp::set(*theTail, theHead);
71 HeadOp::set(inObj,
nullptr);
72 TailOp::set(inObj,
nullptr);
77 T *theHead = &inPosition;
78 T *theTail = TailOp::get(inPosition);
84 T *theHead = HeadOp::get(inPosition);
85 T *theTail = &inPosition;
97 TailOp::set(*inHead, &inObj);
99 HeadOp::set(*inTail, &inObj);
100 HeadOp::set(inObj, inHead);
101 TailOp::set(inObj, inTail);
105template<
typename T,
typename TailOp>
133template<
typename T, T *T::*Next>
147 if (m_head !=
nullptr)
148 BaseList::insert_before(*m_head, inObj);
163 T *lastObj =
nullptr;
164 for (iterator iter = begin(), endIter = end(); iter != endIter; ++iter)
169 TailOp::set(*lastObj, &inObj);
171 TailOp::set(inObj,
nullptr);
177 m_head = TailOp::get(inObj);
178 BaseList::remove(inObj);
182 T *tail = TailOp::get(*head);
183 while (head && tail != &inObj) {
184 head = TailOp::get(*head);
185 tail = head ? TailOp::get(*head) :
nullptr;
188 if (head && tail == &inObj) {
189 T *oldTail = TailOp::get(inObj);
190 TailOp::set(inObj,
nullptr);
191 TailOp::set(*head, oldTail);
197
198
201 for (
auto it = begin(), e = end(); it != e;)
206
207
208
222template<
typename T, T *T::*Previous, T *T::*Next>
258 if (m_head !=
nullptr)
259 BaseList::insert_before(*m_head, inObj);
261 HeadOp::set(inObj,
nullptr);
277 if (m_tail !=
nullptr)
278 BaseList::insert_after(*m_tail, inObj);
280 TailOp::set(inObj,
nullptr);
290 if (m_head == &inObj)
291 m_head = TailOp::get(inObj);
292 if (m_tail == &inObj)
293 m_tail = HeadOp::get(inObj);
295 BaseList::remove(inObj);
299
300
303 for (
auto it = begin(), e = end(); it != e;)
308
309
310
#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)