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 "qmetacontainer.h" |
5 | #include "qmetatype.h" |
6 | |
7 | QT_BEGIN_NAMESPACE |
8 | |
9 | /*! |
10 | \class QMetaSequence |
11 | \inmodule QtCore |
12 | \since 6.0 |
13 | \brief The QMetaSequence class allows type erased access to sequential containers. |
14 | |
15 | \ingroup objectmodel |
16 | |
17 | \compares equality |
18 | |
19 | The class provides a number of primitive container operations, using void* |
20 | as operands. This way, you can manipulate a generic container retrieved from |
21 | a Variant without knowing its type. |
22 | |
23 | The void* arguments to the various methods are typically created by using |
24 | a \l QVariant of the respective container or value type, and calling |
25 | its \l QVariant::data() or \l QVariant::constData() methods. However, you |
26 | can also pass plain pointers to objects of the container or value type. |
27 | |
28 | Iterator invalidation follows the rules given by the underlying containers |
29 | and is not expressed in the API. Therefore, for a truly generic container, |
30 | any iterators should be considered invalid after any write operation. |
31 | */ |
32 | |
33 | /*! |
34 | \fn template<typename C> QMetaSequence QMetaSequence::fromContainer() |
35 | \since 6.0 |
36 | |
37 | Returns the QMetaSequence corresponding to the type given as template parameter. |
38 | */ |
39 | |
40 | /*! |
41 | \class QMetaContainer |
42 | \inmodule QtCore |
43 | \since 6.0 |
44 | \brief The QMetaContainer class provides common functionality for sequential |
45 | and associative containers. |
46 | |
47 | \ingroup objectmodel |
48 | |
49 | \compares equality |
50 | */ |
51 | |
52 | /*! |
53 | Returns \c true if the underlying container provides at least an input |
54 | iterator as defined by std::input_iterator_tag, otherwise returns |
55 | \c false. Forward, Bi-directional, and random access iterators are |
56 | specializations of input iterators. This method will also return |
57 | \c true if the container provides one of those. |
58 | |
59 | QMetaSequence assumes that const and non-const iterators for the same |
60 | container have the same iterator traits. |
61 | */ |
62 | bool QMetaContainer::hasInputIterator() const |
63 | { |
64 | if (!d_ptr) |
65 | return false; |
66 | return d_ptr->iteratorCapabilities.testAnyFlag(flag: QtMetaContainerPrivate::InputCapability); |
67 | } |
68 | |
69 | /*! |
70 | Returns \c true if the underlying container provides at least a forward |
71 | iterator as defined by std::forward_iterator_tag, otherwise returns |
72 | \c false. Bi-directional iterators and random access iterators are |
73 | specializations of forward iterators. This method will also return |
74 | \c true if the container provides one of those. |
75 | |
76 | QMetaSequence assumes that const and non-const iterators for the same |
77 | container have the same iterator traits. |
78 | */ |
79 | bool QMetaContainer::hasForwardIterator() const |
80 | { |
81 | if (!d_ptr) |
82 | return false; |
83 | return d_ptr->iteratorCapabilities.testAnyFlag(flag: QtMetaContainerPrivate::ForwardCapability); |
84 | } |
85 | |
86 | /*! |
87 | Returns \c true if the underlying container provides a bi-directional |
88 | iterator or a random access iterator as defined by |
89 | std::bidirectional_iterator_tag and std::random_access_iterator_tag, |
90 | respectively. Otherwise returns \c false. |
91 | |
92 | QMetaSequence assumes that const and non-const iterators for the same |
93 | container have the same iterator traits. |
94 | */ |
95 | bool QMetaContainer::hasBidirectionalIterator() const |
96 | { |
97 | if (!d_ptr) |
98 | return false; |
99 | return d_ptr->iteratorCapabilities.testAnyFlag(flag: QtMetaContainerPrivate::BiDirectionalCapability); |
100 | } |
101 | |
102 | /*! |
103 | Returns \c true if the underlying container provides a random access |
104 | iterator as defined by std::random_access_iterator_tag, otherwise returns |
105 | \c false. |
106 | |
107 | QMetaSequence assumes that const and non-const iterators for the same |
108 | container have the same iterator traits. |
109 | */ |
110 | bool QMetaContainer::hasRandomAccessIterator() const |
111 | { |
112 | if (!d_ptr) |
113 | return false; |
114 | return d_ptr->iteratorCapabilities.testAnyFlag(flag: QtMetaContainerPrivate::RandomAccessCapability); |
115 | } |
116 | |
117 | /*! |
118 | Returns the meta type for values stored in the container. |
119 | */ |
120 | QMetaType QMetaSequence::valueMetaType() const |
121 | { |
122 | if (auto iface = d()) |
123 | return QMetaType(iface->valueMetaType); |
124 | return QMetaType(); |
125 | } |
126 | |
127 | /*! |
128 | Returns \c true if the underlying container is sortable, otherwise returns |
129 | \c false. A container is considered sortable if values added to it are |
130 | placed in a defined location. Inserting into or adding to a sortable |
131 | container will always succeed. Inserting into or adding to an unsortable |
132 | container may not succeed, for example if the container is a QSet that |
133 | already contains the value being inserted. |
134 | |
135 | \sa addValue(), insertValueAtIterator(), canAddValueAtBegin(), |
136 | canAddValueAtEnd(), canRemoveValueAtBegin(), canRemoveValueAtEnd() |
137 | */ |
138 | bool QMetaSequence::isSortable() const |
139 | { |
140 | if (auto iface = d()) { |
141 | return (iface->addRemoveCapabilities |
142 | & (QtMetaContainerPrivate::CanAddAtBegin | QtMetaContainerPrivate::CanAddAtEnd)) |
143 | && (iface->addRemoveCapabilities |
144 | & (QtMetaContainerPrivate::CanRemoveAtBegin |
145 | | QtMetaContainerPrivate::CanRemoveAtEnd)); |
146 | } |
147 | return false; |
148 | } |
149 | |
150 | /*! |
151 | Returns \c true if values added using \l addValue() can be placed at the |
152 | beginning of the container, otherwise returns \c false. |
153 | |
154 | \sa addValueAtBegin(), canAddValueAtEnd() |
155 | */ |
156 | bool QMetaSequence::canAddValueAtBegin() const |
157 | { |
158 | if (auto iface = d()) { |
159 | return iface->addValueFn |
160 | && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanAddAtBegin; |
161 | } |
162 | return false; |
163 | } |
164 | |
165 | /*! |
166 | Adds \a value to the beginning of \a container if possible. If |
167 | \l canAddValueAtBegin() returns \c false, the \a value is not added. |
168 | |
169 | \sa canAddValueAtBegin(), isSortable(), removeValueAtBegin() |
170 | */ |
171 | void QMetaSequence::addValueAtBegin(void *container, const void *value) const |
172 | { |
173 | if (canAddValueAtBegin()) |
174 | d()->addValueFn(container, value, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin); |
175 | } |
176 | |
177 | /*! |
178 | Returns \c true if values can be removed from the beginning of the container |
179 | using \l removeValue() can be placed at the, otherwise returns \c false. |
180 | |
181 | \sa removeValueAtBegin(), canRemoveValueAtEnd() |
182 | */ |
183 | bool QMetaSequence::canRemoveValueAtBegin() const |
184 | { |
185 | if (auto iface = d()) { |
186 | return iface->removeValueFn |
187 | && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanRemoveAtBegin; |
188 | } |
189 | return false; |
190 | } |
191 | |
192 | /*! |
193 | Removes a value from the beginning of \a container if possible. If |
194 | \l canRemoveValueAtBegin() returns \c false, the value is not removed. |
195 | |
196 | \sa canRemoveValueAtBegin(), isSortable(), addValueAtBegin() |
197 | */ |
198 | void QMetaSequence::removeValueAtBegin(void *container) const |
199 | { |
200 | if (canRemoveValueAtBegin()) |
201 | d()->removeValueFn(container, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin); |
202 | } |
203 | |
204 | /*! |
205 | Returns \c true if values added using \l addValue() can be placed at the |
206 | end of the container, otherwise returns \c false. |
207 | |
208 | \sa addValueAtEnd(), canAddValueAtBegin() |
209 | */ |
210 | bool QMetaSequence::canAddValueAtEnd() const |
211 | { |
212 | if (auto iface = d()) { |
213 | return iface->addValueFn |
214 | && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanAddAtEnd; |
215 | } |
216 | return false; |
217 | } |
218 | |
219 | /*! |
220 | Adds \a value to the end of \a container if possible. If |
221 | \l canAddValueAtEnd() returns \c false, the \a value is not added. |
222 | |
223 | \sa canAddValueAtEnd(), isSortable(), removeValueAtEnd() |
224 | */ |
225 | void QMetaSequence::addValueAtEnd(void *container, const void *value) const |
226 | { |
227 | if (canAddValueAtEnd()) |
228 | d()->addValueFn(container, value, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd); |
229 | } |
230 | |
231 | /*! |
232 | Returns \c true if values can be removed from the end of the container |
233 | using \l removeValue() can be placed at the, otherwise returns \c false. |
234 | |
235 | \sa removeValueAtEnd(), canRemoveValueAtBegin() |
236 | */ |
237 | bool QMetaSequence::canRemoveValueAtEnd() const |
238 | { |
239 | if (auto iface = d()) { |
240 | return iface->removeValueFn |
241 | && iface->addRemoveCapabilities & QtMetaContainerPrivate::CanRemoveAtEnd; |
242 | } |
243 | return false; |
244 | } |
245 | |
246 | /*! |
247 | Removes a value from the end of \a container if possible. If |
248 | \l canRemoveValueAtEnd() returns \c false, the value is not removed. |
249 | |
250 | \sa canRemoveValueAtEnd(), isSortable(), addValueAtEnd() |
251 | */ |
252 | void QMetaSequence::removeValueAtEnd(void *container) const |
253 | { |
254 | if (canRemoveValueAtEnd()) |
255 | d()->removeValueFn(container, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd); |
256 | } |
257 | |
258 | /*! |
259 | Returns \c true if the container can be queried for its size, \c false |
260 | otherwise. |
261 | |
262 | \sa size() |
263 | */ |
264 | bool QMetaContainer::hasSize() const |
265 | { |
266 | return d_ptr && d_ptr->sizeFn; |
267 | } |
268 | |
269 | /*! |
270 | Returns the number of values in the given \a container if it can be |
271 | queried for its size. Otherwise returns \c -1. |
272 | |
273 | \sa hasSize() |
274 | */ |
275 | qsizetype QMetaContainer::size(const void *container) const |
276 | { |
277 | return hasSize() ? d_ptr->sizeFn(container) : -1; |
278 | } |
279 | |
280 | /*! |
281 | Returns \c true if the container can be cleared, \c false otherwise. |
282 | |
283 | \sa clear() |
284 | */ |
285 | bool QMetaContainer::canClear() const |
286 | { |
287 | return d_ptr && d_ptr->clearFn; |
288 | } |
289 | |
290 | /*! |
291 | Clears the given \a container if it can be cleared. |
292 | |
293 | \sa canClear() |
294 | */ |
295 | void QMetaContainer::clear(void *container) const |
296 | { |
297 | if (canClear()) |
298 | d_ptr->clearFn(container); |
299 | } |
300 | |
301 | /*! |
302 | Returns \c true if values can be retrieved from the container by index, |
303 | otherwise \c false. |
304 | |
305 | \sa valueAtIndex() |
306 | */ |
307 | bool QMetaSequence::canGetValueAtIndex() const |
308 | { |
309 | if (auto iface = d()) |
310 | return iface->valueAtIndexFn; |
311 | return false; |
312 | } |
313 | |
314 | /*! |
315 | Retrieves the value at \a index in the \a container and places it in the |
316 | memory location pointed to by \a result, if that is possible. |
317 | |
318 | \sa canGetValueAtIndex() |
319 | */ |
320 | void QMetaSequence::valueAtIndex(const void *container, qsizetype index, void *result) const |
321 | { |
322 | if (canGetValueAtIndex()) |
323 | d()->valueAtIndexFn(container, index, result); |
324 | } |
325 | |
326 | /*! |
327 | Returns \c true if an value can be written to the container by index, |
328 | otherwise \c false. |
329 | |
330 | \sa setValueAtIndex() |
331 | */ |
332 | bool QMetaSequence::canSetValueAtIndex() const |
333 | { |
334 | if (auto iface = d()) |
335 | return iface->setValueAtIndexFn; |
336 | return false; |
337 | } |
338 | |
339 | /*! |
340 | Overwrites the value at \a index in the \a container using the \a value |
341 | passed as parameter if that is possible. |
342 | |
343 | \sa canSetValueAtIndex() |
344 | */ |
345 | void QMetaSequence::setValueAtIndex(void *container, qsizetype index, const void *value) const |
346 | { |
347 | if (canSetValueAtIndex()) |
348 | d()->setValueAtIndexFn(container, index, value); |
349 | } |
350 | |
351 | /*! |
352 | Returns \c true if values can be added to the container, \c false |
353 | otherwise. |
354 | |
355 | \sa addValue(), isSortable() |
356 | */ |
357 | bool QMetaSequence::canAddValue() const |
358 | { |
359 | if (auto iface = d()) |
360 | return iface->addValueFn; |
361 | return false; |
362 | } |
363 | |
364 | /*! |
365 | Adds \a value to the \a container if possible. If \l canAddValue() |
366 | returns \c false, the \a value is not added. Else, if |
367 | \l canAddValueAtEnd() returns \c true, the \a value is added |
368 | to the end of the \a container. Else, if |
369 | \l canAddValueAtBegin() returns \c true, the \a value is added to |
370 | the beginning of the container. Else, the value is added in an unspecified |
371 | place or not at all. The latter is the case for adding values to an |
372 | unordered container, for example \l QSet. |
373 | |
374 | \sa canAddValue(), canAddValueAtBegin(), |
375 | canAddValueAtEnd(), isSortable(), removeValue() |
376 | */ |
377 | void QMetaSequence::addValue(void *container, const void *value) const |
378 | { |
379 | if (canAddValue()) { |
380 | d()->addValueFn(container, value, |
381 | QtMetaContainerPrivate::QMetaSequenceInterface::Unspecified); |
382 | } |
383 | } |
384 | |
385 | /*! |
386 | Returns \c true if values can be removed from the container, \c false |
387 | otherwise. |
388 | |
389 | \sa removeValue(), isSortable() |
390 | */ |
391 | bool QMetaSequence::canRemoveValue() const |
392 | { |
393 | if (auto iface = d()) |
394 | return iface->removeValueFn; |
395 | return false; |
396 | } |
397 | |
398 | /*! |
399 | Removes an value from the \a container if possible. If |
400 | \l canRemoveValue() returns \c false, no value is removed. Else, if |
401 | \l canRemoveValueAtEnd() returns \c true, the last value in |
402 | the \a container is removed. Else, if \l canRemoveValueAtBegin() |
403 | returns \c true, the first value in the \a container is removed. Else, |
404 | an unspecified value or nothing is removed. |
405 | |
406 | \sa canRemoveValue(), canRemoveValueAtBegin(), |
407 | canRemoveValueAtEnd(), isSortable(), addValue() |
408 | */ |
409 | void QMetaSequence::removeValue(void *container) const |
410 | { |
411 | if (canRemoveValue()) { |
412 | d()->removeValueFn(container, |
413 | QtMetaContainerPrivate::QMetaSequenceInterface::Unspecified); |
414 | } |
415 | } |
416 | |
417 | /*! |
418 | Returns \c true if the underlying container offers a non-const iterator, |
419 | \c false otherwise. |
420 | |
421 | \sa begin(), end(), destroyIterator(), compareIterator(), diffIterator(), |
422 | advanceIterator(), copyIterator() |
423 | */ |
424 | bool QMetaContainer::hasIterator() const |
425 | { |
426 | if (!d_ptr || !d_ptr->createIteratorFn) |
427 | return false; |
428 | Q_ASSERT(d_ptr->destroyIteratorFn); |
429 | Q_ASSERT(d_ptr->compareIteratorFn); |
430 | Q_ASSERT(d_ptr->copyIteratorFn); |
431 | Q_ASSERT(d_ptr->advanceIteratorFn); |
432 | Q_ASSERT(d_ptr->diffIteratorFn); |
433 | return true; |
434 | } |
435 | |
436 | /*! |
437 | Creates and returns a non-const iterator pointing to the beginning of |
438 | \a container. The iterator is allocated on the heap using new. It has to be |
439 | destroyed using \l destroyIterator eventually, to reclaim the memory. |
440 | |
441 | Returns \c nullptr if the container doesn't offer any non-const iterators. |
442 | |
443 | \sa end(), constBegin(), constEnd(), destroyIterator() |
444 | */ |
445 | void *QMetaContainer::begin(void *container) const |
446 | { |
447 | return hasIterator() |
448 | ? d_ptr->createIteratorFn( |
449 | container, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin) |
450 | : nullptr; |
451 | } |
452 | |
453 | /*! |
454 | Creates and returns a non-const iterator pointing to the end of |
455 | \a container. The iterator is allocated on the heap using new. It has to be |
456 | destroyed using \l destroyIterator eventually, to reclaim the memory. |
457 | |
458 | Returns \c nullptr if the container doesn't offer any non-const iterators. |
459 | |
460 | \sa hasIterator(), end(), constBegin(), constEnd(), destroyIterator() |
461 | */ |
462 | void *QMetaContainer::end(void *container) const |
463 | { |
464 | return hasIterator() |
465 | ? d_ptr->createIteratorFn( |
466 | container, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd) |
467 | : nullptr; |
468 | } |
469 | |
470 | /*! |
471 | Destroys a non-const \a iterator previously created using \l begin() or |
472 | \l end(). |
473 | |
474 | \sa begin(), end(), destroyConstIterator() |
475 | */ |
476 | void QMetaContainer::destroyIterator(const void *iterator) const |
477 | { |
478 | if (hasIterator()) |
479 | d_ptr->destroyIteratorFn(iterator); |
480 | } |
481 | |
482 | /*! |
483 | Returns \c true if the non-const iterators \a i and \a j point to the same |
484 | value in the container they are iterating over, otherwise returns \c |
485 | false. |
486 | |
487 | \sa begin(), end() |
488 | */ |
489 | bool QMetaContainer::compareIterator(const void *i, const void *j) const |
490 | { |
491 | return hasIterator() ? d_ptr->compareIteratorFn(i, j) : false; |
492 | } |
493 | |
494 | /*! |
495 | Copies the non-const iterator \a source into the non-const iterator |
496 | \a target. Afterwards compareIterator(target, source) returns \c true. |
497 | |
498 | \sa begin(), end() |
499 | */ |
500 | void QMetaContainer::copyIterator(void *target, const void *source) const |
501 | { |
502 | if (hasIterator()) |
503 | d_ptr->copyIteratorFn(target, source); |
504 | } |
505 | |
506 | /*! |
507 | Advances the non-const \a iterator by \a step steps. If \a step is negative |
508 | the \a iterator is moved backwards, towards the beginning of the container. |
509 | The behavior is unspecified for negative values of \a step if |
510 | \l hasBidirectionalIterator() returns false. |
511 | |
512 | \sa begin(), end() |
513 | */ |
514 | void QMetaContainer::advanceIterator(void *iterator, qsizetype step) const |
515 | { |
516 | if (hasIterator()) |
517 | d_ptr->advanceIteratorFn(iterator, step); |
518 | } |
519 | |
520 | /*! |
521 | Returns the distance between the non-const iterators \a i and \a j, the |
522 | equivalent of \a i \c - \a j. If \a j is closer to the end of the container |
523 | than \a i, the returned value is negative. The behavior is unspecified in |
524 | this case if \l hasBidirectionalIterator() returns false. |
525 | |
526 | \sa begin(), end() |
527 | */ |
528 | qsizetype QMetaContainer::diffIterator(const void *i, const void *j) const |
529 | { |
530 | return hasIterator() ? d_ptr->diffIteratorFn(i, j) : 0; |
531 | } |
532 | |
533 | /*! |
534 | Returns \c true if the underlying container can retrieve the value pointed |
535 | to by a non-const iterator, \c false otherwise. |
536 | |
537 | \sa hasIterator(), valueAtIterator() |
538 | */ |
539 | bool QMetaSequence::canGetValueAtIterator() const |
540 | { |
541 | if (auto iface = d()) |
542 | return iface->valueAtIteratorFn; |
543 | return false; |
544 | } |
545 | |
546 | /*! |
547 | Retrieves the value pointed to by the non-const \a iterator and stores it |
548 | in the memory location pointed to by \a result, if possible. |
549 | |
550 | \sa canGetValueAtIterator(), begin(), end() |
551 | */ |
552 | void QMetaSequence::valueAtIterator(const void *iterator, void *result) const |
553 | { |
554 | if (canGetValueAtIterator()) |
555 | d()->valueAtIteratorFn(iterator, result); |
556 | } |
557 | |
558 | /*! |
559 | Returns \c true if the underlying container can write to the value pointed |
560 | to by a non-const iterator, \c false otherwise. |
561 | |
562 | \sa hasIterator(), setValueAtIterator() |
563 | */ |
564 | bool QMetaSequence::canSetValueAtIterator() const |
565 | { |
566 | if (auto iface = d()) |
567 | return iface->setValueAtIteratorFn; |
568 | return false; |
569 | } |
570 | |
571 | /*! |
572 | Writes \a value to the value pointed to by the non-const \a iterator, if |
573 | possible. |
574 | |
575 | \sa canSetValueAtIterator(), begin(), end() |
576 | */ |
577 | void QMetaSequence::setValueAtIterator(const void *iterator, const void *value) const |
578 | { |
579 | if (canSetValueAtIterator()) |
580 | d()->setValueAtIteratorFn(iterator, value); |
581 | } |
582 | |
583 | /*! |
584 | Returns \c true if the underlying container can insert a new value, taking |
585 | the location pointed to by a non-const iterator into account. |
586 | |
587 | \sa hasIterator(), insertValueAtIterator() |
588 | */ |
589 | bool QMetaSequence::canInsertValueAtIterator() const |
590 | { |
591 | if (auto iface = d()) |
592 | return iface->insertValueAtIteratorFn; |
593 | return false; |
594 | } |
595 | |
596 | /*! |
597 | Inserts \a value into the \a container, if possible, taking the non-const |
598 | \a iterator into account. If \l canInsertValueAtIterator() returns |
599 | \c false, the \a value is not inserted. Else if \l isSortable() returns |
600 | \c true, the value is inserted before the value pointed to by |
601 | \a iterator. Else, the \a value is inserted at an unspecified place or not |
602 | at all. In the latter case, the \a iterator is taken as a hint. If it points |
603 | to the correct place for the \a value, the operation may be faster than a |
604 | \l addValue() without iterator. |
605 | |
606 | \sa canInsertValueAtIterator(), isSortable(), begin(), end() |
607 | */ |
608 | void QMetaSequence::insertValueAtIterator(void *container, const void *iterator, |
609 | const void *value) const |
610 | { |
611 | if (canInsertValueAtIterator()) |
612 | d()->insertValueAtIteratorFn(container, iterator, value); |
613 | } |
614 | |
615 | /*! |
616 | Returns \c true if the value pointed to by a non-const iterator can be |
617 | erased, \c false otherwise. |
618 | |
619 | \sa hasIterator(), eraseValueAtIterator() |
620 | */ |
621 | bool QMetaSequence::canEraseValueAtIterator() const |
622 | { |
623 | if (auto iface = d()) |
624 | return iface->eraseValueAtIteratorFn; |
625 | return false; |
626 | } |
627 | |
628 | /*! |
629 | Erases the value pointed to by the non-const \a iterator from the |
630 | \a container, if possible. |
631 | |
632 | \sa canEraseValueAtIterator(), begin(), end() |
633 | */ |
634 | void QMetaSequence::eraseValueAtIterator(void *container, const void *iterator) const |
635 | { |
636 | if (canEraseValueAtIterator()) |
637 | d()->eraseValueAtIteratorFn(container, iterator); |
638 | } |
639 | |
640 | /*! |
641 | Returns \c true if a range between two iterators can be erased from the |
642 | container, \c false otherwise. |
643 | */ |
644 | bool QMetaSequence::canEraseRangeAtIterator() const |
645 | { |
646 | if (auto iface = d()) |
647 | return iface->eraseRangeAtIteratorFn; |
648 | return false; |
649 | } |
650 | |
651 | /*! |
652 | Erases the range of values between the iterators \a iterator1 and |
653 | \a iterator2 from the \a container, if possible. |
654 | |
655 | \sa canEraseValueAtIterator(), begin(), end() |
656 | */ |
657 | void QMetaSequence::eraseRangeAtIterator(void *container, const void *iterator1, |
658 | const void *iterator2) const |
659 | { |
660 | if (canEraseRangeAtIterator()) |
661 | d()->eraseRangeAtIteratorFn(container, iterator1, iterator2); |
662 | } |
663 | |
664 | /*! |
665 | Returns \c true if the underlying container offers a const iterator, |
666 | \c false otherwise. |
667 | |
668 | \sa constBegin(), constEnd(), destroyConstIterator(), |
669 | compareConstIterator(), diffConstIterator(), advanceConstIterator(), |
670 | copyConstIterator() |
671 | */ |
672 | bool QMetaContainer::hasConstIterator() const |
673 | { |
674 | if (!d_ptr || !d_ptr->createConstIteratorFn) |
675 | return false; |
676 | Q_ASSERT(d_ptr->destroyConstIteratorFn); |
677 | Q_ASSERT(d_ptr->compareConstIteratorFn); |
678 | Q_ASSERT(d_ptr->copyConstIteratorFn); |
679 | Q_ASSERT(d_ptr->advanceConstIteratorFn); |
680 | Q_ASSERT(d_ptr->diffConstIteratorFn); |
681 | return true; |
682 | } |
683 | |
684 | /*! |
685 | Creates and returns a const iterator pointing to the beginning of |
686 | \a container. The iterator is allocated on the heap using new. It has to be |
687 | destroyed using \l destroyConstIterator eventually, to reclaim the memory. |
688 | |
689 | Returns \c nullptr if the container doesn't offer any const iterators. |
690 | |
691 | \sa constEnd(), begin(), end(), destroyConstIterator() |
692 | */ |
693 | void *QMetaContainer::constBegin(const void *container) const |
694 | { |
695 | return hasConstIterator() |
696 | ? d_ptr->createConstIteratorFn( |
697 | container, QtMetaContainerPrivate::QMetaSequenceInterface::AtBegin) |
698 | : nullptr; |
699 | } |
700 | |
701 | /*! |
702 | Creates and returns a const iterator pointing to the end of |
703 | \a container. The iterator is allocated on the heap using new. It has to be |
704 | destroyed using \l destroyConstIterator eventually, to reclaim the memory. |
705 | |
706 | Returns \c nullptr if the container doesn't offer any const iterators. |
707 | |
708 | \sa constBegin(), begin(), end(), destroyConstIterator() |
709 | */ |
710 | void *QMetaContainer::constEnd(const void *container) const |
711 | { |
712 | return hasConstIterator() |
713 | ? d_ptr->createConstIteratorFn( |
714 | container, QtMetaContainerPrivate::QMetaSequenceInterface::AtEnd) |
715 | : nullptr; |
716 | } |
717 | |
718 | /*! |
719 | Destroys a const \a iterator previously created using \l constBegin() or |
720 | \l constEnd(). |
721 | |
722 | \sa constBegin(), constEnd(), destroyIterator() |
723 | */ |
724 | void QMetaContainer::destroyConstIterator(const void *iterator) const |
725 | { |
726 | if (hasConstIterator()) |
727 | d_ptr->destroyConstIteratorFn(iterator); |
728 | } |
729 | |
730 | /*! |
731 | Returns \c true if the const iterators \a i and \a j point to the same |
732 | value in the container they are iterating over, otherwise returns \c |
733 | false. |
734 | |
735 | \sa constBegin(), constEnd() |
736 | */ |
737 | bool QMetaContainer::compareConstIterator(const void *i, const void *j) const |
738 | { |
739 | return hasConstIterator() ? d_ptr->compareConstIteratorFn(i, j) : false; |
740 | } |
741 | |
742 | /*! |
743 | Copies the const iterator \a source into the const iterator |
744 | \a target. Afterwards compareConstIterator(target, source) returns \c true. |
745 | |
746 | \sa constBegin(), constEnd() |
747 | */ |
748 | void QMetaContainer::copyConstIterator(void *target, const void *source) const |
749 | { |
750 | if (hasConstIterator()) |
751 | d_ptr->copyConstIteratorFn(target, source); |
752 | } |
753 | |
754 | /*! |
755 | Advances the const \a iterator by \a step steps. If \a step is negative |
756 | the \a iterator is moved backwards, towards the beginning of the container. |
757 | The behavior is unspecified for negative values of \a step if |
758 | \l hasBidirectionalIterator() returns false. |
759 | |
760 | \sa constBegin(), constEnd() |
761 | */ |
762 | void QMetaContainer::advanceConstIterator(void *iterator, qsizetype step) const |
763 | { |
764 | if (hasConstIterator()) |
765 | d_ptr->advanceConstIteratorFn(iterator, step); |
766 | } |
767 | |
768 | /*! |
769 | Returns the distance between the const iterators \a i and \a j, the |
770 | equivalent of \a i \c - \a j. If \a j is closer to the end of the container |
771 | than \a i, the returned value is negative. The behavior is unspecified in |
772 | this case if \l hasBidirectionalIterator() returns false. |
773 | |
774 | \sa constBegin(), constEnd() |
775 | */ |
776 | qsizetype QMetaContainer::diffConstIterator(const void *i, const void *j) const |
777 | { |
778 | return hasConstIterator() ? d_ptr->diffConstIteratorFn(i, j) : 0; |
779 | } |
780 | |
781 | /*! |
782 | Returns \c true if the underlying container can retrieve the value pointed |
783 | to by a const iterator, \c false otherwise. |
784 | |
785 | \sa hasConstIterator(), valueAtConstIterator() |
786 | */ |
787 | bool QMetaSequence::canGetValueAtConstIterator() const |
788 | { |
789 | if (auto iface = d()) |
790 | return iface->valueAtConstIteratorFn; |
791 | return false; |
792 | } |
793 | |
794 | /*! |
795 | Retrieves the value pointed to by the const \a iterator and stores it |
796 | in the memory location pointed to by \a result, if possible. |
797 | |
798 | \sa canGetValueAtConstIterator(), constBegin(), constEnd() |
799 | */ |
800 | void QMetaSequence::valueAtConstIterator(const void *iterator, void *result) const |
801 | { |
802 | if (canGetValueAtConstIterator()) |
803 | d()->valueAtConstIteratorFn(iterator, result); |
804 | } |
805 | |
806 | /*! |
807 | \fn bool QMetaSequence::operator==(const QMetaSequence &lhs, const QMetaSequence &rhs) |
808 | \since 6.0 |
809 | |
810 | Returns \c true if the QMetaSequence \a lhs represents the same container type |
811 | as the QMetaSequence \a rhs, otherwise returns \c false. |
812 | */ |
813 | |
814 | /*! |
815 | \fn bool QMetaSequence::operator!=(const QMetaSequence &lhs, const QMetaSequence &rhs) |
816 | \since 6.0 |
817 | |
818 | Returns \c true if the QMetaSequence \a lhs represents a different container |
819 | type than the QMetaSequence \a rhs, otherwise returns \c false. |
820 | */ |
821 | |
822 | |
823 | /*! |
824 | Returns the meta type for keys in the container. |
825 | */ |
826 | QMetaType QMetaAssociation::keyMetaType() const |
827 | { |
828 | if (auto iface = d()) |
829 | return QMetaType(iface->keyMetaType); |
830 | return QMetaType(); |
831 | } |
832 | |
833 | /*! |
834 | Returns the meta type for mapped values in the container. |
835 | */ |
836 | QMetaType QMetaAssociation::mappedMetaType() const |
837 | { |
838 | if (auto iface = d()) |
839 | return QMetaType(iface->mappedMetaType); |
840 | return QMetaType(); |
841 | } |
842 | |
843 | QT_END_NAMESPACE |
844 |
Definitions
- hasInputIterator
- hasForwardIterator
- hasBidirectionalIterator
- hasRandomAccessIterator
- valueMetaType
- isSortable
- canAddValueAtBegin
- addValueAtBegin
- canRemoveValueAtBegin
- removeValueAtBegin
- canAddValueAtEnd
- addValueAtEnd
- canRemoveValueAtEnd
- removeValueAtEnd
- hasSize
- size
- canClear
- clear
- canGetValueAtIndex
- valueAtIndex
- canSetValueAtIndex
- setValueAtIndex
- canAddValue
- addValue
- canRemoveValue
- removeValue
- hasIterator
- begin
- end
- destroyIterator
- compareIterator
- copyIterator
- advanceIterator
- diffIterator
- canGetValueAtIterator
- valueAtIterator
- canSetValueAtIterator
- setValueAtIterator
- canInsertValueAtIterator
- insertValueAtIterator
- canEraseValueAtIterator
- eraseValueAtIterator
- canEraseRangeAtIterator
- eraseRangeAtIterator
- hasConstIterator
- constBegin
- constEnd
- destroyConstIterator
- compareConstIterator
- copyConstIterator
- advanceConstIterator
- diffConstIterator
- canGetValueAtConstIterator
- valueAtConstIterator
- keyMetaType
Learn to use CMake with our Intro Training
Find out more