File indexing completed on 2026-08-02 09:27:16
0001
0002
0003
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 }
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 }
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 }
0264
0265 QT_END_NAMESPACE
0266
0267 #endif