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
qiterable.h
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
5#ifndef QITERABLE_H
6#define QITERABLE_H
7
8#include <QtCore/qglobal.h>
9#include <QtCore/qtypeinfo.h>
10#include <QtCore/qtaggedpointer.h>
11
12QT_BEGIN_NAMESPACE
13
14namespace QtPrivate {
15 template<typename Type, typename Storage = Type>
17 {
18 enum Tag : bool { Const, Mutable };
19 QTaggedPointer<Storage, Tag> m_pointer;
20
21 public:
23
25 : m_pointer(reinterpret_cast<Storage *>(const_cast<void *>(pointer)), Const)
26 {
29 }
30
37
38 template<typename InputType>
40 : m_pointer(reinterpret_cast<Storage *>(const_cast<InputType *>(pointer)), Const)
41 {
42 static_assert(alignof(InputType) >= alignof(Storage));
43 }
44
45 template<typename InputType>
47 : m_pointer(reinterpret_cast<Storage *>(pointer), Mutable)
48 {
49 static_assert(alignof(InputType) >= alignof(Storage));
50 }
51
53
54 const Type *constPointer() const
55 {
56 return reinterpret_cast<const Type *>(m_pointer.data());
57 }
58
59 Type *mutablePointer() const
60 {
61 return m_pointer.tag() == Mutable ? reinterpret_cast<Type *>(m_pointer.data()) : nullptr;
62 }
63 };
64
70
72}
73
74template<class Iterator, typename IteratorCategory>
75class QTaggedIterator : public Iterator
76{
77public:
78 using iterator_category = IteratorCategory;
79 QTaggedIterator(Iterator &&it) : Iterator(std::move(it))
80 {
81 [[maybe_unused]] const auto metaContainer = this->metaContainer();
82 if constexpr (std::is_base_of_v<std::random_access_iterator_tag, IteratorCategory>) {
83 if (!metaContainer.hasRandomAccessIterator()) {
84 qFatal("You cannot use this iterator as a random access iterator");
85 this->clearIterator();
86 }
87 }
88
89 if constexpr (std::is_base_of_v<std::bidirectional_iterator_tag, IteratorCategory>) {
90 if (!metaContainer.hasBidirectionalIterator()) {
91 qFatal("You cannot use this iterator as a bidirectional iterator");
92 this->clearIterator();
93 }
94 }
95
96 if constexpr (std::is_base_of_v<std::forward_iterator_tag, IteratorCategory>) {
97 if (!metaContainer.hasForwardIterator()) {
98 qFatal("You cannot use this iterator as a forward iterator");
99 this->clearIterator();
100 }
101 }
102
103 if constexpr (std::is_base_of_v<std::input_iterator_tag, IteratorCategory>) {
104 if (!metaContainer.hasInputIterator()) {
105 qFatal("You cannot use this iterator as an input iterator");
106 this->clearIterator();
107 }
108 }
109 }
110
111 bool operator==(const QTaggedIterator &o) const { return Iterator::operator==(o); }
112 bool operator!=(const QTaggedIterator &o) const { return Iterator::operator!=(o); }
113 QTaggedIterator &operator++() { Iterator::operator++(); return *this; }
114 QTaggedIterator operator++(int x) { return QTaggedIterator(Iterator::operator++(x)); }
115 QTaggedIterator &operator--() { Iterator::operator--(); return *this; }
116 QTaggedIterator operator--(int x) { return QTaggedIterator(Iterator::operator--(x)); }
117 QTaggedIterator &operator+=(qsizetype j) { Iterator::operator+=(j); return *this; }
118 QTaggedIterator &operator-=(qsizetype j) { Iterator::operator-=(j); return *this; }
119 QTaggedIterator operator+(qsizetype j) const { return QTaggedIterator(Iterator::operator+(j)); }
120 QTaggedIterator operator-(qsizetype j) const { return QTaggedIterator(Iterator::operator-(j)); }
121 qsizetype operator-(const QTaggedIterator &j) const { return Iterator::operator-(j); }
122
123 bool operator<(const QTaggedIterator &j) { return operator-(j) < 0; }
124 bool operator>=(const QTaggedIterator &j) { return !operator<(j); }
125 bool operator>(const QTaggedIterator &j) { return operator-(j) > 0; }
126 bool operator<=(const QTaggedIterator &j) { return !operator>(j); }
127
128 friend inline QTaggedIterator operator+(qsizetype j, const QTaggedIterator &k) { return k + j; }
129};
130
131template<class Container>
132class QIterable;
133
134template<class Container>
136{
137private:
138 QtPrivate::QConstPreservingPointer<QIterable<Container>> m_iterable;
139 void *m_iterator = nullptr;
140
141protected:
142 QBaseIterator() = default;
143 QBaseIterator(const QIterable<Container> *iterable, void *iterator)
144 : m_iterable(iterable), m_iterator(iterator)
145 {}
146
147 QBaseIterator(QIterable<Container> *iterable, void *iterator)
148 : m_iterable(iterable), m_iterator(iterator)
149 {}
150
153 {
154 other.m_iterator = nullptr;
155 }
156
159 {
160 initIterator(other.m_iterator);
161 }
162
164
166 {
167 if (this != &other) {
169 m_iterable = std::move(other.m_iterable);
170 m_iterator = std::move(other.m_iterator);
171 other.m_iterator = nullptr;
172 }
173 return *this;
174 }
175
177 {
178 if (this != &other) {
180 m_iterable = other.m_iterable;
181 initIterator(other.m_iterator);
182 }
183 return *this;
184 }
185
186 QIterable<Container> *mutableIterable() const
187 {
188 return m_iterable.mutablePointer();
189 }
190
191 const QIterable<Container> *constIterable() const
192 {
193 return m_iterable.constPointer();
194 }
195
196 void initIterator(const void *copy)
197 {
198 if (!copy)
199 return;
200 if (auto *mutableIt = mutableIterable()) {
201 m_iterator = metaContainer().begin(mutableIt->mutableIterable());
202 metaContainer().copyIterator(m_iterator, copy);
203 } else if (auto *constIt = constIterable()) {
204 m_iterator = metaContainer().constBegin(constIt->constIterable());
205 metaContainer().copyConstIterator(m_iterator, copy);
206 }
207 }
208
210 {
211 if (!m_iterator)
212 return;
214 metaContainer().destroyIterator(m_iterator);
215 else
216 metaContainer().destroyConstIterator(m_iterator);
217 }
218
219public:
220 void *mutableIterator() { return m_iterator; }
221 const void *constIterator() const { return m_iterator; }
222 Container metaContainer() const { return constIterable()->m_metaContainer; }
223};
224
225template<class Container>
226struct QIterator : public QBaseIterator<Container>
227{
228public:
230
231 explicit QIterator(QIterable<Container> *iterable, void *iterator)
232 : QBaseIterator<Container>(iterable, iterator)
233 {
234 Q_ASSERT(iterable != nullptr);
235 }
236
237 bool operator==(const QIterator &o) const
238 {
239 return this->metaContainer().compareIterator(this->constIterator(), o.constIterator());
240 }
241
242 bool operator!=(const QIterator &o) const
243 {
244 return !this->metaContainer().compareIterator(this->constIterator(), o.constIterator());
245 }
246
248 {
249 this->metaContainer().advanceIterator(this->mutableIterator(), 1);
250 return *this;
251 }
252
254 {
255 QIterable<Container> *iterable = this->mutableIterable();
256 const Container metaContainer = this->metaContainer();
257 QIterator result(iterable, metaContainer.begin(iterable->mutableIterable()));
258 metaContainer.copyIterator(result.mutableIterator(), this->constIterator());
259 metaContainer.advanceIterator(this->mutableIterator(), 1);
260 return result;
261 }
262
264 {
265 this->metaContainer().advanceIterator(this->mutableIterator(), -1);
266 return *this;
267 }
268
270 {
271 QIterable<Container> *iterable = this->mutableIterable();
272 const Container metaContainer = this->metaContainer();
273 QIterator result(iterable, metaContainer.begin(iterable->mutableIterable()));
274 metaContainer.copyIterator(result.mutableIterator(), this->constIterator());
275 metaContainer.advanceIterator(this->mutableIterator(), -1);
276 return result;
277 }
278
279 QIterator &operator+=(qsizetype j)
280 {
281 this->metaContainer().advanceIterator(this->mutableIterator(), j);
282 return *this;
283 }
284
285 QIterator &operator-=(qsizetype j)
286 {
287 this->metaContainer().advanceIterator(this->mutableIterator(), -j);
288 return *this;
289 }
290
291 QIterator operator+(qsizetype j) const
292 {
293 QIterable<Container> *iterable = this->mutableIterable();
294 const Container metaContainer = this->metaContainer();
295 QIterator result(iterable, metaContainer.begin(iterable->mutableIterable()));
296 metaContainer.copyIterator(result.mutableIterator(), this->constIterator());
297 metaContainer.advanceIterator(result.mutableIterator(), j);
298 return result;
299 }
300
301 QIterator operator-(qsizetype j) const
302 {
303 QIterable<Container> *iterable = this->mutableIterable();
304 const Container metaContainer = this->metaContainer();
305 QIterator result(iterable, metaContainer.begin(iterable->mutableIterable()));
306 metaContainer.copyIterator(result.mutableIterator(), this->constIterator());
307 metaContainer.advanceIterator(result.mutableIterator(), -j);
308 return result;
309 }
310
311 qsizetype operator-(const QIterator &j) const
312 {
313 return this->metaContainer().diffIterator(this->constIterator(), j.constIterator());
314 }
315
316 friend inline QIterator operator+(qsizetype j, const QIterator &k) { return k + j; }
317};
318
319template<class Container>
320struct QConstIterator : public QBaseIterator<Container>
321{
322public:
324
325 explicit QConstIterator(const QIterable<Container> *iterable, void *iterator)
326 : QBaseIterator<Container>(iterable, iterator)
327 {
328 }
329
330 bool operator==(const QConstIterator &o) const
331 {
332 return this->metaContainer().compareConstIterator(
333 this->constIterator(), o.constIterator());
334 }
335
336 bool operator!=(const QConstIterator &o) const
337 {
338 return !this->metaContainer().compareConstIterator(
339 this->constIterator(), o.constIterator());
340 }
341
343 {
344 this->metaContainer().advanceConstIterator(this->mutableIterator(), 1);
345 return *this;
346 }
347
349 {
350 const Container metaContainer = this->metaContainer();
351 QConstIterator result(this->constIterable(), metaContainer.constBegin(
352 this->constIterable()->constIterable()));
353 metaContainer.copyConstIterator(result.mutableIterator(), this->constIterator());
354 metaContainer.advanceConstIterator(this->mutableIterator(), 1);
355 return result;
356 }
357
359 {
360 this->metaContainer().advanceConstIterator(this->mutableIterator(), -1);
361 return *this;
362 }
363
365 {
366 const Container metaContainer = this->metaContainer();
367 QConstIterator result(this->constIterable(), metaContainer.constBegin(
368 this->constIterable()->constIterable()));
369 metaContainer.copyConstIterator(result.mutableIterator(), this->constIterator());
370 metaContainer.advanceConstIterator(this->mutableIterator(), -1);
371 return result;
372 }
373
374 QConstIterator &operator+=(qsizetype j)
375 {
376 this->metaContainer().advanceConstIterator(this->mutableIterator(), j);
377 return *this;
378 }
379
380 QConstIterator &operator-=(qsizetype j)
381 {
382 this->metaContainer().advanceConstIterator(this->mutableIterator(), -j);
383 return *this;
384 }
385
386 QConstIterator operator+(qsizetype j) const
387 {
388 const Container metaContainer = this->metaContainer();
389 QConstIterator result(
390 this->constIterable(),
391 metaContainer.constBegin(this->constIterable()->constIterable()));
392 metaContainer.copyConstIterator(result.mutableIterator(), this->constIterator());
393 metaContainer.advanceConstIterator(result.mutableIterator(), j);
394 return result;
395 }
396
397 QConstIterator operator-(qsizetype j) const
398 {
399 const Container metaContainer = this->metaContainer();
400 QConstIterator result(this->constIterable(), metaContainer.constBegin(
401 this->constIterable()->constIterable()));
402 metaContainer.copyConstIterator(result.mutableIterator(), this->constIterator());
403 metaContainer.advanceConstIterator(result.mutableIterator(), -j);
404 return result;
405 }
406
408 {
409 return this->metaContainer().diffIterator(this->constIterator(), j.constIterator());
410 }
411
412 friend inline QConstIterator operator+(qsizetype j, const QConstIterator &k)
413 {
414 return k + j;
415 }
416};
417
418template<class Container>
420{
421 friend class QBaseIterator<Container>;
422
423protected:
427
428public:
429 template<class T>
430 QIterable(const Container &metaContainer, const T *p)
431 : m_iterable(p), m_metaContainer(metaContainer)
432 {
433 }
434
435 template<class T>
436 QIterable(const Container &metaContainer, T *p)
437 : m_iterable(p), m_metaContainer(metaContainer)
438 {
439 }
440
441 template<typename Pointer>
442 QIterable(const Container &metaContainer, Pointer iterable)
443 : m_iterable(iterable), m_metaContainer(metaContainer)
444 {
445 }
446
447 QIterable(const Container &metaContainer, qsizetype alignment, const void *p)
448 : m_iterable(p, alignment), m_metaContainer(metaContainer)
449 {
450 }
451
452 QIterable(const Container &metaContainer, qsizetype alignment, void *p)
453 : m_iterable(p, alignment), m_metaContainer(metaContainer)
454 {
455 }
456
457 bool canInputIterate() const
458 {
459 return m_metaContainer.hasInputIterator();
460 }
461
462 bool canForwardIterate() const
463 {
464 return m_metaContainer.hasForwardIterator();
465 }
466
467 bool canReverseIterate() const
468 {
469 return m_metaContainer.hasBidirectionalIterator();
470 }
471
473 {
474 return m_metaContainer.hasRandomAccessIterator();
475 }
476
477 const void *constIterable() const { return m_iterable.constPointer(); }
478 void *mutableIterable() { return m_iterable.mutablePointer(); }
479
480 QConstIterator<Container> constBegin() const
481 {
482 return QConstIterator(this, m_metaContainer.constBegin(constIterable()));
483 }
484
485 QConstIterator<Container> constEnd() const
486 {
487 return QConstIterator(this, m_metaContainer.constEnd(constIterable()));
488 }
489
491 {
492 return QIterator(this, m_metaContainer.begin(mutableIterable()));
493 }
494
496 {
498 }
499
501 {
502 const void *container = constIterable();
503 if (m_metaContainer.hasSize())
504 return m_metaContainer.size(container);
505
506#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0)
507 // We shouldn't second-guess the underlying container, so we're not synthesizing a size.
508 return -1;
509#else
512
513 if (!m_metaContainer.hasConstIterator())
514 return -1;
515
516 const void *begin = m_metaContainer.constBegin(container);
517 const void *end = m_metaContainer.constEnd(container);
518 const qsizetype size = m_metaContainer.diffConstIterator(end, begin);
519 m_metaContainer.destroyConstIterator(begin);
520 m_metaContainer.destroyConstIterator(end);
521 return size;
522#endif
523 }
524
525 void clear()
526 {
528 }
529
530 Container metaContainer() const
531 {
532 return m_metaContainer;
533 }
534};
535
536QT_END_NAMESPACE
537
538#endif // QITERABLE_H
\inmodule QtCore QBaseIterator<Container> forms the common base class for all iterators operating on ...
Definition qiterable.h:136
QBaseIterator(QBaseIterator &&other)
Definition qiterable.h:151
QBaseIterator & operator=(QBaseIterator &&other)
Definition qiterable.h:165
QBaseIterator(QIterable< Container > *iterable, void *iterator)
Definition qiterable.h:147
const QIterable< Container > * constIterable() const
Definition qiterable.h:191
const void * constIterator() const
Returns a const pointer to the internal native iterator.
Definition qiterable.h:221
void clearIterator()
Definition qiterable.h:209
Container metaContainer() const
Definition qiterable.h:222
QBaseIterator & operator=(const QBaseIterator &other)
Definition qiterable.h:176
void * mutableIterator()
Returns a non-const pointer to the internal native iterator.
Definition qiterable.h:220
QBaseIterator()=default
QIterable< Container > * mutableIterable() const
Definition qiterable.h:186
QBaseIterator(const QIterable< Container > *iterable, void *iterator)
Definition qiterable.h:143
QBaseIterator(const QBaseIterator &other)
Definition qiterable.h:157
void initIterator(const void *copy)
Definition qiterable.h:196
\inmodule QtCore
Definition qiterable.h:420
bool canForwardIterate() const
Returns whether it is possible to iterate over the container in forward direction.
Definition qiterable.h:462
uint m_revision
Definition qiterable.h:424
QIterable(const Container &metaContainer, Pointer iterable)
Definition qiterable.h:442
QConstIterator< Container > constEnd() const
Returns a Qterable::QConstIterator for the end of the container.
Definition qiterable.h:485
const void * constIterable() const
Definition qiterable.h:477
QIterator< Container > mutableEnd()
Returns a QMetaSequence::Iterable::iterator for the end of the container.
Definition qiterable.h:495
QIterable(const Container &metaContainer, qsizetype alignment, const void *p)
Definition qiterable.h:447
Container m_metaContainer
Definition qiterable.h:426
bool canReverseIterate() const
Returns whether it is possible to iterate over the container in reverse.
Definition qiterable.h:467
QIterable(const Container &metaContainer, const T *p)
Definition qiterable.h:430
QConstIterator< Container > constBegin() const
Returns a QConstIterator for the beginning of the container.
Definition qiterable.h:480
bool canInputIterate() const
Returns whether the container has an input iterator.
Definition qiterable.h:457
bool canRandomAccessIterate() const
Returns whether it is possible to efficiently skip over multiple values using and iterator.
Definition qiterable.h:472
void clear()
Clears the container.
Definition qiterable.h:525
void * mutableIterable()
Definition qiterable.h:478
Container metaContainer() const
Definition qiterable.h:530
QtPrivate::QConstPreservingPointer< void, quint16 > m_iterable
Definition qiterable.h:425
QIterable(const Container &metaContainer, T *p)
Definition qiterable.h:436
QIterable(const Container &metaContainer, qsizetype alignment, void *p)
Definition qiterable.h:452
qsizetype size() const
Returns the number of values in the container.
Definition qiterable.h:500
QIterator< Container > mutableBegin()
Returns a QIterator for the beginning of the container.
Definition qiterable.h:490
QTaggedIterator is a template class that wraps an iterator and exposes standard iterator traits.
Definition qiterable.h:76
QTaggedIterator & operator-=(qsizetype j)
Makes the iterator go back by j items.
Definition qiterable.h:118
friend QTaggedIterator operator+(qsizetype j, const QTaggedIterator &k)
Returns an iterator to the item at j positions forward from iterator k.
Definition qiterable.h:128
bool operator<(const QTaggedIterator &j)
Definition qiterable.h:123
QTaggedIterator operator+(qsizetype j) const
Returns an iterator to the item at j positions forward from this iterator.
Definition qiterable.h:119
QTaggedIterator operator--(int x)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qiterable.h:116
bool operator!=(const QTaggedIterator &o) const
Returns true if other points to a different item than this iterator; otherwise returns false.
Definition qiterable.h:112
QTaggedIterator operator++(int x)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qiterable.h:114
bool operator<=(const QTaggedIterator &j)
Definition qiterable.h:126
bool operator==(const QTaggedIterator &o) const
Returns true if other points to the same item as this iterator; otherwise returns false.
Definition qiterable.h:111
QTaggedIterator & operator--()
The prefix {–} operator ({–it}) makes the preceding item current and returns an iterator to the new c...
Definition qiterable.h:115
QTaggedIterator & operator+=(qsizetype j)
Advances the iterator by j items.
Definition qiterable.h:117
QTaggedIterator & operator++()
The prefix {++} operator ({++it}) advances the iterator to the next item in the container and returns...
Definition qiterable.h:113
bool operator>(const QTaggedIterator &j)
Definition qiterable.h:125
QTaggedIterator operator-(qsizetype j) const
Returns an iterator to the item at j positions backward from this iterator.
Definition qiterable.h:120
QTaggedIterator(Iterator &&it)
Constructs a QTaggedIterator from an iterator or QConstIterator it.
Definition qiterable.h:79
IteratorCategory iterator_category
Definition qiterable.h:78
bool operator>=(const QTaggedIterator &j)
Definition qiterable.h:124
qsizetype operator-(const QTaggedIterator &j) const
Returns the distance between this iterator and j.
Definition qiterable.h:121
const Type * constPointer() const
Definition qiterable.h:54
Q_CORE_EXPORT void warnSynthesizedIterableAccess(SynthesizedAccessFunction function)
SynthesizedAccessFunction
Definition qiterable.h:66
The QConstIterator allows iteration over a container in a QVariant.
Definition qiterable.h:321
bool operator==(const QConstIterator &o) const
Returns true if other points to the same item as this iterator; otherwise returns false.
Definition qiterable.h:330
QConstIterator & operator+=(qsizetype j)
Advances the iterator by j items.
Definition qiterable.h:374
QConstIterator(const QIterable< Container > *iterable, void *iterator)
Creates a QConstIterator to wrap iterator, operating on iterable.
Definition qiterable.h:325
QConstIterator operator++(int)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qiterable.h:348
friend QConstIterator operator+(qsizetype j, const QConstIterator &k)
Definition qiterable.h:412
QConstIterator operator+(qsizetype j) const
Returns an iterator to the item at j positions forward from this iterator.
Definition qiterable.h:386
QConstIterator operator--(int)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qiterable.h:364
bool operator!=(const QConstIterator &o) const
Returns true if other points to a different item than this iterator; otherwise returns false.
Definition qiterable.h:336
qsizetype operator-(const QConstIterator &j) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qiterable.h:407
QConstIterator & operator-=(qsizetype j)
Makes the iterator go back by j items.
Definition qiterable.h:380
QConstIterator & operator--()
The prefix {–} operator ({–it}) makes the preceding item current and returns an iterator to the new c...
Definition qiterable.h:358
QConstIterator & operator++()
The prefix {++} operator ({++it}) advances the iterator to the next item in the container and returns...
Definition qiterable.h:342
QConstIterator operator-(qsizetype j) const
Returns an iterator to the item at j positions backward from this iterator.
Definition qiterable.h:397
The QIterator is a template class that allows iteration over a container in a QVariant.
Definition qiterable.h:227
bool operator==(const QIterator &o) const
Returns true if other points to the same item as this iterator; otherwise returns false.
Definition qiterable.h:237
friend QIterator operator+(qsizetype j, const QIterator &k)
Returns an iterator to the item at j positions forward from iterator k.
Definition qiterable.h:316
QIterator & operator+=(qsizetype j)
Advances the iterator by j items.
Definition qiterable.h:279
bool operator!=(const QIterator &o) const
Returns true if other points to a different item than this iterator; otherwise returns false.
Definition qiterable.h:242
QIterator operator-(qsizetype j) const
Returns an iterator to the item at j positions backward from this iterator.
Definition qiterable.h:301
QIterator & operator--()
The prefix {–} operator ({–it}) makes the preceding item current and returns an iterator to the new c...
Definition qiterable.h:263
qsizetype operator-(const QIterator &j) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qiterable.h:311
QIterator & operator-=(qsizetype j)
Makes the iterator go back by j items.
Definition qiterable.h:285
QIterator(QIterable< Container > *iterable, void *iterator)
Creates an iterator from an iterable and a pointer to a native iterator.
Definition qiterable.h:231
QIterator operator++(int)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qiterable.h:253
QIterator operator+(qsizetype j) const
Returns an iterator to the item at j positions forward from this iterator.
Definition qiterable.h:291
QIterator & operator++()
The prefix {++} operator ({++it}) advances the iterator to the next item in the container and returns...
Definition qiterable.h:247
QIterator operator--(int)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qiterable.h:269