ScriptList: Update iterators when swapping lists

Safe btree iterators store a pointer to the parent container
This commit is contained in:
Jonathan G Rennison
2023-08-05 19:54:05 +01:00
parent 731a79b224
commit 24a77e5b36

View File

@@ -68,18 +68,33 @@ public:
*/
virtual void ValueChange(SQInteger item) = 0;
/**
* Safe btree iterators hold a pointer to the parent container's tree, so update those
*/
virtual void RetargetIterators() = 0;
/**
* Attach the sorter to a new list. This assumes the content of the old list has been moved to
* the new list, too, so that we don't have to invalidate any iterators. Note that std::swap
* doesn't invalidate iterators on lists and maps, so that should be safe.
* the new list, too, so that we don't have to invalidate any iterators.
* @param target New list to attach to.
*/
virtual void Retarget(ScriptList *new_list)
{
this->list = new_list;
this->RetargetIterators();
}
};
template <typename T>
void RetargetIterator(T &container, typename T::iterator &iter)
{
if (iter.generation() > 0) {
iter = container.lower_bound(iter.key());
} else {
iter = container.end();
}
}
/**
* Sort by value, ascending.
*/
@@ -167,6 +182,11 @@ public:
{
this->ScriptListSorterValueAscending::Remove(item);
}
void RetargetIterators()
{
RetargetIterator(this->list->values, this->value_iter);
}
};
/**
@@ -257,6 +277,11 @@ public:
{
this->ScriptListSorterValueDescending::Remove(item);
}
void RetargetIterators()
{
RetargetIterator(this->list->values, this->value_iter);
}
};
/**
@@ -345,6 +370,11 @@ public:
{
/* do nothing */
}
void RetargetIterators()
{
RetargetIterator(this->list->items, this->item_iter);
}
};
/**
@@ -434,6 +464,11 @@ public:
{
/* do nothing */
}
void RetargetIterators()
{
RetargetIterator(this->list->items, this->item_iter);
}
};