Skip to content

Commit 7d44c9c

Browse files
committed
Add lifetime parameter to all graph traits.
I tried to write a Subgraph struct that implements the graph traits (backed by any graph implementation) but got stuck because of lifetimes. This changes allowed me to make some progress. May be it can be simplified with associated lifetimes. See rust-lang/rust#17307.
1 parent 4e29620 commit 7d44c9c

File tree

9 files changed

+123
-122
lines changed

9 files changed

+123
-122
lines changed

src/graph.rs

Lines changed: 39 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@ use std::ops::IndexMut;
44

55
// Basic
66

7-
pub trait Basic {
7+
pub trait Types {
88
type Vertex: Copy + Eq;
99
type Edge: Copy + Eq;
10+
}
11+
12+
pub trait Basic<'a>: Types {
1013
type VertexIter: Iterator<Item=Self::Vertex>;
1114
type EdgeIter: Iterator<Item=Self::Edge>;
1215

1316
fn num_vertices(&self) -> usize;
14-
fn vertices(&self) -> Self::VertexIter;
17+
fn vertices(&'a self) -> Self::VertexIter;
1518

1619
fn num_edges(&self) -> usize;
17-
fn edges(&self) -> Self::EdgeIter;
20+
fn edges(&'a self) -> Self::EdgeIter;
1821

1922
fn source(&self, e: Self::Edge) -> Self::Vertex;
2023
fn target(&self, e: Self::Edge) -> Self::Vertex;
@@ -27,55 +30,43 @@ pub trait Basic {
2730

2831
// Degree
2932

30-
pub trait Degree: Basic {
33+
pub trait Degree<'a>: Basic<'a> {
3134
fn degree(&self, v: Self::Vertex) -> usize;
3235
}
3336

3437

3538
// Inc
3639

37-
pub trait IncIterType<'a>: Basic {
38-
type Type: Iterator<Item=Self::Edge>;
39-
}
40+
pub type IncIter<'a, G> = <G as Inc<'a>>::Type;
4041

41-
// FIXME: change definition when [E0122] is resolved
42-
// pub type IncIter<'a, G: Inc> = <G as IncIterType<'a>>::Type;
43-
pub type IncIter<'a, G> = <G as IncIterType<'a>>::Type;
44-
45-
pub trait Inc: Basic + for<'a> IncIterType<'a> {
46-
fn inc_edges(&self, v: Self::Vertex) -> IncIter<Self>;
42+
pub trait Inc<'a>: Basic<'a> {
43+
type Type: Iterator<Item=Self::Edge>;
44+
fn inc_edges(&'a self, v: Self::Vertex) -> IncIter<Self>;
4745
}
4846

4947

5048
// Adj
5149

52-
pub trait AdjIterType<'a>: Basic {
53-
type Type: Iterator<Item=Self::Vertex>;
54-
}
55-
56-
// FIXME: change definition when [E0122] is resolved
57-
// pub type AdjIter<'a, G: Adj> = <G as AdjIterType<'a>>::Type;
58-
pub type AdjIter<'a, G> = <G as AdjIterType<'a>>::Type;
50+
pub type AdjIter<'a, G> = <G as Adj<'a>>::Type;
5951

60-
pub trait Adj: Basic + for<'a> AdjIterType<'a> {
61-
fn neighbors(&self, v: Self::Vertex) -> AdjIter<Self>;
52+
pub trait Adj<'a>: Basic<'a> {
53+
type Type: Iterator<Item=Self::Vertex>;
54+
fn neighbors(&'a self, v: Self::Vertex) -> AdjIter<Self>;
6255
}
6356

64-
// Implementation of Adj traits for Graphs which implements Inc
65-
impl<'a, G: Inc> AdjIterType<'a> for G {
57+
impl<'a, G> Adj<'a> for G
58+
where G: Inc<'a>
59+
{
6660
type Type = Map1<'a, IncIter<'a, G>, G, fn(&G, G::Edge) -> G::Vertex>;
67-
}
68-
69-
impl<G: Inc> Adj for G {
70-
fn neighbors(&self, v: Self::Vertex) -> AdjIter<Self> {
61+
fn neighbors(&'a self, v: Self::Vertex) -> AdjIter<Self> {
7162
self.inc_edges(v).map1(self, Self::target)
7263
}
7364
}
7465

7566

7667
// Vertex Property
7768

78-
pub trait VertexPropType<'a, T>: Basic {
69+
pub trait VertexPropType<'a, T>: Basic<'a> {
7970
type Type: IndexMut<Self::Vertex, Output=T>;
8071
}
8172

@@ -86,7 +77,7 @@ pub type VertexProp<'a, G, T> = <G as VertexPropType<'a, T>>::Type;
8677

8778
// Edge Property
8879

89-
pub trait EdgePropType<'a, T>: Basic {
80+
pub trait EdgePropType<'a, T>: Basic<'a> {
9081
type Type: IndexMut<Self::Edge, Output=T>;
9182
}
9283

@@ -99,20 +90,22 @@ pub type EdgeProp<'a, G, T> = <G as EdgePropType<'a, T>>::Type;
9990

10091
macro_rules! with_prop {
10192
($t:ty, $($ty:ty),*) => (
102-
pub trait WithVertexProp: for<'a> VertexPropType<'a, $t> +
103-
for<'a> VertexPropType<'a, Option<$t>>
104-
$(+ for<'a> VertexPropType<'a, $ty>)*
105-
$(+ for<'a> VertexPropType<'a, Option<$ty>>)*
93+
pub trait WithVertexProp<'a>: VertexPropType<'a, $t> +
94+
VertexPropType<'a, Option<$t>>
95+
$(+ VertexPropType<'a, $ty>)*
96+
$(+ VertexPropType<'a, Vec<$ty>>)*
97+
$(+ VertexPropType<'a, Option<$ty>>)*
10698
{
107-
fn vertex_prop<T: Clone>(&self, value: T) -> VertexProp<Self, T>;
99+
fn vertex_prop<T: Clone>(&'a self, value: T) -> VertexProp<Self, T>;
108100
}
109101

110-
pub trait WithEdgeProp: for<'a> EdgePropType<'a, $t> +
111-
for<'a> EdgePropType<'a, Option<$t>>
112-
$(+ for<'a> EdgePropType<'a, $ty>)*
113-
$(+ for<'a> EdgePropType<'a, Option<$ty>>)*
102+
pub trait WithEdgeProp<'a>: EdgePropType<'a, $t> +
103+
EdgePropType<'a, Option<$t>>
104+
$(+ EdgePropType<'a, $ty>)*
105+
$(+ EdgePropType<'a, Vec<$ty>>)*
106+
$(+ EdgePropType<'a, Option<$ty>>)*
114107
{
115-
fn edge_prop<T: Clone>(&self, value: T) -> EdgeProp<Self, T>;
108+
fn edge_prop<T: Clone>(&'a self, value: T) -> EdgeProp<Self, T>;
116109
}
117110
)
118111
}
@@ -123,15 +116,15 @@ with_prop! {
123116
i8, i16, i32, i64, isize,
124117
u8, u16, u32, u64, usize,
125118
&'a str, String,
126-
<Self as Basic>::Vertex,
127-
<Self as Basic>::Edge
119+
<Self as Types>::Vertex,
120+
<Self as Types>::Edge
128121
}
129122

130123

131124
// Graph alias
132125

133-
trait_alias!(GraphInc: Basic + Degree + Inc);
134-
trait_alias!(GraphIncWithProps: GraphInc + WithVertexProp + WithEdgeProp);
126+
trait_alias!(GraphInc: Basic<'a> + Degree<'a> + Inc<'a>);
127+
trait_alias!(GraphIncWithProps: GraphInc<'a> + WithVertexProp<'a> + WithEdgeProp<'a>);
135128

136-
trait_alias!(GraphAdj: Basic + Degree + Adj);
137-
trait_alias!(GraphAdjWithProps: GraphAdj + WithVertexProp + WithEdgeProp);
129+
trait_alias!(GraphAdj: Basic<'a> + Degree<'a> + Adj<'a>);
130+
trait_alias!(GraphAdjWithProps: GraphAdj<'a> + WithVertexProp<'a> + WithEdgeProp<'a>);

src/kruskal.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
use graph::*;
22
use unionfind::DisjointSet;
33

4-
pub trait Visitor<G: Basic> {
4+
pub trait Visitor<'a, G: Basic<'a>> {
55
fn visit(&mut self, e: G::Edge, in_same_set: bool) -> bool;
66
}
77

8-
impl<F, G> Visitor< G> for F
9-
where G: Basic,
8+
impl<'a, F, G> Visitor<'a, G> for F
9+
where G: Basic<'a>,
1010
F: FnMut(G::Edge, bool) -> bool {
1111
fn visit(&mut self, e: G::Edge, in_same_set: bool) -> bool {
1212
self(e, in_same_set)
1313
}
1414
}
1515

16-
pub trait Kruskal: Basic + WithVertexProp + Sized {
17-
fn kruskal_edges<I, V>(&self, edges: I, mut visitor: V)
16+
pub trait Kruskal<'a>: Basic<'a> + WithVertexProp<'a> + Sized {
17+
fn kruskal_edges<I, V>(&'a self, edges: I, mut visitor: V)
1818
where I: Iterator<Item = Self::Edge>,
19-
V: Visitor<Self>
19+
V: Visitor<'a, Self>
2020
{
2121
let mut ds = DisjointSet::new(self);
2222
for e in edges {
@@ -31,19 +31,19 @@ pub trait Kruskal: Basic + WithVertexProp + Sized {
3131
}
3232
}
3333

34-
fn kruskal<T, V>(&self, weight: &EdgeProp<Self, T>, visitor: V)
34+
fn kruskal<T, V>(&'a self, weight: &'a EdgeProp<'a, Self, T>, visitor: V)
3535
where T: Ord,
36-
V: Visitor<Self>,
37-
Self: for<'a> EdgePropType<'a, T>
36+
V: Visitor<'a, Self>,
37+
Self: EdgePropType<'a, T>
3838
{
3939
let mut edges = self.edges().collect::<Vec<_>>();
4040
edges.sort_by(|a, b| weight[*a].cmp(&weight[*b]));
4141
self.kruskal_edges(edges.iter().cloned(), visitor);
4242
}
4343

44-
fn kruskal_mst<T>(&self, weight: &EdgeProp<Self, T>) -> Vec<Self::Edge>
44+
fn kruskal_mst<T>(&'a self, weight: &'a EdgeProp<'a, Self, T>) -> Vec<Self::Edge>
4545
where T: Ord,
46-
Self: for<'a> EdgePropType<'a, T>
46+
Self: EdgePropType<'a, T>
4747
{
4848
let mut tree = vec![];
4949
self.kruskal::<T, _>(weight, |e: Self::Edge, in_same_set: bool| {
@@ -56,7 +56,8 @@ pub trait Kruskal: Basic + WithVertexProp + Sized {
5656
}
5757
}
5858

59-
impl<G> Kruskal for G where G: Basic + WithVertexProp { }
59+
impl<'a, G> Kruskal<'a> for G
60+
where G: Basic<'a> + WithVertexProp<'a> { }
6061

6162

6263
#[cfg(test)]

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ macro_rules! items {
1919
macro_rules! trait_alias {
2020
($name:ident : $($base:tt)+) => {
2121
items! {
22-
pub trait $name: $($base)+ { }
23-
impl<T: $($base)+> $name for T { }
22+
pub trait $name<'a>: $($base)+ { }
23+
impl<'a, T> $name<'a> for T where T: $($base)+ { }
2424
}
2525
};
2626
}

src/path.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
use graph::*;
22
use traverse::*;
33

4-
pub type Path<G> = Vec<<G as Basic>::Edge>;
4+
pub type Path<G> = Vec<<G as Types>::Edge>;
55

6-
pub type ParentTree<'a, G> = VertexProp<'a, G, Option<<G as Basic>::Edge>>;
6+
pub type ParentTree<'a, G> = VertexProp<'a, G, Option<<G as Types>::Edge>>;
77

8-
pub trait FindPath: Basic + Sized {
9-
fn find_path_on_parent_tree(&self,
10-
tree: &ParentTree<Self>,
8+
pub trait FindPath<'a>: Basic<'a> + Sized {
9+
fn find_path_on_parent_tree(&'a self,
10+
tree: &ParentTree<'a, Self>,
1111
u: Self::Vertex,
1212
v: Self::Vertex)
1313
-> Option<Path<Self>>
14-
where Self: WithVertexProp
14+
where Self: WithVertexProp<'a>
1515
{
1616
if u == v {
1717
return None;
@@ -30,8 +30,8 @@ pub trait FindPath: Basic + Sized {
3030
None
3131
}
3232

33-
fn find_path(&self, u: Self::Vertex, v: Self::Vertex) -> Option<Path<Self>>
34-
where Self: GraphIncWithProps
33+
fn find_path(&'a self, u: Self::Vertex, v: Self::Vertex) -> Option<Path<Self>>
34+
where Self: GraphIncWithProps<'a>
3535
{
3636
if u == v {
3737
return None;
@@ -52,7 +52,8 @@ pub trait FindPath: Basic + Sized {
5252
}
5353
}
5454

55-
impl<G: Basic> FindPath for G { }
55+
impl<'a, G> FindPath<'a> for G
56+
where G: Basic<'a> { }
5657

5758
#[cfg(test)]
5859
mod tests {

src/props.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use graph::*;
22
use traverse::*;
33

4-
pub trait Props: Basic + Sized {
5-
fn is_acyclic(&self) -> bool
6-
where Self: GraphIncWithProps
4+
pub trait Props<'a>: Basic<'a> + Sized {
5+
fn is_acyclic(&'a self) -> bool
6+
where Self: GraphIncWithProps<'a>
77
{
88
let mut acyclic = true;
99
Dfs::run(self, &mut BackEdgeVisitor(|_| {
@@ -13,8 +13,8 @@ pub trait Props: Basic + Sized {
1313
acyclic
1414
}
1515

16-
fn is_connected(&self) -> bool
17-
where Self: GraphIncWithProps
16+
fn is_connected(&'a self) -> bool
17+
where Self: GraphIncWithProps<'a>
1818
{
1919
self.num_vertices() == 0 || {
2020
let mut count = 0;
@@ -26,16 +26,17 @@ pub trait Props: Basic + Sized {
2626
}
2727
}
2828

29-
fn is_tree(&self) -> bool
30-
where Self: GraphIncWithProps
29+
fn is_tree(&'a self) -> bool
30+
where Self: GraphIncWithProps<'a>
3131
{
3232
self.num_vertices() == 0 || {
3333
self.num_edges() == self.num_vertices() - 1 && self.is_acyclic()
3434
}
3535
}
3636
}
3737

38-
impl<G> Props for G where G: Basic { }
38+
impl<'a, G> Props<'a> for G
39+
where G: Basic<'a> { }
3940

4041
#[cfg(test)]
4142
mod tests {

src/static_.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -114,17 +114,20 @@ impl StaticGraphBuilder {
114114
}
115115

116116

117-
impl Basic for StaticGraph {
117+
impl Types for StaticGraph {
118118
type Vertex = usize;
119119
type Edge = Edge;
120+
}
121+
122+
impl<'a> Basic<'a> for StaticGraph {
120123
type VertexIter = Range<Self::Vertex>;
121124
type EdgeIter = Map<Range<usize>, fn(usize) -> Self::Edge>;
122125

123126
fn num_vertices(&self) -> usize {
124127
self.num_vertices
125128
}
126129

127-
fn vertices(&self) -> Self::VertexIter {
130+
fn vertices(&'a self) -> Self::VertexIter {
128131
0..self.num_vertices
129132
}
130133

@@ -140,22 +143,19 @@ impl Basic for StaticGraph {
140143
self.endvertices.len() / 2
141144
}
142145

143-
fn edges(&self) -> Self::EdgeIter {
146+
fn edges(&'a self) -> Self::EdgeIter {
144147
(0..self.num_edges()).map(Edge::new)
145148
}
146149
}
147150

148-
impl Degree for StaticGraph {
151+
impl<'a> Degree<'a> for StaticGraph {
149152
fn degree(&self, v: Self::Vertex) -> usize {
150153
self.inc[v].len()
151154
}
152155
}
153156

154-
impl<'a> IncIterType<'a> for StaticGraph {
157+
impl<'a> Inc<'a> for StaticGraph {
155158
type Type = Cloned<Iter<'a, Self::Edge>>;
156-
}
157-
158-
impl Inc for StaticGraph {
159159
fn inc_edges(&self, v: Self::Vertex) -> IncIter<Self> {
160160
self.inc[v].iter().cloned()
161161
}
@@ -165,8 +165,8 @@ impl<'a, T> VertexPropType<'a, T> for StaticGraph {
165165
type Type = Vec<T>;
166166
}
167167

168-
impl WithVertexProp for StaticGraph {
169-
fn vertex_prop<T: Clone>(&self, value: T) -> VertexProp<Self, T> {
168+
impl<'a> WithVertexProp<'a> for StaticGraph {
169+
fn vertex_prop<T: Clone>(&'a self, value: T) -> VertexProp<Self, T> {
170170
vec![value; self.num_vertices()]
171171
}
172172
}
@@ -175,8 +175,8 @@ impl<'a, T> EdgePropType<'a, T> for StaticGraph {
175175
type Type = EdgePropVec<T>;
176176
}
177177

178-
impl WithEdgeProp for StaticGraph {
179-
fn edge_prop<T: Clone>(&self, value: T) -> EdgeProp<Self, T> {
178+
impl<'a> WithEdgeProp<'a> for StaticGraph {
179+
fn edge_prop<T: Clone>(&'a self, value: T) -> EdgeProp<Self, T> {
180180
EdgePropVec(vec![value; self.num_edges()])
181181
}
182182
}

0 commit comments

Comments
 (0)