// Copyright (C) 2025 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 // Qt-Security score:significant reason:default #ifndef QMETASEQUENCE_H #define QMETASEQUENCE_H #if 0 #pragma qt_class(QMetaSequence) #endif #include #include #include #include QT_BEGIN_NAMESPACE namespace QtMetaContainerPrivate { class SequentialIterator : public QIterator { public: using value_type = QVariant; using reference = QVariant::Reference; using pointer = QVariant::Pointer; static constexpr bool CanNoexceptAssignQVariant = false; static constexpr bool CanNoexceptConvertToQVariant = false; SequentialIterator(QIterator &&it) : QIterator(std::move(it)) {} reference operator*() const { return reference(*this); } pointer operator->() const { return pointer(*this); } reference operator[](qsizetype n) const { return reference(*this + n); } }; class SequentialConstIterator : public QConstIterator { public: using value_type = QVariant; using reference = QVariant::ConstReference; using pointer = QVariant::ConstPointer; static constexpr bool CanNoexceptConvertToQVariant = false; SequentialConstIterator(QConstIterator &&it) : QConstIterator(std::move(it)) {} value_type operator*() const; pointer operator->() const { return pointer(*this); } value_type operator[](qsizetype n) const; }; } // namespace QtMetaContainerPrivate namespace QtPrivate { template QVariant sequentialIteratorToVariant(const Indirect &referred) { const auto metaSequence = referred.metaContainer(); return QtIterablePrivate::retrieveElement(metaSequence.valueMetaType(), [&](void *dataPtr) { metaSequence.valueAtConstIterator(referred.constIterator(), dataPtr); }); } } // namespace QtPrivate template<> inline QVariant::Reference::operator QVariant() const { return QtPrivate::sequentialIteratorToVariant(m_referred); } template<> inline QVariant::Reference & QVariant::Reference::operator=(const QVariant &value) { QtPrivate::QVariantTypeCoercer coercer; m_referred.metaContainer().setValueAtIterator( m_referred.mutableIterator(), coercer.coerce(value, m_referred.metaContainer().valueMetaType())); return *this; } template<> inline QVariant::ConstReference::operator QVariant() const { return QtPrivate::sequentialIteratorToVariant(m_referred); } namespace QtMetaContainerPrivate { inline SequentialConstIterator::value_type SequentialConstIterator::operator*() const { return reference(*this); } inline SequentialConstIterator::value_type SequentialConstIterator::operator[](qsizetype n) const { return reference(*this + n); } class Sequence : public QIterable { public: using Iterator = QTaggedIterator; using RandomAccessIterator = QTaggedIterator; using BidirectionalIterator = QTaggedIterator; using ForwardIterator = QTaggedIterator; using InputIterator = QTaggedIterator; using ConstIterator = QTaggedIterator; using RandomAccessConstIterator = QTaggedIterator; using BidirectionalConstIterator = QTaggedIterator; using ForwardConstIterator = QTaggedIterator; using InputConstIterator = QTaggedIterator; using iterator = Iterator; using const_iterator = ConstIterator; template Sequence(const T *p) : QIterable(QMetaSequence::fromContainer(), p) { Q_UNUSED(m_revision); } template Sequence(T *p) : QIterable(QMetaSequence::fromContainer(), p) { } Sequence() : QIterable(QMetaSequence(), nullptr) { } template Sequence(const QMetaSequence &metaSequence, Pointer iterable) : QIterable(metaSequence, iterable) { } Sequence(const QMetaSequence &metaSequence, QMetaType metaType, void *iterable) : QIterable(metaSequence, metaType.alignOf(), iterable) { } Sequence(const QMetaSequence &metaSequence, QMetaType metaType, const void *iterable) : QIterable(metaSequence, metaType.alignOf(), iterable) { } Sequence(QIterable &&other) : QIterable(std::move(other)) {} Sequence &operator=(QIterable &&other) { QIterable::operator=(std::move(other)); return *this; } ConstIterator begin() const { return constBegin(); } ConstIterator end() const { return constEnd(); } ConstIterator constBegin() const { return ConstIterator(QIterable::constBegin()); } ConstIterator constEnd() const { return ConstIterator(QIterable::constEnd()); } Iterator mutableBegin() { return Iterator(QIterable::mutableBegin()); } Iterator mutableEnd() { return Iterator(QIterable::mutableEnd()); } QVariant at(qsizetype idx) const { const QMetaSequence meta = metaContainer(); return QtIterablePrivate::retrieveElement(meta.valueMetaType(), [&](void *dataPtr) { if (meta.canGetValueAtIndex()) { meta.valueAtIndex(constIterable(), idx, dataPtr); return; } #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) // We shouldn't second-guess the underlying container. QtPrivate::warnSynthesizedIterableAccess( QtPrivate::SynthesizedAccessFunction::SequenceAt); void *it = meta.constBegin(m_iterable.constPointer()); meta.advanceConstIterator(it, idx); meta.valueAtConstIterator(it, dataPtr); meta.destroyConstIterator(it); #endif }); } void setAt(qsizetype idx, const QVariant &value) { const QMetaSequence meta = metaContainer(); QtPrivate::QVariantTypeCoercer coercer; meta.setValueAtIndex(mutableIterable(), idx, coercer.coerce(value, meta.valueMetaType())); } void append(const QVariant &value) { const QMetaSequence meta = metaContainer(); QtPrivate::QVariantTypeCoercer coercer; meta.addValueAtEnd(mutableIterable(), coercer.coerce(value, meta.valueMetaType())); } void prepend(const QVariant &value) { const QMetaSequence meta = metaContainer(); QtPrivate::QVariantTypeCoercer coercer; meta.addValueAtBegin(mutableIterable(), coercer.coerce(value, meta.valueMetaType())); } void removeLast() { metaContainer().removeValueAtEnd(mutableIterable()); } void removeFirst() { metaContainer().removeValueAtBegin(mutableIterable()); } #if QT_DEPRECATED_SINCE(6, 11) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED enum QT_DEPRECATED_VERSION_X_6_11("Use append(), prepend(), removeLast(), or removeFirst() instead.") Position: quint8 { Unspecified, AtBegin, AtEnd }; QT_DEPRECATED_VERSION_X_6_11("Use append() or prepend() instead.") void addValue(const QVariant &value, Position position = Unspecified) { const QMetaSequence meta = metaContainer(); QtPrivate::QVariantTypeCoercer coercer; const void *valuePtr = coercer.coerce(value, meta.valueMetaType()); switch (position) { case AtBegin: if (meta.canAddValueAtBegin()) meta.addValueAtBegin(mutableIterable(), valuePtr); break; case AtEnd: if (meta.canAddValueAtEnd()) meta.addValueAtEnd(mutableIterable(), valuePtr); break; case Unspecified: if (meta.canAddValue()) meta.addValue(mutableIterable(), valuePtr); break; } } QT_DEPRECATED_VERSION_X_6_11("Use removeLast() or removeFirst() instead.") void removeValue(Position position = Unspecified) { const QMetaSequence meta = metaContainer(); switch (position) { case AtBegin: if (meta.canRemoveValueAtBegin()) meta.removeValueAtBegin(mutableIterable()); break; case AtEnd: if (meta.canRemoveValueAtEnd()) meta.removeValueAtEnd(mutableIterable()); break; case Unspecified: if (meta.canRemoveValue()) meta.removeValue(mutableIterable()); break; } } QT_DEPRECATED_VERSION_X_6_11("Use QMetaSequence::valueMetaType() instead.") QMetaType valueMetaType() const { return metaContainer().valueMetaType(); } void set(qsizetype idx, const QVariant &value) Q_DECL_EQ_DELETE_X("Use setAt() instead."); QT_WARNING_POP #endif // QT_DEPRECATED_SINCE(6, 11) }; } // namespace QtMetaContainerPrivate QT_END_NAMESPACE #endif // QMETASEQUENCE_H