Let's say I have the following struct:
struct Polygon<'a>(Vec<&'a Segment<'a>);
And 2 ways of instanciating it:
fn new(segments: Vec<&'a Segment>) -> Self {
/* Performs some checks */
Self(segments)
}
fn from_points(points: Vec<&'a Point>) -> Self {
/* Builds segments from points */
Self::new(segments)
}
In from_point
, since I'm building the segments inside the constructor, I have to do heap allocation using a combination of Box::new
and Box::leak
before passing those references to new
. Otherwise the temporaries are dropped at the end of the block while still borrowed.
Now, the problem is that I have to manually drop those segments when the polygon instance is dropped to avoid memory leaks.
What's the best way to achieve that ?
I came up with 2 solutions so far:
- Replacing the struct by an enum
enum Polygon<'a> {
Polygon(Vec<&'a Segment<'a>),
OwnedPolygon(Vec<&'a Segment<'a>),
}
Then implementing a custom destructor for OwnedPolygon
instances.
Not ideal because this induces a lot of useless branching at runtime.
- Introducing a const generic parameter
struct Polygon<'a, const DROP: bool>(Vec<&'a Segment<'a>);
Then implementing a custom destructor for Polygon<'a, true>
.
Not ideal because if I have to handle collections of polygons the DROP parameter would make them heterogeneous, which means I'd have to resort to dynamic dispatch.