/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qqmllistcompositor_p.h"

#include <QtCore/qvarlengtharray.h>

//#define QT_QML_VERIFY_MINIMAL
//#define QT_QML_VERIFY_INTEGRITY

QT_BEGIN_NAMESPACE

/*!
    \class QQmlListCompositor
    \brief The QQmlListCompositor class provides a lookup table for filtered, or re-ordered list
    indexes.
    \internal

    QQmlListCompositor is intended as an aid for developing proxy models.  It doesn't however
    directly proxy a list or model, instead a range of indexes from one or many lists can be
    inserted into the compositor and then categorized and shuffled around and it will manage the
    task of translating from an index in the combined space into an index in a particular list.

    Within a compositor indexes are categorized into groups where a group is a sub-set of the
    total indexes referenced by the compositor, each with an address space ranging from 0 to
    the number of indexes in the group - 1.  Group memberships are independent of each other with
    the one exception that items always retain the same order so if an index is moved within a
    group, its position in other groups will change as well.

    The iterator classes encapsulate information about a specific position in a compositor group.
    This includes a source list, the index of an item within that list and the groups that item
    is a member of.  The iterator for a specific position in a group can be retrieved with the
    find() function and the addition and subtraction operators of the iterators can be used to
    navigate to adjacent items in the same group.

    Items can be added to the compositor with the append() and insert() functions, group
    membership can be changed with the setFlags() and clearFlags() functions, and the position
    of items in the compositor can be changed with the move() function.  Each of these functions
    optionally returns a list of the changes made to indexes within each group which can then
    be propagated to view so that it can correctly refresh its contents; e.g. 3 items
    removed at index 6, and 5 items inserted at index 1.  The notification changes are always
    ordered from the start of the list to the end and accumulate, so if 5 items are removed at
    index 4, one is skipped and then 3 move are removed, the changes returned are 5 items removed
    at index 4, followed by 3 items removed at index 4.

    When the contents of a source list change, the mappings within the compositor can be updated
    with the listItemsInserted(), listItemsRemoved(), listItemsMoved(), and listItemsChanged()
    functions.  Like the direct manipulation functions these too return a list of group indexes
    affected by the change.  If items are removed from a source list they are also removed from
    any groups they belong to with the one exception being items belonging to the \l Cache group.
    When items belonging to this group are removed the list, index, and other group membership
    information are discarded but Cache membership is retained until explicitly removed.  This
    allows the cache index to be retained until cached resources for that item are actually
    released.

    Internally the index mapping is stored as a list of Range objects, each has a list identifier,
    a start index, a count, and a set of flags which represent group membership and some other
    properties.  The group index of a range is the sum of all preceding ranges that are members of
    that group.  To avoid the inefficiency of iterating over potentially all ranges when looking
    for a specific index, each time a lookup is done the range and its indexes are cached and the
    next lookup is done relative to this.   This works out to near constant time in most relevant
    use cases because successive index lookups are most frequently adjacent.  The total number of
    ranges is often quite small, which helps as well. If there is a need for faster random access
    then a skip list like index may be an appropriate addition.

    \sa DelegateModel
*/

#ifdef QT_QML_VERIFY_MINIMAL
#define QT_QML_VERIFY_INTEGRITY
/*
    Diagnostic to verify there are no consecutive ranges, or that the compositor contains the
    most compact representation possible.

    Returns false and prints a warning if any range has a starting index equal to the end
    (index + count) index of the previous range, and both ranges also have the same flags and list
    property.

    If there are no consecutive ranges this will return true.
*/

static bool qt_verifyMinimal(
        const QQmlListCompositor::iterator &begin,
        const QQmlListCompositor::iterator &end)
{
    bool minimal = true;
    int index = 0;

    for (const QQmlListCompositor::Range *range = begin->next; range != *end; range = range->next, ++index) {
        if (range->previous->list == range->list
                && range->previous->flags == (range->flags & ~QQmlListCompositor::AppendFlag)
                && range->previous->end() == range->index) {
            qWarning() << index << "Consecutive ranges";
            qWarning() << *range->previous;
            qWarning() << *range;
            minimal = false;
        }
    }

    return minimal;
}

#endif

#ifdef QT_QML_VERIFY_INTEGRITY
static bool qt_printInfo(const QQmlListCompositor &compositor)
{
    qWarning() << compositor;
    return true;
}

/*
    Diagnostic to verify the integrity of a compositor.

    Per range this verifies there are no invalid range combinations, that non-append ranges have
    positive non-zero counts, and that list ranges have non-negative indexes.

    Accumulatively this verifies that the cached total group counts match the sum of counts
    of member ranges.
*/

static bool qt_verifyIntegrity(
        const QQmlListCompositor::iterator &begin,
        const QQmlListCompositor::iterator &end,
        const QQmlListCompositor::iterator &cachedIt)
{
    bool valid = true;

    int index = 0;
    QQmlListCompositor::iterator it;
    for (it = begin; *it != *end; *it = it->next) {
        if (it->count == 0 && !it->append()) {
            qWarning() << index << "Empty non-append range";
            valid = false;
        }
        if (it->count < 0) {
            qWarning() << index << "Negative count";
            valid = false;
        }
        if (it->list && it->flags != QQmlListCompositor::CacheFlag && it->index < 0) {
            qWarning() << index <<"Negative index";
            valid = false;
        }
        if (it->previous->next != it.range) {
            qWarning() << index << "broken list: it->previous->next != it.range";
            valid = false;
        }
        if (it->next->previous != it.range) {
            qWarning() << index << "broken list: it->next->previous != it.range";
            valid = false;
        }
        if (*it == *cachedIt) {
            for (int i = 0; i < end.groupCount; ++i) {
                int groupIndex = it.index[i];
                if (cachedIt->flags & (1 << i))
                    groupIndex += cachedIt.offset;
                if (groupIndex != cachedIt.index[i]) {
                    qWarning() << index
                            << "invalid cached index"
                            << QQmlListCompositor::Group(i)
                            << "Expected:"
                            << groupIndex
                            << "Actual"
                            << cachedIt.index[i]
                            << cachedIt;
                    valid = false;
                }
            }
        }
        it.incrementIndexes(it->count);
        ++index;
    }

    for (int i = 0; i < end.groupCount; ++i) {
        if (end.index[i] != it.index[i]) {
            qWarning() << "Group" << i << "count invalid. Expected:" << end.index[i] << "Actual:" << it.index[i];
            valid = false;
        }
    }
    return valid;
}
#endif

