Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsequentialiterable.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtCore/qiterable_impl.h>
5#include <QtCore/qsequentialiterable.h>
6#include <QtCore/qvariant.h>
7
8QT_BEGIN_NAMESPACE
9
10/*!
11 \class QSequentialIterable
12 \since 5.2
13 \inmodule QtCore
14 \brief The QSequentialIterable class is an iterable interface for a container in a QVariant.
15
16 This class allows several methods of accessing the values of a container held within
17 a QVariant. An instance of QSequentialIterable can be extracted from a QVariant if it can
18 be converted to a QVariantList.
19
20 \snippet code/src_corelib_kernel_qvariant.cpp 9
21
22 The container itself is not copied before iterating over it.
23
24 \sa QVariant
25*/
26
27/*!
28 \typedef QSequentialIterable::RandomAccessIterator
29 Exposes an iterator using std::random_access_iterator_tag.
30*/
31
32/*!
33 \typedef QSequentialIterable::BidirectionalIterator
34 Exposes an iterator using std::bidirectional_iterator_tag.
35*/
36
37/*!
38 \typedef QSequentialIterable::ForwardIterator
39 Exposes an iterator using std::forward_iterator_tag.
40*/
41
42/*!
43 \typedef QSequentialIterable::InputIterator
44 Exposes an iterator using std::input_iterator_tag.
45*/
46
47/*!
48 \typedef QSequentialIterable::RandomAccessConstIterator
49 Exposes a const_iterator using std::random_access_iterator_tag.
50*/
51
52/*!
53 \typedef QSequentialIterable::BidirectionalConstIterator
54 Exposes a const_iterator using std::bidirectional_iterator_tag.
55*/
56
57/*!
58 \typedef QSequentialIterable::ForwardConstIterator
59 Exposes a const_iterator using std::forward_iterator_tag.
60*/
61
62/*!
63 \typedef QSequentialIterable::InputConstIterator
64 Exposes a const_iterator using std::input_iterator_tag.
65*/
66
67/*!
68 Adds \a value to the container, at \a position, if possible.
69 */
70void QSequentialIterable::addValue(const QVariant &value, Position position)
71{
72 QtPrivate::QVariantTypeCoercer coercer;
73 const void *valuePtr = coercer.coerce(value, metaContainer().valueMetaType());
74
75 switch (position) {
76 case AtBegin:
77 if (metaContainer().canAddValueAtBegin())
78 metaContainer().addValueAtBegin(mutableIterable(), valuePtr);
79 break;
80 case AtEnd:
81 if (metaContainer().canAddValueAtEnd())
82 metaContainer().addValueAtEnd(mutableIterable(), valuePtr);
83 break;
84 case Unspecified:
85 if (metaContainer().canAddValue())
86 metaContainer().addValue(mutableIterable(), valuePtr);
87 break;
88 }
89}
90
91/*!
92 Removes a value from the container, at \a position, if possible.
93 */
94void QSequentialIterable::removeValue(Position position)
95{
96 switch (position) {
97 case AtBegin:
98 if (metaContainer().canRemoveValueAtBegin())
99 metaContainer().removeValueAtBegin(mutableIterable());
100 break;
101 case AtEnd:
102 if (metaContainer().canRemoveValueAtEnd())
103 metaContainer().removeValueAtEnd(mutableIterable());
104 break;
105 case Unspecified:
106 if (metaContainer().canRemoveValue())
107 metaContainer().removeValue(mutableIterable());
108 break;
109 }
110}
111
112QMetaType QSequentialIterable::valueMetaType() const
113{
114 return QMetaType(metaContainer().valueMetaType());
115}
116
117/*!
118 Returns the value at position \a idx in the container.
119*/
120QVariant QSequentialIterable::at(qsizetype idx) const
121{
122 QVariant v(valueMetaType());
123 void *dataPtr;
124 if (valueMetaType() == QMetaType::fromType<QVariant>())
125 dataPtr = &v;
126 else
127 dataPtr = v.data();
128
129 const QMetaSequence meta = metaContainer();
130 if (meta.canGetValueAtIndex()) {
131 meta.valueAtIndex(m_iterable.constPointer(), idx, dataPtr);
132 } else if (meta.canGetValueAtConstIterator()) {
133 void *iterator = meta.constBegin(m_iterable.constPointer());
134 meta.advanceConstIterator(iterator, idx);
135 meta.valueAtConstIterator(iterator, dataPtr);
136 meta.destroyConstIterator(iterator);
137 }
138
139 return v;
140}
141
142/*!
143 Sets the element at position \a idx in the container to \a value.
144*/
145void QSequentialIterable::set(qsizetype idx, const QVariant &value)
146{
147 QtPrivate::QVariantTypeCoercer coercer;
148 const void *dataPtr = coercer.coerce(value, metaContainer().valueMetaType());
149
150 const QMetaSequence meta = metaContainer();
151 if (meta.canSetValueAtIndex()) {
152 meta.setValueAtIndex(m_iterable.mutablePointer(), idx, dataPtr);
153 } else if (meta.canSetValueAtIterator()) {
154 void *iterator = meta.begin(m_iterable.mutablePointer());
155 meta.advanceIterator(iterator, idx);
156 meta.setValueAtIterator(iterator, dataPtr);
157 meta.destroyIterator(iterator);
158 }
159}
160
161/*!
162 \typealias QSequentialIterable::const_iterator
163 \brief The QSequentialIterable::const_iterator allows iteration over a container in a QVariant.
164
165 A QSequentialIterable::const_iterator can only be created by a QSequentialIterable instance,
166 and can be used in a way similar to other stl-style iterators.
167
168 \snippet code/src_corelib_kernel_qvariant.cpp 9
169*/
170
171/*!
172 \typealias QSequentialIterable::iterator
173 \since 6.0
174 \brief The QSequentialIterable::iterator allows iteration over a container in a QVariant.
175
176 A QSequentialIterable::iterator can only be created by a QSequentialIterable instance,
177 and can be used in a way similar to other stl-style iterators.
178*/
179
180/*!
181 Returns the current item, converted to a QVariantRef.
182*/
183QVariantRef<QSequentialIterator> QSequentialIterator::operator*() const
184{
185 return QVariantRef<QSequentialIterator>(this);
186}
187
188/*!
189 Returns the current item, converted to a QVariantPointer.
190*/
191QVariantPointer<QSequentialIterator> QSequentialIterator::operator->() const
192{
193 return QVariantPointer<QSequentialIterator>(this);
194}
195
196/*!
197 Returns the current item, converted to a QVariant.
198*/
199QVariant QSequentialConstIterator::operator*() const
200{
201 return QIterablePrivate::retrieveElement(metaContainer().valueMetaType(), [this](void *dataPtr) {
202 metaContainer().valueAtConstIterator(constIterator(), dataPtr);
203 });
204}
205
206/*!
207 Returns the current item, converted to a QVariantConstPointer.
208*/
209QVariantConstPointer QSequentialConstIterator::operator->() const
210{
211 return QVariantConstPointer(operator*());
212}
213
214QT_END_NAMESPACE