// 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 #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 Referred &referred) { const auto metaSequence = referred.metaContainer(); return QIterablePrivate::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 QIterablePrivate::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::warnSynthesizedAccess( "at() called on an iterable without native indexed accessors. This is slow"); void *it = meta.constBegin(m_iterable.constPointer()); meta.advanceConstIterator(it, idx); meta.valueAtConstIterator(it, dataPtr); meta.destroyConstIterator(it); #endif }); } void set(qsizetype idx, const QVariant &value) { const QMetaSequence meta = metaContainer(); QtPrivate::QVariantTypeCoercer coercer; const void *dataPtr = coercer.coerce(value, meta.valueMetaType()); if (meta.canSetValueAtIndex()) { meta.setValueAtIndex(mutableIterable(), idx, dataPtr); return; } #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) // We shouldn't second-guess the underlying container QtPrivate::warnSynthesizedAccess( "set() called on an iterable without native indexed accessors. This is slow"); void *it = meta.begin(m_iterable.mutablePointer()); meta.advanceIterator(it, idx); meta.setValueAtIterator(it, dataPtr); meta.destroyIterator(it); #endif } 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 }; void addValue(const QVariant &value, Position position = Unspecified) Q_DECL_EQ_DELETE_X("Use append() or prepend() instead."); void removeValue(Position position = Unspecified) Q_DECL_EQ_DELETE_X("Use removeLast() or removeFirst() instead."); QMetaType valueMetaType() const Q_DECL_EQ_DELETE_X("Use QMetaSequence::valueMetaType() instead."); QT_WARNING_POP #endif // QT_DEPRECATED_SINCE(6, 11) }; } // namespace QtMetaContainerPrivate QT_END_NAMESPACE #endif // QMETASEQUENCE_H