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
qmetacontainer.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// Qt-Security score:significant reason:default
4
6#include "qmetatype.h"
7
9
10/*!
11 \class QMetaContainer
12 \inmodule QtCore
13 \since 6.0
14 \brief The QMetaContainer class provides common functionality for sequential
15 and associative containers.
16
17 QMetaContainer is part of Qt's meta-type system that allows type-erased access
18 to container-like types at runtime.
19
20 It serves as a common base for accessing properties of containers in a generic
21 way, such as size, iteration, and clearing operations, without knowing the actual
22 container type.
23
24 Derived classes, such as QMetaSequence, provide specialized interfaces for
25 sequential containers.
26
27 \ingroup objectmodel
28
29 \compares equality
30*/
31
32/*!
33 Returns \c true if the underlying container provides at least an input
34 iterator as defined by std::input_iterator_tag, otherwise returns
35 \c false. Forward, Bi-directional, and random access iterators are
36 specializations of input iterators. This method will also return
37 \c true if the container provides one of those.
38
39 QMetaContainer assumes that const and non-const iterators for the same
40 container have the same iterator traits.
41 */
42bool QMetaContainer::hasInputIterator() const
43{
44 if (!d_ptr)
45 return false;
46 return d_ptr->iteratorCapabilities.testAnyFlag(QtMetaContainerPrivate::InputCapability);
47}
48
49/*!
50 Returns \c true if the underlying container provides at least a forward
51 iterator as defined by std::forward_iterator_tag, otherwise returns
52 \c false. Bi-directional iterators and random access iterators are
53 specializations of forward iterators. This method will also return
54 \c true if the container provides one of those.
55
56 QMetaContainer assumes that const and non-const iterators for the same
57 container have the same iterator traits.
58 */
59bool QMetaContainer::hasForwardIterator() const
60{
61 if (!d_ptr)
62 return false;
63 return d_ptr->iteratorCapabilities.testAnyFlag(QtMetaContainerPrivate::ForwardCapability);
64}
65
66/*!
67 Returns \c true if the underlying container provides a bi-directional
68 iterator or a random access iterator as defined by
69 std::bidirectional_iterator_tag and std::random_access_iterator_tag,
70 respectively. Otherwise returns \c false.
71
72 QMetaContainer assumes that const and non-const iterators for the same
73 container have the same iterator traits.
74 */
75bool QMetaContainer::hasBidirectionalIterator() const
76{
77 if (!d_ptr)
78 return false;
79 return d_ptr->iteratorCapabilities.testAnyFlag(QtMetaContainerPrivate::BiDirectionalCapability);
80}
81
82/*!
83 Returns \c true if the underlying container provides a random access
84 iterator as defined by std::random_access_iterator_tag, otherwise returns
85 \c false.
86
87 QMetaContainer assumes that const and non-const iterators for the same
88 container have the same iterator traits.
89 */
90bool QMetaContainer::hasRandomAccessIterator() const
91{
92 if (!d_ptr)
93 return false;
94 return d_ptr->iteratorCapabilities.testAnyFlag(QtMetaContainerPrivate::RandomAccessCapability);
95}
96
97/*!
98 Returns \c true if the container can be queried for its size, \c false
99 otherwise.
100
101 \sa size()
102 */
103bool QMetaContainer::hasSize() const
104{
105 return d_ptr && d_ptr->sizeFn;
106}
107
108/*!
109 Returns the number of values in the given \a container if it can be
110 queried for its size. Otherwise returns \c -1.
111
112 \sa hasSize()
113 */
114qsizetype QMetaContainer::size(const void *container) const
115{
116 return hasSize() ? d_ptr->sizeFn(container) : -1;
117}
118
119/*!
120 Returns \c true if the container can be cleared, \c false otherwise.
121
122 \sa clear()
123 */
124bool QMetaContainer::canClear() const
125{
126 return d_ptr && d_ptr->clearFn;
127}
128
129/*!
130 Clears the given \a container if it can be cleared.
131
132 \sa canClear()
133 */
134void QMetaContainer::clear(void *container) const
135{
136 if (canClear())
137 d_ptr->clearFn(container);
138}
139
140/*!
141 Returns \c true if the underlying container offers a non-const iterator,
142 \c false otherwise.
143
144 \sa begin(), end(), destroyIterator(), compareIterator(), diffIterator(),
145 advanceIterator(), copyIterator()
146 */
147bool QMetaContainer::hasIterator() const
148{
149 if (!d_ptr || !d_ptr->createIteratorFn)
150 return false;
151 Q_ASSERT(d_ptr->destroyIteratorFn);
152 Q_ASSERT(d_ptr->compareIteratorFn);
153 Q_ASSERT(d_ptr->copyIteratorFn);
154 Q_ASSERT(d_ptr->advanceIteratorFn);
155 Q_ASSERT(d_ptr->diffIteratorFn);
156 return true;
157}
158
159/*!
160 Creates and returns a non-const iterator pointing to the beginning of
161 \a container. The iterator is allocated on the heap using new. It has to be
162 destroyed using \l destroyIterator eventually, to reclaim the memory.
163
164 Returns \c nullptr if the container doesn't offer any non-const iterators.
165
166 \sa end(), constBegin(), constEnd(), destroyIterator()
167 */
168void *QMetaContainer::begin(void *container) const
169{
170 return hasIterator()
171 ? d_ptr->createIteratorFn(
172 container, QtMetaContainerPrivate::QMetaContainerInterface::AtBegin)
173 : nullptr;
174}
175
176/*!
177 Creates and returns a non-const iterator pointing to the end of
178 \a container. The iterator is allocated on the heap using new. It has to be
179 destroyed using \l destroyIterator eventually, to reclaim the memory.
180
181 Returns \c nullptr if the container doesn't offer any non-const iterators.
182
183 \sa hasIterator(), begin(), constBegin(), constEnd(), destroyIterator()
184 */
185void *QMetaContainer::end(void *container) const
186{
187 return hasIterator()
188 ? d_ptr->createIteratorFn(
189 container, QtMetaContainerPrivate::QMetaContainerInterface::AtEnd)
190 : nullptr;
191}
192
193/*!
194 Destroys a non-const \a iterator previously created using \l begin() or
195 \l end().
196
197 \sa begin(), end(), destroyConstIterator()
198 */
199void QMetaContainer::destroyIterator(const void *iterator) const
200{
201 if (hasIterator())
202 d_ptr->destroyIteratorFn(iterator);
203}
204
205/*!
206 Returns \c true if the non-const iterators \a i and \a j point to the same
207 value in the container they are iterating over, otherwise returns \c
208 false.
209
210 \sa begin(), end()
211 */
212bool QMetaContainer::compareIterator(const void *i, const void *j) const
213{
214 return i == j || (hasIterator() && d_ptr->compareIteratorFn(i, j));
215}
216
217/*!
218 Copies the non-const iterator \a source into the non-const iterator
219 \a target. Afterwards compareIterator(target, source) returns \c true.
220
221 \sa begin(), end()
222 */
223void QMetaContainer::copyIterator(void *target, const void *source) const
224{
225 if (hasIterator())
226 d_ptr->copyIteratorFn(target, source);
227}
228
229/*!
230 Advances the non-const \a iterator by \a step steps. If \a step is negative
231 the \a iterator is moved backwards, towards the beginning of the container.
232 The behavior is unspecified for negative values of \a step if
233 \l hasBidirectionalIterator() returns false.
234
235 \sa begin(), end()
236 */
237void QMetaContainer::advanceIterator(void *iterator, qsizetype step) const
238{
239 if (hasIterator())
240 d_ptr->advanceIteratorFn(iterator, step);
241}
242
243/*!
244 Returns the distance between the non-const iterators \a i and \a j, the
245 equivalent of \a i \c - \a j. If \a j is closer to the end of the container
246 than \a i, the returned value is negative. The behavior is unspecified in
247 this case if \l hasBidirectionalIterator() returns false.
248
249 \sa begin(), end()
250 */
251qsizetype QMetaContainer::diffIterator(const void *i, const void *j) const
252{
253 return (i != j && hasIterator()) ? d_ptr->diffIteratorFn(i, j) : 0;
254}
255
256/*!
257 Returns \c true if the underlying container offers a const iterator,
258 \c false otherwise.
259
260 \sa constBegin(), constEnd(), destroyConstIterator(),
261 compareConstIterator(), diffConstIterator(), advanceConstIterator(),
262 copyConstIterator()
263 */
264bool QMetaContainer::hasConstIterator() const
265{
266 if (!d_ptr || !d_ptr->createConstIteratorFn)
267 return false;
268 Q_ASSERT(d_ptr->destroyConstIteratorFn);
269 Q_ASSERT(d_ptr->compareConstIteratorFn);
270 Q_ASSERT(d_ptr->copyConstIteratorFn);
271 Q_ASSERT(d_ptr->advanceConstIteratorFn);
272 Q_ASSERT(d_ptr->diffConstIteratorFn);
273 return true;
274}
275
276/*!
277 Creates and returns a const iterator pointing to the beginning of
278 \a container. The iterator is allocated on the heap using new. It has to be
279 destroyed using \l destroyConstIterator eventually, to reclaim the memory.
280
281 Returns \c nullptr if the container doesn't offer any const iterators.
282
283 \sa constEnd(), begin(), end(), destroyConstIterator()
284 */
285void *QMetaContainer::constBegin(const void *container) const
286{
287 return hasConstIterator()
288 ? d_ptr->createConstIteratorFn(
289 container, QtMetaContainerPrivate::QMetaContainerInterface::AtBegin)
290 : nullptr;
291}
292
293/*!
294 Creates and returns a const iterator pointing to the end of
295 \a container. The iterator is allocated on the heap using new. It has to be
296 destroyed using \l destroyConstIterator eventually, to reclaim the memory.
297
298 Returns \c nullptr if the container doesn't offer any const iterators.
299
300 \sa constBegin(), begin(), end(), destroyConstIterator()
301 */
302void *QMetaContainer::constEnd(const void *container) const
303{
304 return hasConstIterator()
305 ? d_ptr->createConstIteratorFn(
306 container, QtMetaContainerPrivate::QMetaContainerInterface::AtEnd)
307 : nullptr;
308}
309
310/*!
311 Destroys a const \a iterator previously created using \l constBegin() or
312 \l constEnd().
313
314 \sa constBegin(), constEnd(), destroyIterator()
315 */
316void QMetaContainer::destroyConstIterator(const void *iterator) const
317{
318 if (hasConstIterator())
319 d_ptr->destroyConstIteratorFn(iterator);
320}
321
322/*!
323 Returns \c true if the const iterators \a i and \a j point to the same
324 value in the container they are iterating over, otherwise returns \c
325 false.
326
327 \sa constBegin(), constEnd()
328 */
329bool QMetaContainer::compareConstIterator(const void *i, const void *j) const
330{
331 return i == j || (hasConstIterator() && d_ptr->compareConstIteratorFn(i, j));
332}
333
334/*!
335 Copies the const iterator \a source into the const iterator
336 \a target. Afterwards compareConstIterator(target, source) returns \c true.
337
338 \sa constBegin(), constEnd()
339 */
340void QMetaContainer::copyConstIterator(void *target, const void *source) const
341{
342 if (hasConstIterator())
343 d_ptr->copyConstIteratorFn(target, source);
344}
345
346/*!
347 Advances the const \a iterator by \a step steps. If \a step is negative
348 the \a iterator is moved backwards, towards the beginning of the container.
349 The behavior is unspecified for negative values of \a step if
350 \l hasBidirectionalIterator() returns false.
351
352 \sa constBegin(), constEnd()
353 */
354void QMetaContainer::advanceConstIterator(void *iterator, qsizetype step) const
355{
356 if (hasConstIterator())
357 d_ptr->advanceConstIteratorFn(iterator, step);
358}
359
360/*!
361 Returns the distance between the const iterators \a i and \a j, the
362 equivalent of \a i \c - \a j. If \a j is closer to the end of the container
363 than \a i, the returned value is negative. The behavior is unspecified in
364 this case if \l hasBidirectionalIterator() returns false.
365
366 \sa constBegin(), constEnd()
367 */
368qsizetype QMetaContainer::diffConstIterator(const void *i, const void *j) const
369{
370 return (i != j && hasConstIterator()) ? d_ptr->diffConstIteratorFn(i, j) : 0;
371}
372
373QT_END_NAMESPACE
Combined button and popup list for selecting options.