#if defined(QT_QML_VERIFY_MINIMAL)
#   define QT_QML_VERIFY_LISTCOMPOSITOR Q_ASSERT(!(!(qt_verifyIntegrity(iterator(m_ranges.next, 0, Default, m_groupCount), m_end, m_cacheIt) \
            && qt_verifyMinimal(iterator(m_ranges.next, 0, Default, m_groupCount), m_end)) \
            && qt_printInfo(*this)));
#elif defined(QT_QML_VERIFY_INTEGRITY)
#   define QT_QML_VERIFY_LISTCOMPOSITOR Q_ASSERT(!(!qt_verifyIntegrity(iterator(m_ranges.next, 0, Default, m_groupCount), m_end, m_cacheIt) \
            && qt_printInfo(*this)));
#else
#   define QT_QML_VERIFY_LISTCOMPOSITOR
#endif

//#define QT_QML_TRACE_LISTCOMPOSITOR(args) qDebug() << m_end.index[1] << m_end.index[0] << Q_FUNC_INFO args;
#define QT_QML_TRACE_LISTCOMPOSITOR(args)

QQmlListCompositor::iterator &QQmlListCompositor::iterator::operator +=(int difference)
{
    // Update all indexes to the start of the range.
    decrementIndexes(offset);

    // If the iterator group isn't a member of the current range ignore the current offset.
    if (!(range->flags & groupFlag))
        offset = 0;

    offset += difference;

    // Iterate backwards looking for a range with a positive offset.
    while (offset <= 0 && range->previous->flags) {
        range = range->previous;
        if (range->flags & groupFlag)
            offset += range->count;
        decrementIndexes(range->count);
    }

    // Iterate forwards looking for the first range which contains both the offset and the
    // iterator group.
    while (range->flags && (offset >= range->count || !(range->flags & groupFlag))) {
        if (range->flags & groupFlag)
            offset -= range->count;
        incrementIndexes(range->count);
        range = range->next;
    }

    // Update all the indexes to inclue the remaining offset.
    incrementIndexes(offset);

    return *this;
}

QQmlListCompositor::insert_iterator &QQmlListCompositor::insert_iterator::operator +=(int difference)
{
    iterator::operator +=(difference);

    // If the previous range contains the append flag move the iterator to the tail of the previous
    // range so that appended appear after the insert position.
    if (offset == 0 && range->previous->append()) {
        range = range->previous;
        offset = range->inGroup() ? range->count : 0;
    }

    return *this;
}


/*!
    Constructs an empty list compositor.
*/

QQmlListCompositor::QQmlListCompositor()
    : m_end(m_ranges.next, 0, Default, 2)
    , m_cacheIt(m_end)
    , m_groupCount(2)
    , m_defaultFlags(PrependFlag | DefaultFlag)
    , m_removeFlags(AppendFlag | PrependFlag | GroupMask)
    , m_moveId(0)
{
}

/*!
    Destroys a list compositor.
*/

QQmlListCompositor::~QQmlListCompositor()
{
    for (Range *next, *range = m_ranges.next; range != &m_ranges; range = next) {
        next = range->next;
        delete range;
    }
}

/*!
    Inserts a range with the given source \a list, start \a index, \a count and \a flags, in front
    of the existing range \a before.
*/

inline QQmlListCompositor::Range *QQmlListCompositor::insert(
        Range *before, void *list, int index, int count, uint flags)
{
    return new Range(before, list, index, count, flags);
}

/*!
    Erases a \a range from the compositor.

    Returns a pointer to the next range in the compositor.
*/

inline QQmlListCompositor::Range *QQmlListCompositor::erase(
        Range *range)
{
    Range *next = range->next;
    next->previous = range->previous;
    next->previous->next = range->next;
    delete range;
    return next;
}

/*!
    Sets the number (\a count) of possible groups that items may belong to in a compositor.
*/

void QQmlListCompositor::setGroupCount(int count)
{
    m_groupCount = count;
    m_end = iterator(&m_ranges, 0, Default, m_groupCount);
    m_cacheIt = m_end;
}

/*!
    Returns the number of items that belong to a \a group.
*/

int QQmlListCompositor::count(Group group) const
{
    return m_end.index[group];
}

/*!
    Returns an iterator representing the item at \a index in a \a group.

    The index must be between 0 and count(group) - 1.
*/

QQmlListCompositor::iterator QQmlListCompositor::find(Group group, int index)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< group << index)
    Q_ASSERT(index >=0 && index < count(group));
    if (m_cacheIt == m_end) {
        m_cacheIt = iterator(m_ranges.next, 0, group, m_groupCount);
        m_cacheIt += index;
    } else {
        const int offset = index - m_cacheIt.index[group];
        m_cacheIt.setGroup(group);
        m_cacheIt += offset;
    }
    Q_ASSERT(m_cacheIt.index[group] == index);
    Q_ASSERT(m_cacheIt->inGroup(group));
    QT_QML_VERIFY_LISTCOMPOSITOR
    return m_cacheIt;
}

/*!
    Returns an iterator representing the item at \a index in a \a group.

    The index must be between 0 and count(group) - 1.
*/

QQmlListCompositor::iterator QQmlListCompositor::find(Group group, int index) const
{
    return const_cast<QQmlListCompositor *>(this)->find(group, index);
}

/*!
    Returns an iterator representing an insert position in front of the item at \a index in a
    \a group.

    The iterator for an insert position can sometimes resolve to a different Range than a regular
    iterator.  This is because when items are inserted on a boundary between Ranges, if the first
    range has the Append flag set then the items should be inserted into that range to ensure
    that the append position for the existing range remains after the insert position.

    The index must be between 0 and count(group) - 1.
*/

