/**************************************************************************** ** ** 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$ ** ****************************************************************************/ #ifndef QQMLLIST_H #define QQMLLIST_H #include #include #include #include QT_BEGIN_NAMESPACE class QObject; struct QMetaObject; #define QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_APPEND Q_CLASSINFO("QML.ListPropertyAssignBehavior", "Append") #define QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE_IF_NOT_DEFAULT Q_CLASSINFO("QML.ListPropertyAssignBehavior", "ReplaceIfNotDefault") #define QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE Q_CLASSINFO("QML.ListPropertyAssignBehavior", "Replace") #ifndef QQMLLISTPROPERTY #define QQMLLISTPROPERTY template class QQmlListProperty { public: using AppendFunction = void (*)(QQmlListProperty *, T *); using CountFunction = qsizetype (*)(QQmlListProperty *); using AtFunction = T *(*)(QQmlListProperty *, qsizetype); using ClearFunction = void (*)(QQmlListProperty *); using ReplaceFunction = void (*)(QQmlListProperty *, qsizetype, T *); using RemoveLastFunction = void (*)(QQmlListProperty *); QQmlListProperty() = default; QQmlListProperty(QObject *o, QList *list) : object(o), data(list), append(qlist_append), count(qlist_count), at(qlist_at), clear(qlist_clear), replace(qlist_replace), removeLast(qlist_removeLast) {} QQmlListProperty(QObject *o, void *d, AppendFunction a, CountFunction c, AtFunction t, ClearFunction r ) : object(o), data(d), append(a), count(c), at(t), clear(r), replace((a && c && t && r) ? qslow_replace : nullptr), removeLast((a && c && t && r) ? qslow_removeLast : nullptr) {} QQmlListProperty(QObject *o, void *d, AppendFunction a, CountFunction c, AtFunction t, ClearFunction r, ReplaceFunction s, RemoveLastFunction p) : object(o), data(d), append(a), count(c), at(t), clear((!r && p && c) ? qslow_clear : r), replace((!s && a && c && t && (r || p)) ? qslow_replace : s), removeLast((!p && a && c && t && r) ? qslow_removeLast : p) {} QQmlListProperty(QObject *o, void *d, CountFunction c, AtFunction a) : object(o), data(d), count(c), at(a) {} bool operator==(const QQmlListProperty &o) const { return object == o.object && data == o.data && append == o.append && count == o.count && at == o.at && clear == o.clear && replace == o.replace && removeLast == o.removeLast; } QObject *object = nullptr; void *data = nullptr; AppendFunction append = nullptr; CountFunction count = nullptr; AtFunction at = nullptr; ClearFunction clear = nullptr; ReplaceFunction replace = nullptr; RemoveLastFunction removeLast = nullptr; private: static void qlist_append(QQmlListProperty *p, T *v) { reinterpret_cast *>(p->data)->append(v); } static qsizetype qlist_count(QQmlListProperty *p) { return reinterpret_cast *>(p->data)->count(); } static T *qlist_at(QQmlListProperty *p, qsizetype idx) { return reinterpret_cast *>(p->data)->at(idx); } static void qlist_clear(QQmlListProperty *p) { return reinterpret_cast *>(p->data)->clear(); } static void qlist_replace(QQmlListProperty *p, qsizetype idx, T *v) { return reinterpret_cast *>(p->data)->replace(idx, v); } static void qlist_removeLast(QQmlListProperty *p) { return reinterpret_cast *>(p->data)->removeLast(); } static void qslow_replace(QQmlListProperty *list, qsizetype idx, T *v) { const qsizetype length = list->count(list); if (idx < 0 || idx >= length) return; QVector stash; if (list->clear != qslow_clear) { stash.reserve(length); for (qsizetype i = 0; i < length; ++i) stash.append(i == idx ? v : list->at(list, i)); list->clear(list); for (T *item : qAsConst(stash)) list->append(list, item); } else { stash.reserve(length - idx - 1); for (qsizetype i = length - 1; i > idx; --i) { stash.append(list->at(list, i)); list->removeLast(list); } list->removeLast(list); list->append(list, v); while (!stash.isEmpty()) list->append(list, stash.takeLast()); } } static void qslow_clear(QQmlListProperty *list) { for (qsizetype i = 0, end = list->count(list); i < end; ++i) list->removeLast(list); } static void qslow_removeLast(QQmlListProperty *list) { const qsizetype length = list->count(list) - 1; if (length < 0) return; QVector stash; stash.reserve(length); for (qsizetype i = 0; i < length; ++i) stash.append(list->at(list, i)); list->clear(list); for (T *item : qAsConst(stash)) list->append(list, item); } }; #endif class QQmlEngine; class QQmlListReferencePrivate; class Q_QML_EXPORT QQmlListReference { public: QQmlListReference(); QQmlListReference(QObject *, const char *property, QQmlEngine * = nullptr); QQmlListReference(const QQmlListReference &); QQmlListReference &operator=(const QQmlListReference &); ~QQmlListReference(); bool isValid() const; QObject *object() const; const QMetaObject *listElementType() const; bool canAppend() const; bool canAt() const; bool canClear() const; bool canCount() const; bool canReplace() const; bool canRemoveLast() const; bool isManipulable() const; bool isReadable() const; bool append(QObject *) const; QObject *at(qsizetype) const; bool clear() const; qsizetype count() const; bool replace(qsizetype, QObject *) const; bool removeLast() const; bool operator==(const QQmlListReference &other) const {return d == other.d;} private: friend class QQmlListReferencePrivate; QQmlListReferencePrivate* d; }; namespace QtPrivate { template inline constexpr bool IsQmlListType> = true; } QT_END_NAMESPACE Q_DECLARE_METATYPE(QQmlListReference) #endif // QQMLLIST_H