6#include <QtCore/qvarlengtharray.h>
69#ifdef QT_QML_VERIFY_MINIMAL
70#define QT_QML_VERIFY_INTEGRITY
82static bool qt_verifyMinimal(
105#ifdef QT_QML_VERIFY_INTEGRITY
122static bool qt_verifyIntegrity(
144 if (
it->previous->next !=
it.range) {
145 qWarning() <<
index <<
"broken list: it->previous->next != it.range";
148 if (
it->next->previous !=
it.range) {
149 qWarning() <<
index <<
"broken list: it->next->previous != it.range";
152 if (*
it == *cachedIt) {
153 for (
int i = 0;
i <
end.groupCount; ++
i) {
154 int groupIndex =
it.index[
i];
155 if (cachedIt->
flags & (1 <<
i))
156 groupIndex += cachedIt.
offset;
157 if (groupIndex != cachedIt.
index[
i]) {
159 <<
"invalid cached index"
174 for (
int i = 0;
i <
end.groupCount; ++
i) {
175 if (
end.index[
i] !=
it.index[
i]) {
176 qWarning() <<
"Group" <<
i <<
"count invalid. Expected:" <<
end.index[
i] <<
"Actual:" <<
it.index[
i];
184#if defined(QT_QML_VERIFY_MINIMAL)
185# define QT_QML_VERIFY_LISTCOMPOSITOR Q_ASSERT(!(!(qt_verifyIntegrity(iterator(m_ranges.next, 0, Default, m_groupCount), m_end, m_cacheIt) \
186 && qt_verifyMinimal(iterator(m_ranges.next, 0, Default, m_groupCount), m_end)) \
187 && qt_printInfo(*this)));
188#elif defined(QT_QML_VERIFY_INTEGRITY)
189# define QT_QML_VERIFY_LISTCOMPOSITOR Q_ASSERT(!(!qt_verifyIntegrity(iterator(m_ranges.next, 0, Default, m_groupCount), m_end, m_cacheIt) \
190 && qt_printInfo(*this)));
192# define QT_QML_VERIFY_LISTCOMPOSITOR
196#define QT_QML_TRACE_LISTCOMPOSITOR(args)
210 while (offset <= 0 && range->previous->flags) {
306 m_groupCount =
count;
330 if (m_cacheIt == m_end) {
372 if (m_cacheIt == m_end) {
461 *before = erase(*before);
503 }
else if (from.
offset > 0) {
512 if (from != from.
group) {
522 const uint insertFlags = ~from->flags &
flags;
524 if (insertFlags && inserts)
536 from->
index += difference;
537 from->
count -= difference;
538 if (from->
count == 0) {
548 }
else if (!insertFlags) {
552 }
else if (difference < from->
count) {
556 from->
index += difference;
557 from->
count -= difference;
615 }
else if (from.
offset > 0) {
637 if (removeFlags && removes) {
638 const int maskedFlags = clearCache
639 ? (removeFlags & ~CacheFlag)
654 from->
index += difference;
655 from->
count -= difference;
656 if (from->
count == 0) {
664 }
else if (difference < from->
count) {
668 *from =
insert(*from, from->
list, from->
index, difference, clearedFlags)->next;
669 from->
index += difference;
670 from->
count -= difference;
672 }
else if (clearedFlags) {
681 if (*from != &m_ranges && from->
previous != &m_ranges
698 if (
group != toGroup) {
702 int intersectingCount = 0;
704 for (;
count > 0; *fromIt = fromIt->
next) {
705 if (*fromIt == &m_ranges)
714 count = intersectingCount;
717 return to >= 0 && to +
count <= m_end.
index[toGroup];
748 if (fromIt != moveGroup) {
753 *fromIt = fromIt->
next;
754 }
else if (fromIt.
offset > 0) {
767 for (
int moveId = m_moveId;
count > 0;) {
768 if (fromIt != moveGroup) {
771 *fromIt = fromIt->
next;
787 fromIt->
count -= difference;
791 int removeIndex = fromIt->
index;
799 }
else if (fromIt->
prepend()) {
802 fromIt->
index += difference;
804 if (fromIt->
count == 0) {
808 *fromIt = erase(*fromIt);
818 *fromIt = erase(*fromIt);
820 }
else if (
count > 0) {
821 *fromIt = fromIt->
next;
826 if (*fromIt != m_ranges.
next
827 && *fromIt != &m_ranges
831 if (fromIt == fromIt.
group)
843 const int difference = to - toIt.
index[toGroup];
851 toIt->count -= toIt.
offset;
858 if (*toIt != &m_ranges
861 &&
range->flags == (toIt->flags & ~AppendFlag)) {
863 toIt->count +=
range->count;
870 if (*toIt != m_ranges.
next
871 && toIt->previous->
list == toIt->
list
872 && (!toIt->
list || (toIt->previous->end() == toIt->
index && toIt->previous->flags == (toIt->flags & ~
AppendFlag)))) {
873 toIt.
offset = toIt->previous->count;
874 toIt->previous->count += toIt->count;
875 toIt->previous->flags = toIt->flags;
884 insert.moveId = ++m_moveId;
887 for (
int i = 0;
i < m_groupCount; ++
i) {
920 for (iterator
it(m_ranges.
next, 0,
Default, m_groupCount); *
it != &m_ranges; *
it =
it->next) {
927 it->flags &= ~MovedFlag;
932 int offset = insertion.index -
it->index;
940 if (insertion.isMove()) {
946 if (
move->moveId == insertion.moveId) {
954 Insert translatedInsert(
it, insertion.
count,
flags, insertion.moveId);
955 for (
int i = 0;
i < m_groupCount; ++
i) {
957 translatedInsert.index[
i] +=
offset;
959 translatedInsertions->
append(translatedInsert);
966 &&
it->previous != &m_ranges
967 &&
it->previous->list ==
list
969 &&
it->previous->flags ==
flags) {
972 it->previous->
count += insertion.count;
974 it.incrementIndexes(insertion.count);
983 it.incrementIndexes(insertion.count,
flags);
1044 for (iterator
it(m_ranges.
next, 0,
Default, m_groupCount); *
it != &m_ranges; *
it =
it->next) {
1050 bool removed =
false;
1052 !removed && removal != removals->
end();
1054 int relativeIndex = removal->index -
it->index;
1055 int itemsRemoved = removal->
count;
1056 if (relativeIndex + removal->count > 0 && relativeIndex < it->
count) {
1061 int removeFlags =
it->flags & m_removeFlags;
1062 Remove translatedRemoval(
it, removeCount,
it->flags);
1063 for (
int i = 0;
i < m_groupCount; ++
i) {
1065 translatedRemoval.index[
i] +=
offset;
1067 if (removal->isMove()) {
1070 for (; insertion != insertions->
end() && insertion->moveId != removal->moveId;
1073 Q_ASSERT(insertion->count == removal->count);
1075 if (relativeIndex < 0) {
1078 int splitMoveId = ++m_moveId;
1080 removal->index, -relativeIndex, splitMoveId));
1082 removal->
count -= -relativeIndex;
1084 insertion->index, -relativeIndex, splitMoveId));
1086 insertion->index += -relativeIndex;
1087 insertion->count -= -relativeIndex;
1090 if (
it->prepend()) {
1094 translatedRemoval.moveId = ++m_moveId;
1097 if (removeCount < removal->
count) {
1101 removal->index, removeCount, translatedRemoval.moveId));
1104 insertion->index, removeCount, translatedRemoval.moveId));
1107 removal->count -= removeCount;
1108 insertion->index += removeCount;
1109 insertion->count -= removeCount;
1113 removal->moveId = translatedRemoval.moveId;
1114 insertion->moveId = translatedRemoval.moveId;
1126 if (
it->previous != &m_ranges
1127 &&
it->previous->list ==
it->list
1128 &&
it->
end() == insertion->index
1130 it->previous->
count += removeCount;
1135 translatedRemoval.flags = 0;
1138 }
else if (
it->inCache()) {
1148 if (
it->previous != &m_ranges
1149 &&
it->previous->list ==
it->list
1151 it->previous->
count += removeCount;
1155 it.index[
Cache] += removeCount;
1158 translatedRemovals->
append(translatedRemoval);
1164 }
else if (relativeIndex <= 0) {
1167 it->index = removal->index;
1169 }
else if (relativeIndex < 0) {
1172 it->index -= itemsRemoved;
1174 if (
it->previous != &m_ranges
1175 &&
it->previous->list ==
it->list
1176 &&
it->previous->
end() ==
it->index
1179 it.decrementIndexes(
it->previous->
count);
1181 it->previous->flags =
it->flags;
1191 }
else if (!removed) {
1261 for (iterator
it(m_ranges.
next, 0,
Default, m_groupCount); *
it != &m_ranges; *
it =
it->next) {
1265 }
else if (!
it->inGroup()) {
1269 const int offset = change.index -
it->index;
1270 if (
offset + change.count > 0 && offset < it->
count) {
1274 Change translatedChange(
it, changeCount,
it->flags);
1275 for (
int i = 0;
i < m_groupCount; ++
i) {
1277 translatedChange.index[
i] += changeOffset;
1279 translatedChanges->
append(translatedChange);
1310 int removeCount = 0;
1312 if (
it == from &&
it != to) {
1315 }
else if (
it != from &&
it == to) {
1332 default:
return (
debug.nospace() <<
"Group" <<
int(
group)).space();
1346 <<
range.list) <<
' '
1347 <<
range.index <<
' '
1348 <<
range.count <<
' '
1349 << (
range.isUnresolved() ?
'U' :
'0')
1350 << (
range.append() ?
'A' :
'0')
1351 << (
range.prepend() ?
'P' :
'0');
1361 for (
int i =
count - 1;
i >= 0; --
i)
1372 (
debug.nospace() <<
"iterator(" <<
it.group).space() <<
"offset:" <<
it.offset;
1374 return ((
debug << **
it).nospace() <<
')').space();
1388 return (
debug <<
')').maybeSpace();
1431 debug.nospace() <<
"QQmlListCompositor(";
1434 (
debug <<
'\n').space();
1438 for (
int i = 0;
i <
list.m_groupCount; ++
i) {
1440 indexes[
i] +=
range->count;
1443 return (
debug <<
')').maybeSpace();
iterator insert(qsizetype i, parameter_type t)
void append(parameter_type t)
insert_iterator & operator+=(int difference)
void decrementIndexes(int difference)
int index[MaximumGroupCount]
void incrementIndexes(int difference)
iterator & operator+=(int difference)
The QQmlListCompositor class provides a lookup table for filtered, or re-ordered list indexes.
void listItemsChanged(void *list, int index, int count, QVector< Change > *changes)
Translates the positions of count changed items at index in a list.
iterator find(Group group, int index)
Returns an iterator representing the item at index in a group.
void listItemsInserted(void *list, int index, int count, QVector< Insert > *inserts)
Updates the contents of a compositor when count items are inserted into a list at index.
void listItemsMoved(void *list, int from, int to, int count, QVector< Remove > *removals, QVector< Insert > *inserts)
Updates the contents of a compositor when count items are removed from a list at index.
void transition(Group from, Group to, QVector< QQmlChangeSet::Change > *removes, QVector< QQmlChangeSet::Change > *inserts)
void append(void *list, int index, int count, uint flags, QVector< Insert > *inserts=nullptr)
Appends a range of count indexes starting at index from a list into a compositor with the given flags...
QQmlListCompositor()
Constructs an empty list compositor.
int count(Group group) const
Returns the number of items that belong to a group.
void clearFlags(Group fromGroup, int from, int count, Group group, uint flags, QVector< Remove > *removals=nullptr)
Clears the given flags flags on count items belonging to group starting at the position from.
~QQmlListCompositor()
Destroys a list compositor.
void listItemsRemoved(void *list, int index, int count, QVector< Remove > *removals)
Updates the contents of a compositor when count items are removed from a list at index.
bool verifyMoveTo(Group fromGroup, int from, Group toGroup, int to, int count, Group group) const
void move(Group fromGroup, int from, Group toGroup, int to, int count, Group group, QVector< Remove > *removals=nullptr, QVector< Insert > *inserts=nullptr)
insert_iterator findInsertPosition(Group group, int index)
Returns an iterator representing an insert position in front of the item at index in a group.
void setFlags(Group fromGroup, int from, int count, Group group, int flags, QVector< Insert > *inserts=nullptr)
Sets the given flags flags on count items belonging to group starting at the position identified by f...
void clear()
Clears the contents of a compositor.
void setGroupCount(int count)
Sets the number (count) of possible groups that items may belong to in a compositor.
void insert(Group group, int before, void *list, int index, int count, uint flags, QVector< Insert > *inserts=nullptr)
Inserts a range of count indexes starting at index from a list with the given flags into a group at i...
cache insert(employee->id(), employee)
QSet< QString >::iterator it
Combined button and popup list for selecting options.
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qMax(const T &a, const T &b)
static QOpenGLCompositor * compositor
GLenum GLenum GLsizei count
GLenum GLuint GLintptr offset
#define QT_QML_VERIFY_LISTCOMPOSITOR
static QDebug qt_print_change(QDebug debug, const char *name, const QQmlListCompositor::Change &change)
static void qt_print_indexes(QDebug &debug, int count, const int *indexes)
#define QT_QML_TRACE_LISTCOMPOSITOR(args)
QDebug operator<<(QDebug debug, const QQmlListCompositor::Group &group)
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
settings remove("monkey")
int index[MaximumGroupCount]