QQmlListCompositor::insert_iterator QQmlListCompositor::findInsertPosition(Group group, int index)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< group << index)
    Q_ASSERT(index >=0 && index <= count(group));
    insert_iterator it;
    if (m_cacheIt == m_end) {
        it = iterator(m_ranges.next, 0, group, m_groupCount);
        it += index;
    } else {
        const int offset = index - m_cacheIt.index[group];
        it = m_cacheIt;
        it.setGroup(group);
        it += offset;
    }
    Q_ASSERT(it.index[group] == index);
    return it;
}

/*!
    Appends a range of \a count indexes starting at \a index from a \a list into a compositor
    with the given \a flags.

    If supplied the \a inserts list will be populated with the positions of the inserted items
    in each group.
*/

void QQmlListCompositor::append(
        void *list, int index, int count, uint flags, QVector<Insert> *inserts)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count << flags)
    insert(m_end, list, index, count, flags, inserts);
}

/*!
    Inserts a range of \a count indexes starting at \a index from a \a list with the given \a flags
    into a \a group at index \a before.

    If supplied the \a inserts list will be populated with the positions of items inserted into
    each group.
*/

void QQmlListCompositor::insert(
        Group group, int before, void *list, int index, int count, uint flags, QVector<Insert> *inserts)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< group << before << list << index << count << flags)
    insert(findInsertPosition(group, before), list, index, count, flags, inserts);
}

/*!
    Inserts a range of \a count indexes starting at \a index from a \a list with the given \a flags
    into a compositor at position \a before.

    If supplied the \a inserts list will be populated with the positions of items inserted into
    each group.
*/

QQmlListCompositor::iterator QQmlListCompositor::insert(
        iterator before, void *list, int index, int count, uint flags, QVector<Insert> *inserts)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< before << list << index << count << flags)
    if (inserts) {
        inserts->append(Insert(before, count, flags & GroupMask));
    }
    if (before.offset > 0) {
        // Inserting into the middle of a range.  Split it two and update the iterator so it's
        // positioned at the start of the second half.
        *before = insert(
                *before, before->list, before->index, before.offset, before->flags & ~AppendFlag)->next;
        before->index += before.offset;
        before->count -= before.offset;
        before.offset = 0;
    }


    if (!(flags & AppendFlag) && *before != m_ranges.next
            && before->previous->list == list
            && before->previous->flags == flags
            && (!list || before->previous->end() == index)) {
        // The insert arguments represent a continuation of the previous range so increment
        // its count instead of inserting a new range.
        before->previous->count += count;
        before.incrementIndexes(count, flags);
    } else {
        *before = insert(*before, list, index, count, flags);
        before.offset = 0;
    }

    if (!(flags & AppendFlag) && before->next != &m_ranges
            && before->list == before->next->list
            && before->flags == before->next->flags
            && (!list || before->end() == before->next->index)) {
        // The current range and the next are continuous so add their counts and delete one.
        before->next->index = before->index;
        before->next->count += before->count;
        *before = erase(*before);
    }

    m_end.incrementIndexes(count, flags);
    m_cacheIt = before;
    QT_QML_VERIFY_LISTCOMPOSITOR
    return before;
}

/*!
    Sets the given flags \a flags on \a count items belonging to \a group starting at the position
    identified by \a fromGroup and the index \a from.

    If supplied the \a inserts list will be populated with insert notifications for affected groups.
*/

void QQmlListCompositor::setFlags(
        Group fromGroup, int from, int count, Group group, int flags, QVector<Insert> *inserts)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< fromGroup << from << count << group << flags)
    setFlags(find(fromGroup, from), count, group, flags, inserts);
}

/*!
    Sets the given flags \a flags on \a count items belonging to \a group starting at the position
    \a from.

    If supplied the \a inserts list will be populated with insert notifications for affected groups.
*/

void QQmlListCompositor::setFlags(
        iterator from, int count, Group group, uint flags, QVector<Insert> *inserts)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< from << count << flags)
    if (!flags || !count)
        return;

    if (from != group) {
        // Skip to the next full range if the start one is not a member of the target group.
        from.incrementIndexes(from->count - from.offset);
        from.offset = 0;
        *from = from->next;
    } else if (from.offset > 0) {
        // If the start position is mid range split off the portion unaffected.
        *from = insert(*from, from->list, from->index, from.offset, from->flags & ~AppendFlag)->next;
        from->index += from.offset;
        from->count -= from.offset;
        from.offset = 0;
    }

    for (; count > 0; *from = from->next) {
        if (from != from.group) {
            // Skip ranges that are not members of the target group.
            from.incrementIndexes(from->count);
            continue;
        }
        // Find the number of items affected in the current range.
        const int difference = qMin(count, from->count);
        count -= difference;

        // Determine the actual changes made to the range and increment counts accordingly.
        const uint insertFlags = ~from->flags & flags;
        const uint setFlags = (from->flags | flags) & ~AppendFlag;
        if (insertFlags && inserts)
            inserts->append(Insert(from, difference, insertFlags | (from->flags & CacheFlag)));
        m_end.incrementIndexes(difference, insertFlags);
        from.incrementIndexes(difference, setFlags);

        if (from->previous != &m_ranges
                && from->previous->list == from->list
                && (!from->list || from->previous->end() == from->index)
                && from->previous->flags == setFlags) {
            // If the additional flags make the current range a continuation of the previous
            // then move the affected items over to the previous range.
            from->previous->count += difference;
            from->index += difference;
            from->count -= difference;
            if (from->count == 0) {
                // Delete the current range if it is now empty, preserving the append flag
                // in the previous range.
                if (from->append())
                    from->previous->flags |= AppendFlag;
                *from = erase(*from)->previous;
                continue;
            } else {
                break;
            }
        } else if (!insertFlags) {
            // No new flags, so roll onto the next range.
            from.incrementIndexes(from->count - difference);
            continue;
        } else if (difference < from->count) {
            // Create a new range with the updated flags, and remove the affected items
            // from the current range.
            *from = insert(*from, from->list, from->index, difference, setFlags)->next;
            from->index += difference;
            from->count -= difference;
        } else {
            // The whole range is affected so simply update the flags.
            from->flags |= flags;
            continue;
        }
        from.incrementIndexes(from->count);
    }

    if (from->previous != &m_ranges
            && from->previous->list == from->list
            && (!from->list || from->previous->end() == from->index)
            && from->previous->flags == (from->flags & ~AppendFlag)) {
        // If the following range is now a continuation, merge it with its previous range.
        from.offset = from->previous->count;
        from->previous->count += from->count;
        from->previous->flags = from->flags;
        *from = erase(*from)->previous;
    }
    m_cacheIt = from;
    QT_QML_VERIFY_LISTCOMPOSITOR
}

