diff --git a/src/view/filter.rs b/src/view/filter.rs index 0c8b426..c39043e 100644 --- a/src/view/filter.rs +++ b/src/view/filter.rs @@ -25,20 +25,22 @@ pub type LinkFilter = fn(PortIndex, &Ctx) -> bool; /// For the special case of filtering out nodes only, the type alias /// [`NodeFiltered`] is provided, along with [`NodeFiltered::new_node_filtered`]. #[derive(Debug, Copy, Clone, PartialEq)] -pub struct FilteredGraph<'a, G, FN, FP, Context = ()> { - graph: &'a G, +pub struct FilteredGraph { + graph: G, node_filter: FN, link_filter: FP, context: Context, } /// A wrapper around a portgraph that filters out nodes. -pub type NodeFiltered<'a, G, FN, Context = ()> = - FilteredGraph<'a, G, FN, LinkFilter, Context>; +pub type NodeFiltered = FilteredGraph, Context>; -impl<'a, G, FN, FP, Ctx> FilteredGraph<'a, G, FN, FP, Ctx> { +impl FilteredGraph +where + G: Clone, +{ /// Create a new node filtered portgraph. - pub fn new(graph: &'a G, node_filter: FN, link_filter: FP, context: Ctx) -> Self { + pub fn new(graph: G, node_filter: FN, link_filter: FP, context: Ctx) -> Self { Self { graph, node_filter, @@ -52,20 +54,26 @@ impl<'a, G, FN, FP, Ctx> FilteredGraph<'a, G, FN, FP, Ctx> { &self.context } - pub(super) fn graph(&self) -> &'a G { - self.graph + pub(super) fn graph(&self) -> G { + self.graph.clone() } } -impl<'a, G, F, Ctx> NodeFiltered<'a, G, F, Ctx> { +impl NodeFiltered +where + G: Clone, +{ /// Create a new node filtered portgraph. - pub fn new_node_filtered(graph: &'a G, node_filter: F, context: Ctx) -> Self { + pub fn new_node_filtered(graph: G, node_filter: F, context: Ctx) -> Self { Self::new(graph, node_filter, |_, _| true, context) } } /// Filter functions used on the items of the [`FilteredGraph`] iterators. -impl FilteredGraph<'_, G, NodeFilter, LinkFilter, Ctx> { +impl FilteredGraph, LinkFilter, Ctx> +where + G: Clone, +{ /// Node filter used for the iterators fn node_filter(node: &NodeIndex, ctx: &FilteredGraphCtx) -> bool where @@ -103,12 +111,12 @@ impl FilteredGraph<'_, G, NodeFilter, LinkFilter, Ctx> { } /// The full context used for the iterators - fn as_context(&self) -> FilteredGraphCtx + fn as_context(&self) -> FilteredGraphCtx<'_, G, Ctx> where G: PortView, { FilteredGraphCtx::new( - self.graph, + self.graph.clone(), self.node_filter, self.link_filter, &self.context, @@ -121,7 +129,7 @@ impl FilteredGraph<'_, G, NodeFilter, LinkFilter, Ctx> { /// This is a named struct to make the iterator signatures more readable. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct FilteredGraphCtx<'a, G, Ctx> { - pub(self) graph: &'a G, + pub(self) graph: G, pub(self) node_filter: NodeFilter, pub(self) link_filter: LinkFilter, pub(self) context: &'a Ctx, @@ -130,7 +138,7 @@ pub struct FilteredGraphCtx<'a, G, Ctx> { impl<'a, G, Ctx> FilteredGraphCtx<'a, G, Ctx> { /// Create a new context. pub(self) fn new( - graph: &'a G, + graph: G, node_filter: NodeFilter, link_filter: LinkFilter, context: &'a Ctx, @@ -149,9 +157,9 @@ pub type FilteredGraphIter<'a, G, Ctx, I> = FilterWithCtx = MapWithCtx, O>; -impl PortView for FilteredGraph<'_, G, NodeFilter, LinkFilter, Ctx> +impl PortView for FilteredGraph, LinkFilter, Ctx> where - G: PortView, + G: PortView + Clone, { type Nodes<'a> = FilteredGraphIter<'a, G, Ctx, ::Nodes<'a>> where @@ -235,9 +243,9 @@ where } } -impl LinkView for FilteredGraph<'_, G, NodeFilter, LinkFilter, Ctx> +impl LinkView for FilteredGraph, LinkFilter, Ctx> where - G: LinkView, + G: LinkView + Clone, { type LinkEndpoint = G::LinkEndpoint; @@ -304,9 +312,9 @@ where } } -impl MultiView for FilteredGraph<'_, G, NodeFilter, LinkFilter, Ctx> +impl MultiView for FilteredGraph, LinkFilter, Ctx> where - G: MultiView, + G: MultiView + Clone, { type NodeSubports<'a> = FilteredGraphIter<'a, G, Ctx, ::NodeSubports<'a>> where diff --git a/src/view/petgraph.rs b/src/view/petgraph.rs index 2f43d5b..6086b96 100644 --- a/src/view/petgraph.rs +++ b/src/view/petgraph.rs @@ -258,17 +258,17 @@ macro_rules! impl_visit_sparse { impl_petgraph_traits!(PortGraph); impl_petgraph_traits!(MultiPortGraph); -impl_petgraph_traits!(NodeFiltered<'a, G, NodeFilter, Ctx>, ['a, G, Ctx] +impl_petgraph_traits!(NodeFiltered, Ctx>, ['a, G, Ctx] where - G: LinkView, + G: LinkView + Clone, ::LinkEndpoint: Eq ); impl_visit_dense!(PortGraph); impl_visit_dense!(MultiPortGraph); -impl_visit_sparse!(NodeFiltered<'a, G, NodeFilter, Ctx>, ['a, G, Ctx] +impl_visit_sparse!(NodeFiltered, Ctx>, ['a, G, Ctx] where - G: LinkView, + G: LinkView + Clone, ::LinkEndpoint: Eq ); diff --git a/src/view/region.rs b/src/view/region.rs index 5afd2af..7dbedf8 100644 --- a/src/view/region.rs +++ b/src/view/region.rs @@ -16,11 +16,14 @@ type RegionCallback<'g> = fn(NodeIndex, &RegionContext<'g>) -> bool; /// /// [`Region`] does not implement `Sync` as it uses a [`RefCell`] to cache the /// node filtering. -pub type Region<'g, G> = NodeFiltered<'g, G, RegionCallback<'g>, RegionContext<'g>>; +pub type Region<'g, G> = NodeFiltered, RegionContext<'g>>; -impl<'a, G> Region<'a, G> { +impl<'a, G> Region<'a, G> +where + G: Clone, +{ /// Create a new region view including all the descendants of the root node. - pub fn new_region(graph: &'a G, hierarchy: &'a Hierarchy, root: NodeIndex) -> Self { + pub fn new_region(graph: G, hierarchy: &'a Hierarchy, root: NodeIndex) -> Self { let region_filter: RegionCallback<'a> = |node, context| node == context.root() || context.is_descendant(node); Self::new_node_filtered(graph, region_filter, RegionContext::new(hierarchy, root)) @@ -92,11 +95,14 @@ type FlatRegionCallback<'g> = fn(NodeIndex, &FlatRegionContext<'g>) -> bool; /// View of a portgraph containing only a root node and its direct children in a [`Hierarchy`]. /// /// For a view of all descendants, see [`Region`]. -pub type FlatRegion<'g, G> = NodeFiltered<'g, G, FlatRegionCallback<'g>, FlatRegionContext<'g>>; +pub type FlatRegion<'g, G> = NodeFiltered, FlatRegionContext<'g>>; -impl<'a, G> FlatRegion<'a, G> { +impl<'a, G> FlatRegion<'a, G> +where + G: Clone, +{ /// Create a new region view including all the descendants of the root node. - pub fn new_flat_region(graph: &'a G, hierarchy: &'a Hierarchy, root: NodeIndex) -> Self { + pub fn new_flat_region(graph: G, hierarchy: &'a Hierarchy, root: NodeIndex) -> Self { let region_filter: FlatRegionCallback<'a> = |node, context| { let (hierarchy, root) = context; node == *root || hierarchy.parent(node) == Some(*root) diff --git a/src/view/subgraph.rs b/src/view/subgraph.rs index 9283b74..c7ef184 100644 --- a/src/view/subgraph.rs +++ b/src/view/subgraph.rs @@ -43,7 +43,7 @@ type PortCallback = fn(PortIndex, &SubgraphContext) -> bool; /// /// At initialisation, this performs a one-off expensive computation (linear in /// the size of the subgraph) to determine the nodes that are in the subgraph. -pub type Subgraph<'g, G> = FilteredGraph<'g, G, NodeCallback, PortCallback, SubgraphContext>; +pub type Subgraph = FilteredGraph; /// Internal context used in the [`Subgraph`] adaptor. #[derive(Debug, Clone)] @@ -54,7 +54,10 @@ pub struct SubgraphContext { outputs: Vec, } -impl<'a, G: LinkView> Subgraph<'a, G> { +impl Subgraph +where + G: Clone, +{ /// Create a new subgraph view of `graph`. /// /// ### Arguments @@ -64,7 +67,7 @@ impl<'a, G: LinkView> Subgraph<'a, G> { /// and outgoing ports are outgoing boundary edges. /// /// This initialisation is linear in the size of the subgraph. - pub fn new_subgraph(graph: &'a G, boundary: impl IntoIterator) -> Self { + pub fn new_subgraph(graph: G, boundary: impl IntoIterator) -> Self { let mut inputs = Vec::new(); let mut outputs = Vec::new(); @@ -76,7 +79,7 @@ impl<'a, G: LinkView> Subgraph<'a, G> { p }); - let (nodes, ports) = traverse_subgraph(graph, boundary); + let (nodes, ports) = traverse_subgraph(graph.clone(), boundary); let context = SubgraphContext { nodes: nodes.into_iter().collect(), ports: ports.into_iter().collect(), @@ -98,7 +101,7 @@ impl<'a, G: LinkView> Subgraph<'a, G> { } /// Whether the subgraph is convex, using a pre-existing checker. - pub fn is_convex_with_checker(&self, checker: &mut ConvexChecker<&G>) -> bool { + pub fn is_convex_with_checker(&self, checker: &mut ConvexChecker) -> bool { checker.is_convex( self.nodes_iter(), self.context().inputs.iter().copied(), @@ -112,7 +115,7 @@ impl<'a, G: LinkView> Subgraph<'a, G> { /// Start just inside the boundaries and follow each edge that is not itself /// a boundary. fn traverse_subgraph( - graph: &G, + graph: G, boundary: impl IntoIterator, ) -> (BTreeSet, BTreeSet) { // Nodes within subgraph