// Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QFIELDLIST_P_H #define QFIELDLIST_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include #include // QForwardFieldList is a super simple linked list that can only prepend template> class QForwardFieldList { public: inline QForwardFieldList(); inline N *first() const; inline N *takeFirst(); inline void prepend(N *); template inline void copyAndClearPrepend(QForwardFieldList &); inline bool isEmpty() const; inline bool isOne() const; inline bool isMany() const; static inline N *next(N *v); inline Tag tag() const; inline void setTag(Tag t); private: QTaggedPointer _first; }; // QFieldList is a simple linked list, that can append and prepend and also // maintains a count template class QFieldList { public: inline QFieldList(); inline N *first() const; inline N *takeFirst(); inline void append(N *); inline void prepend(N *); inline bool isEmpty() const; inline bool isOne() const; inline bool isMany() const; inline int count() const; inline void append(QFieldList &); inline void prepend(QFieldList &); inline void insertAfter(N *, QFieldList &); inline void copyAndClear(QFieldList &); template inline void copyAndClearAppend(QForwardFieldList &); template inline void copyAndClearPrepend(QForwardFieldList &); static inline N *next(N *v); inline bool flag() const; inline void setFlag(); inline void clearFlag(); inline void setFlagValue(bool); private: N *_first; N *_last; quint32 _flag:1; quint32 _count:31; }; template QForwardFieldList::QForwardFieldList() { } template N *QForwardFieldList::first() const { return _first.data(); } template N *QForwardFieldList::takeFirst() { N *value = _first.data(); if (value) { _first = next(value); value->*nextMember = nullptr; } return value; } template void QForwardFieldList::prepend(N *v) { Q_ASSERT(v->*nextMember == nullptr); v->*nextMember = _first.data(); _first = v; } template template void QForwardFieldList::copyAndClearPrepend(QForwardFieldList &o) { _first = nullptr; while (N *n = o.takeFirst()) prepend(n); } template bool QForwardFieldList::isEmpty() const { return _first.isNull(); } template bool QForwardFieldList::isOne() const { return _first.data() && _first->*nextMember == 0; } template bool QForwardFieldList::isMany() const { return _first.data() && _first->*nextMember != 0; } template N *QForwardFieldList::next(N *v) { Q_ASSERT(v); return v->*nextMember; } template Tag QForwardFieldList::tag() const { return _first.tag(); } template void QForwardFieldList::setTag(Tag t) { _first.setTag(t); } template QFieldList::QFieldList() : _first(nullptr), _last(nullptr), _flag(0), _count(0) { } template N *QFieldList::first() const { return _first; } template N *QFieldList::takeFirst() { N *value = _first; if (value) { _first = next(value); if (_last == value) { Q_ASSERT(_first == nullptr); _last = nullptr; } value->*nextMember = nullptr; --_count; } return value; } template void QFieldList::append(N *v) { Q_ASSERT(v->*nextMember == nullptr); if (isEmpty()) { _first = v; _last = v; } else { _last->*nextMember = v; _last = v; } ++_count; } template void QFieldList::prepend(N *v) { Q_ASSERT(v->*nextMember == nullptr); if (isEmpty()) { _first = v; _last = v; } else { v->*nextMember = _first; _first = v; } ++_count; } template bool QFieldList::isEmpty() const { return _count == 0; } template bool QFieldList::isOne() const { return _count == 1; } template bool QFieldList::isMany() const { return _count > 1; } template int QFieldList::count() const { return _count; } template N *QFieldList::next(N *v) { Q_ASSERT(v); return v->*nextMember; } template void QFieldList::append(QFieldList &o) { if (!o.isEmpty()) { if (isEmpty()) { _first = o._first; _last = o._last; _count = o._count; } else { _last->*nextMember = o._first; _last = o._last; _count += o._count; } o._first = o._last = 0; o._count = 0; } } template void QFieldList::prepend(QFieldList &o) { if (!o.isEmpty()) { if (isEmpty()) { _first = o._first; _last = o._last; _count = o._count; } else { o._last->*nextMember = _first; _first = o._first; _count += o._count; } o._first = o._last = 0; o._count = 0; } } template void QFieldList::insertAfter(N *after, QFieldList &o) { if (after == 0) { prepend(o); } else if (after == _last) { append(o); } else if (!o.isEmpty()) { if (isEmpty()) { _first = o._first; _last = o._last; _count = o._count; } else { o._last->*nextMember = after->*nextMember; after->*nextMember = o._first; _count += o._count; } o._first = o._last = 0; o._count = 0; } } template void QFieldList::copyAndClear(QFieldList &o) { _first = o._first; _last = o._last; _count = o._count; o._first = o._last = nullptr; o._count = 0; } template template void QFieldList::copyAndClearAppend(QForwardFieldList &o) { _first = 0; _last = 0; _count = 0; while (N *n = o.takeFirst()) append(n); } template template void QFieldList::copyAndClearPrepend(QForwardFieldList &o) { _first = nullptr; _last = nullptr; _count = 0; while (N *n = o.takeFirst()) prepend(n); } template bool QFieldList::flag() const { return _flag; } template void QFieldList::setFlag() { _flag = true; } template void QFieldList::clearFlag() { _flag = false; } template void QFieldList::setFlagValue(bool v) { _flag = v; } #endif // QFIELDLIST_P_H