/*!
    Clears the given flags \a flags on \a count items belonging to \a group starting at the position
    \a from.

    If supplied the \a removes list will be populated with remove notifications for affected groups.
*/

void QQmlListCompositor::clearFlags(
        Group fromGroup, int from, int count, Group group, uint flags, QVector<Remove> *removes)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< fromGroup << from << count << group << flags)
    clearFlags(find(fromGroup, from), count, group, flags, removes);
}

/*!
    Clears the given flags \a flags on \a count items belonging to \a group starting at the position
    identified by \a fromGroup and the index \a from.

    If supplied the \a removes list will be populated with remove notifications for affected groups.
*/

void QQmlListCompositor::clearFlags(
        iterator from, int count, Group group, uint flags, QVector<Remove> *removes)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< from << count << flags)
    if (!flags || !count)
        return;

    const bool clearCache = flags & CacheFlag;

    if (from != group) {
        // Skip to the next full range if the start one is not a member of the target group.
        from.incrementIndexes(from->count - from.offset);
        from.offset = 0;
        *from = from->next;
    } else if (from.offset > 0) {
        // If the start position is mid range split off the portion unaffected.
        *from = insert(*from, from->list, from->index, from.offset, from->flags & ~AppendFlag)->next;
        from->index += from.offset;
        from->count -= from.offset;
        from.offset = 0;
    }

    for (; count > 0; *from = from->next) {
        if (from != group) {
            // Skip ranges that are not members of the target group.
            from.incrementIndexes(from->count);
            continue;
        }
        // Find the number of items affected in the current range.
        const int difference = qMin(count, from->count);
        count -= difference;


        // Determine the actual changes made to the range and decrement counts accordingly.
        const uint removeFlags = from->flags & flags & ~(AppendFlag | PrependFlag);
        const uint clearedFlags = from->flags & ~(flags | AppendFlag | UnresolvedFlag);
        if (removeFlags && removes) {
            const int maskedFlags = clearCache
                    ? (removeFlags & ~CacheFlag)
                    : (removeFlags | (from->flags & CacheFlag));
            if (maskedFlags)
                removes->append(Remove(from, difference, maskedFlags));
        }
        m_end.decrementIndexes(difference, removeFlags);
        from.incrementIndexes(difference, clearedFlags);

        if (from->previous != &m_ranges
                && from->previous->list == from->list
                && (!from->list || clearedFlags == CacheFlag || from->previous->end() == from->index)
                && from->previous->flags == clearedFlags) {
            // If the removed flags make the current range a continuation of the previous
            // then move the affected items over to the previous range.
            from->previous->count += difference;
            from->index += difference;
            from->count -= difference;
            if (from->count == 0) {
                // Delete the current range if it is now empty, preserving the append flag
                if (from->append())
                    from->previous->flags |= AppendFlag;
                *from = erase(*from)->previous;
            } else {
                from.incrementIndexes(from->count);
            }
        } else if (difference < from->count) {
            // Create a new range with the reduced flags, and remove the affected items from
            // the current range.
            if (clearedFlags)
                *from = insert(*from, from->list, from->index, difference, clearedFlags)->next;
            from->index += difference;
            from->count -= difference;
            from.incrementIndexes(from->count);
        } else if (clearedFlags) {
            // The whole range is affected so simply update the flags.
            from->flags &= ~flags;
        } else {
            // All flags have been removed from the range so remove it.
            *from = erase(*from)->previous;
        }
    }

    if (*from != &m_ranges && from->previous != &m_ranges
            && from->previous->list == from->list
            && (!from->list || from->previous->end() == from->index)
            && from->previous->flags == (from->flags & ~AppendFlag)) {
        // If the following range is now a continuation, merge it with its previous range.
        from.offset = from->previous->count;
        from->previous->count += from->count;
        from->previous->flags = from->flags;
        *from = erase(*from)->previous;
    }
    m_cacheIt = from;
    QT_QML_VERIFY_LISTCOMPOSITOR
}

bool QQmlListCompositor::verifyMoveTo(
        Group fromGroup, int from, Group toGroup, int to, int count, Group group) const
{
    if (group != toGroup) {
        // determine how many items from the destination group intersect with the source group.
        iterator fromIt = find(fromGroup, from);

        int intersectingCount = 0;

        for (; count > 0; *fromIt = fromIt->next) {
            if (*fromIt == &m_ranges)
                return false;
            if (!fromIt->inGroup(group))
                continue;
            if (fromIt->inGroup(toGroup))
                intersectingCount += qMin(count, fromIt->count - fromIt.offset);
            count -= fromIt->count - fromIt.offset;
            fromIt.offset = 0;
        }
        count = intersectingCount;
    }

    return to >= 0 && to + count <= m_end.index[toGroup];
}

/*!
    \internal

    Moves \a count items belonging to \a moveGroup from the index \a from in \a fromGroup
    to the index \a to in \a toGroup.

    If \a removes and \a inserts are not null they will be populated with per group notifications
    of the items moved.
 */

