File indexing completed on 2025-01-18 10:07:16
0001
0002
0003
0004 #ifndef QASSOCIATIVEITERABLE_H
0005 #define QASSOCIATIVEITERABLE_H
0006
0007 #include <QtCore/qiterable.h>
0008 #include <QtCore/qvariant.h>
0009
0010 QT_BEGIN_NAMESPACE
0011
0012 class Q_CORE_EXPORT QAssociativeIterator : public QIterator<QMetaAssociation>
0013 {
0014 public:
0015 using key_type = QVariant;
0016 using mapped_type = QVariant;
0017 using reference = QVariantRef<QAssociativeIterator>;
0018 using pointer = QVariantPointer<QAssociativeIterator>;
0019
0020 QAssociativeIterator(QIterator &&it)
0021 : QIterator(std::move(it))
0022 {}
0023
0024 QVariant key() const;
0025 QVariantRef<QAssociativeIterator> value() const;
0026
0027 QVariantRef<QAssociativeIterator> operator*() const;
0028 QVariantPointer<QAssociativeIterator> operator->() const;
0029 };
0030
0031 class Q_CORE_EXPORT QAssociativeConstIterator : public QConstIterator<QMetaAssociation>
0032 {
0033 public:
0034 using key_type = QVariant;
0035 using mapped_type = QVariant;
0036 using reference = const QVariant &;
0037 using pointer = QVariantConstPointer;
0038
0039 QAssociativeConstIterator(QConstIterator &&it)
0040 : QConstIterator(std::move(it))
0041 {}
0042
0043 QVariant key() const;
0044 QVariant value() const;
0045
0046 QVariant operator*() const;
0047 QVariantConstPointer operator->() const;
0048 };
0049
0050 class Q_CORE_EXPORT QAssociativeIterable : public QIterable<QMetaAssociation>
0051 {
0052 public:
0053 using iterator = QTaggedIterator<QAssociativeIterator, void>;
0054 using const_iterator = QTaggedIterator<QAssociativeConstIterator, void>;
0055
0056 using RandomAccessIterator = QTaggedIterator<iterator, std::random_access_iterator_tag>;
0057 using BidirectionalIterator = QTaggedIterator<iterator, std::bidirectional_iterator_tag>;
0058 using ForwardIterator = QTaggedIterator<iterator, std::forward_iterator_tag>;
0059 using InputIterator = QTaggedIterator<iterator, std::input_iterator_tag>;
0060
0061 using RandomAccessConstIterator = QTaggedIterator<const_iterator, std::random_access_iterator_tag>;
0062 using BidirectionalConstIterator = QTaggedIterator<const_iterator, std::bidirectional_iterator_tag>;
0063 using ForwardConstIterator = QTaggedIterator<const_iterator, std::forward_iterator_tag>;
0064 using InputConstIterator = QTaggedIterator<const_iterator, std::input_iterator_tag>;
0065
0066 template<class T>
0067 QAssociativeIterable(const T *p)
0068 : QIterable(QMetaAssociation::fromContainer<T>(), p)
0069 {
0070 }
0071
0072 template<class T>
0073 QAssociativeIterable(T *p)
0074 : QIterable(QMetaAssociation::fromContainer<T>(), p)
0075 {
0076 }
0077
0078 QAssociativeIterable()
0079 : QIterable(QMetaAssociation(), nullptr)
0080 {
0081 }
0082
0083 template<typename Pointer>
0084 QAssociativeIterable(const QMetaAssociation &metaAssociation, Pointer iterable)
0085 : QIterable(metaAssociation, iterable)
0086 {
0087 }
0088
0089
0090 QAssociativeIterable(const QMetaAssociation &metaAssociation, const QMetaType &metaType,
0091 void *iterable)
0092 : QIterable(metaAssociation, metaType.alignOf(), iterable)
0093 {
0094 }
0095
0096
0097 QAssociativeIterable(const QMetaAssociation &metaAssociation, const QMetaType &metaType,
0098 const void *iterable)
0099 : QIterable(metaAssociation, metaType.alignOf(), iterable)
0100 {
0101 }
0102
0103 QAssociativeIterable(QIterable<QMetaAssociation> &&other) : QIterable(std::move(other)) {}
0104
0105 QAssociativeIterable &operator=(QIterable<QMetaAssociation> &&other)
0106 {
0107 QIterable::operator=(std::move(other));
0108 return *this;
0109 }
0110
0111 const_iterator begin() const { return constBegin(); }
0112 const_iterator end() const { return constEnd(); }
0113
0114 const_iterator constBegin() const { return const_iterator(QIterable::constBegin()); }
0115 const_iterator constEnd() const { return const_iterator(QIterable::constEnd()); }
0116
0117 iterator mutableBegin() { return iterator(QIterable::mutableBegin()); }
0118 iterator mutableEnd() { return iterator(QIterable::mutableEnd()); }
0119
0120 const_iterator find(const QVariant &key) const;
0121 const_iterator constFind(const QVariant &key) const { return find(key); }
0122 iterator mutableFind(const QVariant &key);
0123
0124 bool containsKey(const QVariant &key);
0125 void insertKey(const QVariant &key);
0126 void removeKey(const QVariant &key);
0127
0128 QVariant value(const QVariant &key) const;
0129 void setValue(const QVariant &key, const QVariant &mapped);
0130 };
0131
0132 template<>
0133 inline QVariantRef<QAssociativeIterator>::operator QVariant() const
0134 {
0135 if (m_pointer == nullptr)
0136 return QVariant();
0137
0138 const auto metaAssociation = m_pointer->metaContainer();
0139 const QMetaType metaType(metaAssociation.mappedMetaType());
0140 if (!metaType.isValid())
0141 return m_pointer->key();
0142
0143 QVariant v(metaType);
0144 metaAssociation.mappedAtIterator(m_pointer->constIterator(),
0145 metaType == QMetaType::fromType<QVariant>() ? &v : v.data());
0146 return v;
0147 }
0148
0149 template<>
0150 inline QVariantRef<QAssociativeIterator> &QVariantRef<QAssociativeIterator>::operator=(
0151 const QVariant &value)
0152 {
0153 if (m_pointer == nullptr)
0154 return *this;
0155
0156 const auto metaAssociation = m_pointer->metaContainer();
0157 const QMetaType metaType(metaAssociation.mappedMetaType());
0158 if (metaType.isValid()) {
0159 QtPrivate::QVariantTypeCoercer coercer;
0160 metaAssociation.setMappedAtIterator(m_pointer->constIterator(),
0161 coercer.coerce(value, metaType));
0162 }
0163
0164 return *this;
0165 }
0166
0167 Q_DECLARE_TYPEINFO(QAssociativeIterable, Q_RELOCATABLE_TYPE);
0168 Q_DECLARE_TYPEINFO(QAssociativeIterable::iterator, Q_RELOCATABLE_TYPE);
0169 Q_DECLARE_TYPEINFO(QAssociativeIterable::const_iterator, Q_RELOCATABLE_TYPE);
0170
0171 QT_END_NAMESPACE
0172
0173 #endif