Iterate over all entities with range-for even when the mesh is modified
Currently, when using range-for on mesh entities (e.g. for (auto c: mesh.cells()){}
), the end iterator is an explicit handle to a past-the-end element during initialisation time. If the mesh is modified, the loop will either skip the new elements, or worse, go past the end.
CellIter cells_begin() const {
return CellIter(this, CellHandle(0));
}
CellIter cells_end() const {
return CellIter(this, CellHandle((int)cells_.size()));
}
std::pair<CellIter, CellIter> cells() const {
return std::make_pair(cells_begin(), cells_end());
}
While modifications during iteration usually is a bad idea, the expectation (IMO rightfully) is that this kind of range loop would iterate until the last element, as long as you use deferred deletion (or only add elements at the end).
My idea here would be to create a special immutable end iterator object, that compares equal to an iterator if the iterator is the current past-the-end element. Maybe an extra type that implicitly converts to the current end iterator, or is that too much magic? We could also comapare equal to an iterator that is further past the end - this way, even deleting the last element while iterating over it will work without deferred deletion.