void QQmlListCompositor::move(
        Group fromGroup,
        int from,
        Group toGroup,
        int to,
        int count,
        Group moveGroup,
        QVector<Remove> *removes,
        QVector<Insert> *inserts)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< fromGroup << from << toGroup << to << count)
    Q_ASSERT(count > 0);
    Q_ASSERT(from >=0);
    Q_ASSERT(verifyMoveTo(fromGroup, from, toGroup, to, count, moveGroup));

    // Find the position of the first item to move.
    iterator fromIt = find(fromGroup, from);

    if (fromIt != moveGroup) {
        // If the range at the from index doesn't contain items from the move group; skip
        // to the next range.
        fromIt.incrementIndexes(fromIt->count - fromIt.offset);
        fromIt.offset = 0;
        *fromIt = fromIt->next;
    } else if (fromIt.offset > 0) {
        // If the range at the from index contains items from the move group and the index isn't
        // at the start of the range; split the range at the index and move the iterator to start
        // of the second range.
        *fromIt = insert(
                *fromIt, fromIt->list, fromIt->index, fromIt.offset, fromIt->flags & ~AppendFlag)->next;
        fromIt->index += fromIt.offset;
        fromIt->count -= fromIt.offset;
        fromIt.offset = 0;
    }

    // Remove count items belonging to the move group from the list.
    Range movedFlags;
    for (int moveId = m_moveId; count > 0;) {
        if (fromIt != moveGroup) {
            // Skip ranges not containing items from the move group.
            fromIt.incrementIndexes(fromIt->count);
            *fromIt = fromIt->next;
            continue;
        }
        int difference = qMin(count, fromIt->count);

        // Create a new static range containing the moved items from an existing range.
        new Range(
                &movedFlags,
                fromIt->list,
                fromIt->index,
                difference,
                fromIt->flags & ~(PrependFlag | AppendFlag));
        // Remove moved items from the count, the existing range, and a remove notification.
        if (removes)
            removes->append(Remove(fromIt, difference, fromIt->flags, ++moveId));
        count -= difference;
        fromIt->count -= difference;

        // If the existing range contains the prepend flag replace the removed items with
        // a placeholder range for new items inserted into the source model.
        int removeIndex = fromIt->index;
        if (fromIt->prepend()
                && fromIt->previous != &m_ranges
                && fromIt->previous->flags == PrependFlag
                && fromIt->previous->list == fromIt->list
                && fromIt->previous->end() == fromIt->index) {
            // Grow the previous range instead of creating a new one if possible.
            fromIt->previous->count += difference;
        } else if (fromIt->prepend()) {
            *fromIt = insert(*fromIt, fromIt->list, removeIndex, difference, PrependFlag)->next;
        }
        fromIt->index += difference;

        if (fromIt->count == 0) {
            // If the existing range has no items remaining; remove it from the list.
            if (fromIt->append())
                fromIt->previous->flags |= AppendFlag;
            *fromIt = erase(*fromIt);

            // If the ranges before and after the removed range can be joined, do so.
            if (*fromIt != m_ranges.next && fromIt->flags == PrependFlag
                    && fromIt->previous != &m_ranges
                    && fromIt->previous->flags == PrependFlag
                    && fromIt->previous->list == fromIt->list
                    && fromIt->previous->end() == fromIt->index) {
                fromIt.incrementIndexes(fromIt->count);
                fromIt->previous->count += fromIt->count;
                *fromIt = erase(*fromIt);
            }
        } else if (count > 0) {
            *fromIt = fromIt->next;
        }
    }

    // Try and join the range following the removed items to the range preceding it.
    if (*fromIt != m_ranges.next
            && *fromIt != &m_ranges
            && fromIt->previous->list == fromIt->list
            && (!fromIt->list || fromIt->previous->end() == fromIt->index)
            && fromIt->previous->flags == (fromIt->flags & ~AppendFlag)) {
        if (fromIt == fromIt.group)
            fromIt.offset = fromIt->previous->count;
        fromIt.offset = fromIt->previous->count;
        fromIt->previous->count += fromIt->count;
        fromIt->previous->flags = fromIt->flags;
        *fromIt = erase(*fromIt)->previous;
    }

    // Find the destination position of the move.
    insert_iterator toIt = fromIt;
    toIt.setGroup(toGroup);

    const int difference = to - toIt.index[toGroup];
    toIt += difference;

    // If the insert position is part way through a range; split it and move the iterator to the
    // start of the second range.
    if (toIt.offset > 0) {
        *toIt = insert(*toIt, toIt->list, toIt->index, toIt.offset, toIt->flags & ~AppendFlag)->next;
        toIt->index += toIt.offset;
        toIt->count -= toIt.offset;
        toIt.offset = 0;
    }

    // Insert the moved ranges before the insert iterator, growing the previous range if that
    // is an option.
    for (Range *range = movedFlags.previous; range != &movedFlags; range = range->previous) {
        if (*toIt != &m_ranges
                && range->list == toIt->list
                && (!range->list || range->end() == toIt->index)
                && range->flags == (toIt->flags & ~AppendFlag)) {
            toIt->index -= range->count;
            toIt->count += range->count;
        } else {
            *toIt = insert(*toIt, range->list, range->index, range->count, range->flags);
        }
    }

    // Try and join the range after the inserted ranges to the last range inserted.
    if (*toIt != m_ranges.next
            && toIt->previous->list == toIt->list
            && (!toIt->list || (toIt->previous->end() == toIt->index && toIt->previous->flags == (toIt->flags & ~AppendFlag)))) {
        toIt.offset = toIt->previous->count;
        toIt->previous->count += toIt->count;
        toIt->previous->flags = toIt->flags;
        *toIt = erase(*toIt)->previous;
    }
    // Create insert notification for the ranges moved.
    Insert insert(toIt, 0, 0, 0);
    for (Range *next, *range = movedFlags.next; range != &movedFlags; range = next) {
        insert.count = range->count;
        insert.flags = range->flags;
        if (inserts) {
            insert.moveId = ++m_moveId;
            inserts->append(insert);
        }
        for (int i = 0; i < m_groupCount; ++i) {
            if (insert.inGroup(i))
                insert.index[i] += range->count;
        }

        next = range->next;
        delete range;
    }

    m_cacheIt = toIt;

    QT_QML_VERIFY_LISTCOMPOSITOR
}

/*!
    Clears the contents of a compositor.
*/

void QQmlListCompositor::clear()
{
    QT_QML_TRACE_LISTCOMPOSITOR("")
    for (Range *range = m_ranges.next; range != &m_ranges; range = erase(range)) {}
    m_end = iterator(m_ranges.next, 0, Default, m_groupCount);
    m_cacheIt = m_end;
}

