The function CWorldView::RemoveSomeInfluences maintains a list of CInfluence objects with the mark-and-sweep technique: old influences as well as the lowest-priority-influence are "marked". If there are enough such obsolete influences, they are removed ("sweeped").
There are two key problems with the current implementation:
The list of influences is actually a std::set. This collection only gives const access to its entries to ensure the validity of the internal tree structure. To bypass this restriction and modify the entries in the "mark" phase, the code uses some awkward pointer casting.
Execution with additional memory access validation (full page heap verification) raises complaints. The stored pointer to the lowest-priority influence, taken from an iterator, seems to become invalid at some stage.
In a refactoring of the function, both problems are resolved:
The setFlags member is declared as mutable to allow direct modification despite constness. Unit tests ensure that this does not affect the relational comparison upon which std::set is built.
The function bRemoveInfluence takes a CInstance* as its argument. Every CInfluence has such a pointer, which is also the basis of the relational comparison for std::set. Instead of collecting a list of CInfluence pointers to remove later, we collect a list of their inner CInstance pointers. Unit tests ensure that the behavior of CWorldView::RemoveSomeInfluences is not changed.
The function
CWorldView::RemoveSomeInfluences
maintains a list ofCInfluence
objects with the mark-and-sweep technique: old influences as well as the lowest-priority-influence are "marked". If there are enough such obsolete influences, they are removed ("sweeped").There are two key problems with the current implementation:
std::set
. This collection only givesconst
access to its entries to ensure the validity of the internal tree structure. To bypass this restriction and modify the entries in the "mark" phase, the code uses some awkward pointer casting.In a refactoring of the function, both problems are resolved:
setFlags
member is declared asmutable
to allow direct modification despite constness. Unit tests ensure that this does not affect the relational comparison upon whichstd::set
is built.bRemoveInfluence
takes aCInstance*
as its argument. EveryCInfluence
has such a pointer, which is also the basis of the relational comparison forstd::set
. Instead of collecting a list ofCInfluence
pointers to remove later, we collect a list of their innerCInstance
pointers. Unit tests ensure that the behavior ofCWorldView::RemoveSomeInfluences
is not changed.