I've got some code that implements a geometric data structure called a "doubly connected edge list" (DCEL). It's used for algorithms related to polygons. It stores arrays of vertices, edges, and faces. I use IDs (usize
) to refer to these elements in their arrays. I have a function that returns an iterator to walk the edges around a polygon face:
type EdgeId = usize;
...
for edge_id in dcel.walk_around_face(start_edge_id) {
dcel.edges[edge_id].incident_face = f;
}
The problem here is that my iterator borrows the data structure. So that line inside the loop fails the borrow check.
pub struct FaceEdgeWalkIterator<'d> {
dcel: &'d DCEL,
start: EdgeId,
current: EdgeId
...
}
impl<'d> Iterator for FaceEdgeWalkIterator<'d> {
type Item = EdgeId;
fn next(&mut self) -> Option<EdgeId> {
let to_ret = self.current;
self.edge = self.dcel.edges[self.current].next;
...
However I think my code should be safe. The iterator uses properties of the edges like next
, but does not touch the incident_face
property.
I know I can use unsafe
here to get a raw pointer to dcel.edges
before the loop and just blast away. But I wonder if there are any standard ways to handle this?
let edges_hack = ptr::addr_of_mut!(self.dcel.edges);
for e_id in self.dcel.walk_around_face(start) {
let edge_ref = unsafe { &mut (*edges_hack)[e_id] };
edge_ref.incident_face = f;
}