void QQmlListCompositor::listItemsInserted(
        QVector<Insert> *translatedInsertions,
        void *list,
        const QVector<QQmlChangeSet::Change> &insertions,
        const QVector<MovedFlags> *movedFlags)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< list << insertions)
    for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
        if (it->list != list || it->flags == CacheFlag) {
            // Skip ranges that don't reference list.
            it.incrementIndexes(it->count);
            continue;
        } else if (it->flags & MovedFlag) {
            // Skip ranges that were already moved in listItemsRemoved.
            it->flags &= ~MovedFlag;
            it.incrementIndexes(it->count);
            continue;
        }
        for (const QQmlChangeSet::Change &insertion : insertions) {
            int offset = insertion.index - it->index;
            if ((offset > 0 && offset < it->count)
                    || (offset == 0 && it->prepend())
                    || (offset == it->count && it->append())) {
                // The insert index is within the current range.
                if (it->prepend()) {
                    // The range has the prepend flag set so we insert new items into the range.
                    uint flags = m_defaultFlags;
                    if (insertion.isMove()) {
                        // If the insert was part of a move replace the default flags with
                        // the flags from the source range.
                        for (QVector<MovedFlags>::const_iterator move = movedFlags->begin();
                                move != movedFlags->end();
                                ++move) {
                            if (move->moveId == insertion.moveId) {
                                flags = move->flags;
                                break;
                            }
                        }
                    }
                    if (flags & ~(AppendFlag | PrependFlag)) {
                        // If any items are added to groups append an insert notification.
                        Insert translatedInsert(it, insertion.count, flags, insertion.moveId);
                        for (int i = 0; i < m_groupCount; ++i) {
                            if (it->inGroup(i))
                                translatedInsert.index[i] += offset;
                        }
                        translatedInsertions->append(translatedInsert);
                    }
                    if ((it->flags & ~AppendFlag) == flags) {
                        // Accumulate items on the current range it its flags are the same as
                        // the insert flags.
                        it->count += insertion.count;
                    } else if (offset == 0
                            && it->previous != &m_ranges
                            && it->previous->list == list
                            && it->previous->end() == insertion.index
                            && it->previous->flags == flags) {
                        // Attempt to append to the previous range if the insert position is at
                        // the start of the current range.
                        it->previous->count += insertion.count;
                        it->index += insertion.count;
                        it.incrementIndexes(insertion.count);
                    } else {
                        if (offset > 0) {
                            // Divide the current range at the insert position.
                            it.incrementIndexes(offset);
                            *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next;
                        }
                        // Insert a new range, and increment the start index of the current range.
                        *it = insert(*it, it->list, insertion.index, insertion.count, flags)->next;
                        it.incrementIndexes(insertion.count, flags);
                        it->index += offset + insertion.count;
                        it->count -= offset;
                    }
                    m_end.incrementIndexes(insertion.count, flags);
                } else {
                    // The range doesn't have the prepend flag set so split the range into parts;
                    // one before the insert position and one after the last inserted item.
                    if (offset > 0) {
                        *it = insert(*it, it->list, it->index, offset, it->flags)->next;
                        it->index += offset;
                        it->count -= offset;
                    }
                    it->index += insertion.count;
                }
            } else if (offset <= 0) {
                // The insert position was before the current range so increment the start index.
                it->index += insertion.count;
            }
        }
        it.incrementIndexes(it->count);
    }
    m_cacheIt = m_end;
    QT_QML_VERIFY_LISTCOMPOSITOR
}

/*!
    Updates the contents of a compositor when \a count items are inserted into a \a list at
    \a index.

    This corrects the indexes of each range for that list in the compositor, splitting the range
    in two if the insert index is in the middle of that range.  If a range at the insert position
    has the Prepend flag set then a new range will be inserted at that position with the groups
    specified in defaultGroups().  If the insert index corresponds to the end of a range with
    the Append flag set a new range will be inserted before the end of the append range.

    The \a translatedInsertions list is populated with insert notifications for affected
    groups.
*/

void QQmlListCompositor::listItemsInserted(
        void *list, int index, int count, QVector<Insert> *translatedInsertions)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count)
    Q_ASSERT(count > 0);

    QVector<QQmlChangeSet::Change> insertions;
    insertions.append(QQmlChangeSet::Change(index, count));

    listItemsInserted(translatedInsertions, list, insertions);
}

