diff options
Diffstat (limited to 'src/qml/qml/ftw/qintrusivelist_p.h')
-rw-r--r-- | src/qml/qml/ftw/qintrusivelist_p.h | 326 |
1 files changed, 107 insertions, 219 deletions
diff --git a/src/qml/qml/ftw/qintrusivelist_p.h b/src/qml/qml/ftw/qintrusivelist_p.h index 8992be9f93..1170370fae 100644 --- a/src/qml/qml/ftw/qintrusivelist_p.h +++ b/src/qml/qml/ftw/qintrusivelist_p.h @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// 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 QINTRUSIVELIST_P_H #define QINTRUSIVELIST_P_H @@ -51,220 +15,144 @@ // We mean it. // -#include <QtCore/qglobal.h> +#include <QtCore/private/qglobal_p.h> QT_BEGIN_NAMESPACE -class QIntrusiveListNode; -template<class N, QIntrusiveListNode N::*member> -class QIntrusiveList +class QIntrusiveListNode { public: - inline QIntrusiveList(); - inline ~QIntrusiveList(); - - inline bool isEmpty() const; - inline void insert(N *n); - inline void remove(N *n); - inline bool contains(N *) const; - - class iterator { - public: - inline iterator(); - inline iterator(N *value); - - inline N *operator*() const; - inline N *operator->() const; - inline bool operator==(const iterator &other) const; - inline bool operator!=(const iterator &other) const; - inline iterator &operator++(); - - inline iterator &erase(); - - private: - N *_value; - }; - typedef iterator Iterator; - - inline N *first() const; - static inline N *next(N *current); + ~QIntrusiveListNode() { remove(); } + + void remove() + { + if (_prev) *_prev = _next; + if (_next) _next->_prev = _prev; + _prev = nullptr; + _next = nullptr; + } - inline iterator begin(); - inline iterator end(); + bool isInList() const { return _prev != nullptr; } private: - static inline N *nodeToN(QIntrusiveListNode *node); - - QIntrusiveListNode *__first = nullptr; -}; - -class QIntrusiveListNode -{ -public: - inline QIntrusiveListNode(); - inline ~QIntrusiveListNode(); - - inline void remove(); - inline bool isInList() const; + template<class N, QIntrusiveListNode N::*member> + friend class QIntrusiveList; QIntrusiveListNode *_next = nullptr; QIntrusiveListNode**_prev = nullptr; }; template<class N, QIntrusiveListNode N::*member> -QIntrusiveList<N, member>::iterator::iterator() -: _value(nullptr) -{ -} - -template<class N, QIntrusiveListNode N::*member> -QIntrusiveList<N, member>::iterator::iterator(N *value) -: _value(value) -{ -} - -template<class N, QIntrusiveListNode N::*member> -N *QIntrusiveList<N, member>::iterator::operator*() const -{ - return _value; -} - -template<class N, QIntrusiveListNode N::*member> -N *QIntrusiveList<N, member>::iterator::operator->() const -{ - return _value; -} - -template<class N, QIntrusiveListNode N::*member> -bool QIntrusiveList<N, member>::iterator::operator==(const iterator &other) const -{ - return other._value == _value; -} - -template<class N, QIntrusiveListNode N::*member> -bool QIntrusiveList<N, member>::iterator::operator!=(const iterator &other) const -{ - return other._value != _value; -} - -template<class N, QIntrusiveListNode N::*member> -typename QIntrusiveList<N, member>::iterator &QIntrusiveList<N, member>::iterator::operator++() -{ - _value = QIntrusiveList<N, member>::next(_value); - return *this; -} - -template<class N, QIntrusiveListNode N::*member> -typename QIntrusiveList<N, member>::iterator &QIntrusiveList<N, member>::iterator::erase() +class QIntrusiveList { - N *old = _value; - _value = QIntrusiveList<N, member>::next(_value); - (old->*member).remove(); - return *this; -} +private: + template<typename O> + class iterator_impl { + public: + iterator_impl() = default; + iterator_impl(O value) : _value(value) {} + + O operator*() const { return _value; } + O operator->() const { return _value; } + bool operator==(const iterator_impl &other) const { return other._value == _value; } + bool operator!=(const iterator_impl &other) const { return other._value != _value; } + iterator_impl &operator++() + { + _value = QIntrusiveList<N, member>::next(_value); + return *this; + } + + protected: + O _value = nullptr; + }; -template<class N, QIntrusiveListNode N::*member> -QIntrusiveList<N, member>::QIntrusiveList() +public: + class iterator : public iterator_impl<N *> + { + public: + iterator() = default; + iterator(N *value) : iterator_impl<N *>(value) {} + + iterator &erase() + { + N *old = this->_value; + this->_value = QIntrusiveList<N, member>::next(this->_value); + (old->*member).remove(); + return *this; + } + }; -{ -} + using const_iterator = iterator_impl<const N *>; -template<class N, QIntrusiveListNode N::*member> -QIntrusiveList<N, member>::~QIntrusiveList() -{ - while (__first) __first->remove(); -} + using Iterator = iterator; + using ConstIterator = const_iterator; -template<class N, QIntrusiveListNode N::*member> -bool QIntrusiveList<N, member>::isEmpty() const -{ - return __first == nullptr; -} + ~QIntrusiveList() { while (__first) __first->remove(); } -template<class N, QIntrusiveListNode N::*member> -void QIntrusiveList<N, member>::insert(N *n) -{ - QIntrusiveListNode *nnode = &(n->*member); - nnode->remove(); + bool isEmpty() const { return __first == nullptr; } - nnode->_next = __first; - if (nnode->_next) nnode->_next->_prev = &nnode->_next; - __first = nnode; - nnode->_prev = &__first; -} + void insert(N *n) + { + QIntrusiveListNode *nnode = &(n->*member); + nnode->remove(); -template<class N, QIntrusiveListNode N::*member> -void QIntrusiveList<N, member>::remove(N *n) -{ - QIntrusiveListNode *nnode = &(n->*member); - nnode->remove(); -} + nnode->_next = __first; + if (nnode->_next) nnode->_next->_prev = &nnode->_next; + __first = nnode; + nnode->_prev = &__first; + } -template<class N, QIntrusiveListNode N::*member> -bool QIntrusiveList<N, member>::contains(N *n) const -{ - QIntrusiveListNode *nnode = __first; - while (nnode) { - if (nodeToN(nnode) == n) - return true; - nnode = nnode->_next; + void remove(N *n) + { + QIntrusiveListNode *nnode = &(n->*member); + nnode->remove(); } - return false; -} -template<class N, QIntrusiveListNode N::*member> -N *QIntrusiveList<N, member>::first() const -{ - return __first?nodeToN(__first):nullptr; -} + bool contains(const N *n) const + { + QIntrusiveListNode *nnode = __first; + while (nnode) { + if (nodeToN(nnode) == n) + return true; + nnode = nnode->_next; + } + return false; + } -template<class N, QIntrusiveListNode N::*member> -N *QIntrusiveList<N, member>::next(N *current) -{ - QIntrusiveListNode *nextnode = (current->*member)._next; - N *nextstruct = nextnode?nodeToN(nextnode):nullptr; - return nextstruct; -} + const N *first() const { return __first ? nodeToN(__first) : nullptr; } + N *first() { return __first ? nodeToN(__first) : nullptr; } -template<class N, QIntrusiveListNode N::*member> -typename QIntrusiveList<N, member>::iterator QIntrusiveList<N, member>::begin() -{ - return __first?iterator(nodeToN(__first)):iterator(); -} + template<typename O> + static O next(O current) + { + QIntrusiveListNode *nextnode = (current->*member)._next; + return nextnode ? nodeToN(nextnode) : nullptr; + } -template<class N, QIntrusiveListNode N::*member> -typename QIntrusiveList<N, member>::iterator QIntrusiveList<N, member>::end() -{ - return iterator(); -} + iterator begin() { return __first ? iterator(nodeToN(__first)) : iterator(); } + iterator end() { return iterator(); } -template<class N, QIntrusiveListNode N::*member> -N *QIntrusiveList<N, member>::nodeToN(QIntrusiveListNode *node) -{ - return (N *)((char *)node - ((char *)&(((N *)nullptr)->*member) - (char *)nullptr)); -} + const_iterator begin() const + { + return __first ? const_iterator(nodeToN(__first)) : const_iterator(); + } -QIntrusiveListNode::QIntrusiveListNode() -{ -} + const_iterator end() const { return const_iterator(); } -QIntrusiveListNode::~QIntrusiveListNode() -{ - remove(); -} +private: -void QIntrusiveListNode::remove() -{ - if (_prev) *_prev = _next; - if (_next) _next->_prev = _prev; - _prev = nullptr; - _next = nullptr; -} + static N *nodeToN(QIntrusiveListNode *node) + { + QT_WARNING_PUSH +#if defined(Q_CC_CLANG) && Q_CC_CLANG >= 1300 + QT_WARNING_DISABLE_CLANG("-Wnull-pointer-subtraction") +#endif + return (N *)((char *)node - ((char *)&(((N *)nullptr)->*member) - (char *)nullptr)); + QT_WARNING_POP + } -bool QIntrusiveListNode::isInList() const -{ - return _prev != nullptr; -} + QIntrusiveListNode *__first = nullptr; +}; QT_END_NAMESPACE |