Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-02 09:27:16

0001 // Copyright (C) 2025 The Qt Company Ltd.
0002 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0003 // Qt-Security score:significant reason:default
0004 
0005 #ifndef QMETAASSOCIATION_H
0006 #define QMETAASSOCIATION_H
0007 
0008 #if 0
0009 #pragma qt_class(QMetaAssociation)
0010 #endif
0011 
0012 #include <QtCore/qiterable.h>
0013 #include <QtCore/qiterable_impl.h>
0014 #include <QtCore/qmetacontainer.h>
0015 #include <QtCore/qvariant.h>
0016 
0017 QT_BEGIN_NAMESPACE
0018 
0019 namespace QtMetaContainerPrivate {
0020 
0021 class AssociativeIterator : public QIterator<QMetaAssociation>
0022 {
0023 public:
0024     using key_type = QVariant;
0025     using mapped_type = QVariant;
0026     using reference = QVariant::Reference<AssociativeIterator>;
0027     using pointer = QVariant::Pointer<AssociativeIterator>;
0028 
0029     static constexpr bool CanNoexceptAssignQVariant = false;
0030     static constexpr bool CanNoexceptConvertToQVariant = false;
0031 
0032     AssociativeIterator(QIterator &&it) : QIterator(std::move(it)) {}
0033 
0034     key_type key() const
0035     {
0036         const QMetaAssociation meta = metaContainer();
0037         return QtIterablePrivate::retrieveElement(meta.keyMetaType(), [&](void *dataPtr) {
0038             meta.keyAtIterator(constIterator(), dataPtr);
0039         });
0040     }
0041     reference value() const { return operator*(); }
0042 
0043     reference operator*() const { return reference(*this); }
0044     pointer operator->() const { return pointer(*this); }
0045 };
0046 
0047 class AssociativeConstIterator : public QConstIterator<QMetaAssociation>
0048 {
0049 public:
0050     using key_type = QVariant;
0051     using mapped_type = QVariant;
0052     using reference = QVariant::ConstReference<AssociativeConstIterator>;
0053     using pointer = QVariant::ConstPointer<AssociativeConstIterator>;
0054 
0055     static constexpr bool CanNoexceptConvertToQVariant = false;
0056 
0057     AssociativeConstIterator(QConstIterator &&it) : QConstIterator(std::move(it)) {}
0058 
0059     key_type key() const
0060     {
0061         const QMetaAssociation meta = metaContainer();
0062         return QtIterablePrivate::retrieveElement(meta.keyMetaType(), [&](void *dataPtr) {
0063             meta.keyAtConstIterator(constIterator(), dataPtr);
0064         });
0065     }
0066 
0067     mapped_type value() const { return operator*(); }
0068 
0069     mapped_type operator*() const;
0070     pointer operator->() const { return pointer(*this); }
0071 };
0072 
0073 } // namespace QtMetaContainerPrivate
0074 
0075 namespace QtPrivate {
0076 
0077 template<typename Indirect>
0078 QVariant associativeIteratorToVariant(const Indirect &referred)
0079 {
0080     const auto metaAssociation = referred.metaContainer();
0081     const QMetaType metaType(metaAssociation.mappedMetaType());
0082     if (metaType.isValid(QT6_CALL_NEW_OVERLOAD)) {
0083         return QtIterablePrivate::retrieveElement(metaType, [&](void *dataPtr) {
0084             metaAssociation.mappedAtConstIterator(referred.constIterator(), dataPtr);
0085         });
0086     }
0087 
0088     return QtIterablePrivate::retrieveElement(metaType, [&](void *dataPtr) {
0089         metaAssociation.keyAtConstIterator(referred.constIterator(), dataPtr);
0090     });
0091 }
0092 
0093 } // namespace QtPrivate
0094 
0095 template<>
0096 inline QVariant::Reference<QtMetaContainerPrivate::AssociativeIterator>::operator QVariant() const
0097 {
0098     return QtPrivate::associativeIteratorToVariant(m_referred);
0099 }
0100 
0101 template<>
0102 inline QVariant::Reference<QtMetaContainerPrivate::AssociativeIterator> &
0103 QVariant::Reference<QtMetaContainerPrivate::AssociativeIterator>::operator=(const QVariant &value)
0104 {
0105     const auto metaAssociation = m_referred.metaContainer();
0106     const QMetaType metaType(metaAssociation.mappedMetaType());
0107     if (!metaType.isValid(QT6_CALL_NEW_OVERLOAD))
0108         return *this;
0109 
0110     QtPrivate::QVariantTypeCoercer coercer;
0111     metaAssociation.setMappedAtIterator(
0112             m_referred.constIterator(), coercer.coerce(value, metaType));
0113     return *this;
0114 }
0115 
0116 template<>
0117 inline QVariant::ConstReference<QtMetaContainerPrivate::AssociativeConstIterator>::operator QVariant() const
0118 {
0119     return QtPrivate::associativeIteratorToVariant(m_referred);
0120 }
0121 
0122 namespace QtMetaContainerPrivate {
0123 inline AssociativeConstIterator::mapped_type AssociativeConstIterator::operator*() const
0124 {
0125     return reference(*this);
0126 }
0127 
0128 class Association : public QIterable<QMetaAssociation>
0129 {
0130 public:
0131     using Iterator
0132             = QTaggedIterator<AssociativeIterator, void>;
0133     using RandomAccessIterator
0134             = QTaggedIterator<AssociativeIterator, std::random_access_iterator_tag>;
0135     using BidirectionalIterator
0136             = QTaggedIterator<AssociativeIterator, std::bidirectional_iterator_tag>;
0137     using ForwardIterator
0138             = QTaggedIterator<AssociativeIterator, std::forward_iterator_tag>;
0139     using InputIterator
0140             = QTaggedIterator<AssociativeIterator, std::input_iterator_tag>;
0141 
0142     using ConstIterator
0143             = QTaggedIterator<AssociativeConstIterator, void>;
0144     using RandomAccessConstIterator
0145             = QTaggedIterator<AssociativeConstIterator, std::random_access_iterator_tag>;
0146     using BidirectionalConstIterator
0147             = QTaggedIterator<AssociativeConstIterator, std::bidirectional_iterator_tag>;
0148     using ForwardConstIterator
0149             = QTaggedIterator<AssociativeConstIterator, std::forward_iterator_tag>;
0150     using InputConstIterator
0151             = QTaggedIterator<AssociativeConstIterator, std::input_iterator_tag>;
0152 
0153     using iterator = Iterator;
0154     using const_iterator = ConstIterator;
0155 
0156     template<class T>
0157     Association(const T *p) : QIterable(QMetaAssociation::fromContainer<T>(), p) {}
0158 
0159     template<class T>
0160     Association(T *p) : QIterable(QMetaAssociation::fromContainer<T>(), p) {}
0161 
0162     Association() : QIterable(QMetaAssociation(), nullptr) {}
0163 
0164     template<typename Pointer>
0165     Association(const QMetaAssociation &metaAssociation, Pointer iterable)
0166         : QIterable(metaAssociation, iterable)
0167     {
0168     }
0169 
0170     Association(const QMetaAssociation &metaAssociation, QMetaType metaType, void *iterable)
0171         : QIterable(metaAssociation, metaType.alignOf(), iterable)
0172     {
0173     }
0174 
0175     Association(const QMetaAssociation &metaAssociation, QMetaType metaType, const void *iterable)
0176         : QIterable(metaAssociation, metaType.alignOf(), iterable)
0177     {
0178     }
0179 
0180     Association(QIterable<QMetaAssociation> &&other)
0181         : QIterable(std::move(other))
0182     {}
0183 
0184     Association &operator=(QIterable<QMetaAssociation> &&other)
0185     {
0186         QIterable::operator=(std::move(other));
0187         return *this;
0188     }
0189 
0190     ConstIterator begin() const { return constBegin(); }
0191     ConstIterator end() const { return constEnd(); }
0192 
0193     ConstIterator constBegin() const { return ConstIterator(QIterable::constBegin()); }
0194     ConstIterator constEnd() const { return ConstIterator(QIterable::constEnd()); }
0195 
0196     Iterator mutableBegin() { return Iterator(QIterable::mutableBegin()); }
0197     Iterator mutableEnd() { return Iterator(QIterable::mutableEnd()); }
0198 
0199     ConstIterator find(const QVariant &key) const
0200     {
0201         const QMetaAssociation meta = metaContainer();
0202         QtPrivate::QVariantTypeCoercer coercer;
0203         if (const void *keyData = coercer.convert(key, meta.keyMetaType())) {
0204             return ConstIterator(QConstIterator<QMetaAssociation>(
0205                     this, meta.createConstIteratorAtKey(constIterable(), keyData)));
0206         }
0207         return constEnd();
0208     }
0209 
0210     ConstIterator constFind(const QVariant &key) const { return find(key); }
0211 
0212     Iterator mutableFind(const QVariant &key)
0213     {
0214         const QMetaAssociation meta = metaContainer();
0215         QtPrivate::QVariantTypeCoercer coercer;
0216         if (const void *keyData = coercer.convert(key, meta.keyMetaType()))
0217             return Iterator(QIterator(this, meta.createIteratorAtKey(mutableIterable(), keyData)));
0218         return mutableEnd();
0219     }
0220 
0221     bool containsKey(const QVariant &key) const
0222     {
0223         const QMetaAssociation meta = metaContainer();
0224         QtPrivate::QVariantTypeCoercer keyCoercer;
0225         if (const void *keyData = keyCoercer.convert(key, meta.keyMetaType()))
0226             return meta.containsKey(constIterable(), keyData);
0227         return false;
0228     }
0229 
0230     void insertKey(const QVariant &key)
0231     {
0232         const QMetaAssociation meta = metaContainer();
0233         QtPrivate::QVariantTypeCoercer keyCoercer;
0234         meta.insertKey(mutableIterable(), keyCoercer.coerce(key, meta.keyMetaType()));
0235     }
0236 
0237     void removeKey(const QVariant &key)
0238     {
0239         const QMetaAssociation meta = metaContainer();
0240         QtPrivate::QVariantTypeCoercer keyCoercer;
0241         meta.removeKey(mutableIterable(), keyCoercer.coerce(key, meta.keyMetaType()));
0242     }
0243 
0244     QVariant value(const QVariant &key) const
0245     {
0246         const QMetaAssociation meta = metaContainer();
0247         return QtIterablePrivate::retrieveElement(meta.mappedMetaType(), [&](void *dataPtr) {
0248             QtPrivate::QVariantTypeCoercer coercer;
0249             meta.mappedAtKey(constIterable(), coercer.coerce(key, meta.keyMetaType()), dataPtr);
0250         });
0251     }
0252 
0253     void setValue(const QVariant &key, const QVariant &mapped)
0254     {
0255         const QMetaAssociation meta = metaContainer();
0256         QtPrivate::QVariantTypeCoercer keyCoercer;
0257         QtPrivate::QVariantTypeCoercer mappedCoercer;
0258         meta.setMappedAtKey(mutableIterable(), keyCoercer.coerce(key, meta.keyMetaType()),
0259                             mappedCoercer.coerce(mapped, meta.mappedMetaType()));
0260     }
0261 };
0262 
0263 } // namespace QtMetaContainerPrivate
0264 
0265 QT_END_NAMESPACE
0266 
0267 #endif // QMETAASSOCIATION_H