void QQmlListCompositor::listItemsRemoved(
        QVector<Remove> *translatedRemovals,
        void *list,
        QVector<QQmlChangeSet::Change> *removals,
        QVector<QQmlChangeSet::Change> *insertions,
        QVector<MovedFlags> *movedFlags)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< list << *removals)

    for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
        if (it->list != list || it->flags == CacheFlag) {
            // Skip ranges that don't reference list.
            it.incrementIndexes(it->count);
            continue;
        }
        bool removed = false;
        for (QVector<QQmlChangeSet::Change>::iterator removal = removals->begin();
                !removed && removal != removals->end();
                ++removal) {
            int relativeIndex = removal->index - it->index;
            int itemsRemoved = removal->count;
            if (relativeIndex + removal->count > 0 && relativeIndex < it->count) {
                // If the current range intersects the remove; remove the intersecting items.
                const int offset = qMax(0, relativeIndex);
                int removeCount = qMin(it->count, relativeIndex + removal->count) - offset;
                it->count -= removeCount;
                int removeFlags = it->flags & m_removeFlags;
                Remove translatedRemoval(it, removeCount, it->flags);
                for (int i = 0; i < m_groupCount; ++i) {
                    if (it->inGroup(i))
                        translatedRemoval.index[i] += offset;
                }
                if (removal->isMove()) {
                    // If the removal was part of a move find the corresponding insert.
                    QVector<QQmlChangeSet::Change>::iterator insertion = insertions->begin();
                    for (; insertion != insertions->end() && insertion->moveId != removal->moveId;
                            ++insertion) {}
                    Q_ASSERT(insertion != insertions->end());
                    Q_ASSERT(insertion->count == removal->count);

                    if (relativeIndex < 0) {
                        // If the remove started before the current range, split it and the
                        // corresponding insert so we're only working with intersecting part.
                        int splitMoveId = ++m_moveId;
                        removal = removals->insert(removal, QQmlChangeSet::Change(
                                removal->index, -relativeIndex, splitMoveId));
                        ++removal;
                        removal->count -= -relativeIndex;
                        insertion = insertions->insert(insertion, QQmlChangeSet::Change(
                                insertion->index, -relativeIndex, splitMoveId));
                        ++insertion;
                        insertion->index += -relativeIndex;
                        insertion->count -= -relativeIndex;
                    }

                    if (it->prepend()) {
                        // If the current range has the prepend flag preserve its flags to transfer
                        // to its new location.
                        removeFlags |= it->flags & CacheFlag;
                        translatedRemoval.moveId = ++m_moveId;
                        movedFlags->append(MovedFlags(m_moveId, it->flags & ~AppendFlag));

                        if (removeCount < removal->count) {
                            // If the remove doesn't encompass all of the current range,
                            // split it and the corresponding insert.
                            removal = removals->insert(removal, QQmlChangeSet::Change(
                                    removal->index, removeCount, translatedRemoval.moveId));
                            ++removal;
                            insertion = insertions->insert(insertion, QQmlChangeSet::Change(
                                    insertion->index, removeCount, translatedRemoval.moveId));
                            ++insertion;

                            removal->count -= removeCount;
                            insertion->index += removeCount;
                            insertion->count -= removeCount;
                        } else {
                            // If there's no need to split the move simply replace its moveId
                            // with that of the translated move.
                            removal->moveId = translatedRemoval.moveId;
                            insertion->moveId = translatedRemoval.moveId;
                        }
                    } else {
                        // If the current range doesn't have prepend flags then insert a new range
                        // with list indexes from the corresponding insert location.  The MoveFlag
                        // is to notify listItemsInserted that it can skip evaluation of that range.
                        if (offset > 0) {
                            *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next;
                            it->index += offset;
                            it->count -= offset;
                            it.incrementIndexes(offset);
                        }
                        if (it->previous != &m_ranges
                                && it->previous->list == it->list
                                && it->end() == insertion->index
                                && it->previous->flags == (it->flags | MovedFlag)) {
                            it->previous->count += removeCount;
                        } else {
                            *it = insert(*it, it->list, insertion->index, removeCount, it->flags | MovedFlag)->next;
                        }
                        // Clear the changed flags as the item hasn't been removed.
                        translatedRemoval.flags = 0;
                        removeFlags = 0;
                    }
                } else if (it->inCache()) {
                    // If not moving and the current range has the cache flag, insert a new range
                    // with just the cache flag set to retain caching information for the removed
                    // range.
                    if (offset > 0) {
                        *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next;
                        it->index += offset;
                        it->count -= offset;
                        it.incrementIndexes(offset);
                    }
                    if (it->previous != &m_ranges
                            && it->previous->list == it->list
                            && it->previous->flags == CacheFlag) {
                        it->previous->count += removeCount;
                    } else {
                        *it = insert(*it, it->list, -1, removeCount, CacheFlag)->next;
                    }
                    it.index[Cache] += removeCount;
                }
                if (removeFlags & GroupMask)
                    translatedRemovals->append(translatedRemoval);
                m_end.decrementIndexes(removeCount, removeFlags);
                if (it->count == 0 && !it->append()) {
                    // Erase empty non-append ranges.
                    *it = erase(*it)->previous;
                    removed = true;
                } else if (relativeIndex <= 0) {
                    // If the remove started before the current range move the start index of
                    // the range to the remove index.
                    it->index = removal->index;
                }
            } else if (relativeIndex < 0) {
                // If the remove was before the current range decrement the start index by the
                // number of items removed.
                it->index -= itemsRemoved;

                if (it->previous != &m_ranges
                        && it->previous->list == it->list
                        && it->previous->end() == it->index
                        && it->previous->flags == (it->flags & ~AppendFlag)) {
                    // Compress ranges made continuous by the removal of separating ranges.
                    it.decrementIndexes(it->previous->count);
                    it->previous->count += it->count;
                    it->previous->flags = it->flags;
                    *it = erase(*it)->previous;
                }
            }
        }
        if (it->flags == CacheFlag && it->next->flags == CacheFlag && it->next->list == it->list) {
            // Compress consecutive cache only ranges.
            it.index[Cache] += it->next->count;
            it->count += it->next->count;
            erase(it->next);
        } else if (!removed) {
            it.incrementIndexes(it->count);
        }
    }
    m_cacheIt = m_end;
    QT_QML_VERIFY_LISTCOMPOSITOR
}


/*!
    Updates the contents of a compositor when \a count items are removed from a \a list at
    \a index.

    Ranges that intersect the specified range are removed from the compositor and the indexes of
    ranges after index + count are updated.

    The \a translatedRemovals list is populated with remove notifications for the affected
    groups.
*/


void QQmlListCompositor::listItemsRemoved(
        void *list, int index, int count, QVector<Remove> *translatedRemovals)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count)
    Q_ASSERT(count >= 0);

    QVector<QQmlChangeSet::Change> removals;
    removals.append(QQmlChangeSet::Change(index, count));
    listItemsRemoved(translatedRemovals, list, &removals, nullptr, nullptr);
}

/*!
    Updates the contents of a compositor when \a count items are removed from a \a list at
    \a index.

    Ranges that intersect the specified range are removed from the compositor and the indexes of
    ranges after index + count are updated.

    The \a translatedRemovals and translatedInserts lists are populated with move
    notifications for the affected groups.
*/

void QQmlListCompositor::listItemsMoved(
        void *list,
        int from,
        int to,
        int count,
        QVector<Remove> *translatedRemovals,
        QVector<Insert> *translatedInsertions)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< list << from << to << count)
    Q_ASSERT(count >= 0);

    QVector<QQmlChangeSet::Change> removals;
    QVector<QQmlChangeSet::Change> insertions;
    QVector<MovedFlags> movedFlags;
    removals.append(QQmlChangeSet::Change(from, count, 0));
    insertions.append(QQmlChangeSet::Change(to, count, 0));

    listItemsRemoved(translatedRemovals, list, &removals, &insertions, &movedFlags);
    listItemsInserted(translatedInsertions, list, insertions, &movedFlags);
}

void QQmlListCompositor::listItemsChanged(
        QVector<Change> *translatedChanges,
        void *list,
        const QVector<QQmlChangeSet::Change> &changes)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< list << changes)
    for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
        if (it->list != list || it->flags == CacheFlag) {
            it.incrementIndexes(it->count);
            continue;
        } else if (!it->inGroup()) {
            continue;
        }
        for (const QQmlChangeSet::Change &change : changes) {
            const int offset = change.index - it->index;
            if (offset + change.count > 0 && offset < it->count) {
                const int changeOffset = qMax(0, offset);
                const int changeCount = qMin(it->count, offset + change.count) - changeOffset;

                Change translatedChange(it, changeCount, it->flags);
                for (int i = 0; i < m_groupCount; ++i) {
                    if (it->inGroup(i))
                        translatedChange.index[i] += changeOffset;
                }
                translatedChanges->append(translatedChange);
            }
        }
        it.incrementIndexes(it->count);
    }
}


/*!
    Translates the positions of \a count changed items at \a index in a \a list.

    The \a translatedChanges list is populated with change notifications for the
    affected groups.
*/

void QQmlListCompositor::listItemsChanged(
        void *list, int index, int count, QVector<Change> *translatedChanges)
{
    QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count)
    Q_ASSERT(count >= 0);
    QVector<QQmlChangeSet::Change> changes;
    changes.append(QQmlChangeSet::Change(index, count));
    listItemsChanged(translatedChanges, list, changes);
}

void QQmlListCompositor::transition(
        Group from,
        Group to,
        QVector<QQmlChangeSet::Change> *removes,
        QVector<QQmlChangeSet::Change> *inserts)
{
    int removeCount = 0;
    for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) {
        if (it == from && it != to) {
            removes->append(QQmlChangeSet::Change(it.index[from]- removeCount, it->count));
            removeCount += it->count;
        } else if (it != from && it == to) {
            inserts->append(QQmlChangeSet::Change(it.index[to], it->count));
        }
        it.incrementIndexes(it->count);
    }
}

/*!
    \internal
    Writes the name of \a group to \a debug.
*/

QDebug operator <<(QDebug debug, const QQmlListCompositor::Group &group)
{
    switch (group) {
    case QQmlListCompositor::Cache:   return debug << "Cache";
    case QQmlListCompositor::Default: return debug << "Default";
    default: return (debug.nospace() << "Group" << int(group)).space();
    }

}

/*!
    \internal
    Writes the contents of \a range to \a debug.
*/

QDebug operator <<(QDebug debug, const QQmlListCompositor::Range &range)
{
    (debug.nospace()
            << "Range("
            << range.list) << ' '
            << range.index << ' '
            << range.count << ' '
            << (range.isUnresolved() ? 'U' : '0')
            << (range.append() ? 'A' : '0')
            << (range.prepend() ? 'P' : '0');
    for (int i = QQmlListCompositor::MaximumGroupCount - 1; i >= 2; --i)
        debug << (range.inGroup(i) ? '1' : '0');
    return (debug
            << (range.inGroup(QQmlListCompositor::Default) ? 'D' : '0')
            << (range.inGroup(QQmlListCompositor::Cache) ? 'C' : '0'));
}

static void qt_print_indexes(QDebug &debug, int count, const int *indexes)
{
    for (int i = count - 1; i >= 0; --i)
        debug << indexes[i];
}

/*!
    \internal
    Writes the contents of \a it to \a debug.
*/

QDebug operator <<(QDebug debug, const QQmlListCompositor::iterator &it)
{
    (debug.nospace() << "iterator(" << it.group).space() << "offset:" << it.offset;
    qt_print_indexes(debug, it.groupCount, it.index);
    return ((debug << **it).nospace() << ')').space();
}

static QDebug qt_print_change(QDebug debug, const char *name, const QQmlListCompositor::Change &change)
{
    debug.nospace() << name << '(' << change.moveId << ' ' << change.count << ' ';
    for (int i = QQmlListCompositor::MaximumGroupCount - 1; i >= 2; --i)
        debug << (change.inGroup(i) ? '1' : '0');
    debug << (change.inGroup(QQmlListCompositor::Default) ? 'D' : '0')
            << (change.inGroup(QQmlListCompositor::Cache) ? 'C' : '0');
    int i = QQmlListCompositor::MaximumGroupCount - 1;
    for (; i >= 0 && !change.inGroup(i); --i) {}
    for (; i >= 0; --i)
        debug << ' ' << change.index[i];
    return (debug << ')').maybeSpace();
}

/*!
    \internal
    Writes the contents of \a change to \a debug.
*/

QDebug operator <<(QDebug debug, const QQmlListCompositor::Change &change)
{
    return qt_print_change(debug, "Change", change);
}

/*!
    \internal
    Writes the contents of \a remove to \a debug.
*/

QDebug operator <<(QDebug debug, const QQmlListCompositor::Remove &remove)
{
    return qt_print_change(debug, "Remove", remove);
}

/*!
    \internal
    Writes the contents of \a insert to \a debug.
*/

QDebug operator <<(QDebug debug, const QQmlListCompositor::Insert &insert)
{
    return qt_print_change(debug, "Insert", insert);
}

/*!
    \internal
    Writes the contents of \a list to \a debug.
*/

QDebug operator <<(QDebug debug, const QQmlListCompositor &list)
{
    int indexes[QQmlListCompositor::MaximumGroupCount];
    for (int i = 0; i < QQmlListCompositor::MaximumGroupCount; ++i)
        indexes[i] = 0;
    debug.nospace() << "QQmlListCompositor(";
    qt_print_indexes(debug, list.m_groupCount, list.m_end.index);
    for (QQmlListCompositor::Range *range = list.m_ranges.next; range != &list.m_ranges; range = range->next) {
        (debug << '\n').space();
        qt_print_indexes(debug, list.m_groupCount, indexes);
        debug << ' ' << *range;

        for (int i = 0; i < list.m_groupCount; ++i) {
            if (range->inGroup(i))
                indexes[i] += range->count;
        }
    }
    return (debug << ')').maybeSpace();
}

QT_END_NAMESPACE
