Skip to content

Instantly share code, notes, and snippets.

@jorendorff
Created January 15, 2016 04:37
Show Gist options
  • Save jorendorff/45116c5aa132d5fe58e9 to your computer and use it in GitHub Desktop.
Save jorendorff/45116c5aa132d5fe58e9 to your computer and use it in GitHub Desktop.
use std::marker::PhantomData;
use std::collections::HashSet;
type GraphId<'a> = PhantomData<::std::cell::Cell<&'a mut ()>>;
struct Graph<'a> {
id: GraphId<'a>,
vertices: usize,
edges: HashSet<(usize, usize)>
}
struct VertexRef<'a> {
graph_id: GraphId<'a>,
index: usize
}
fn with_graph<F, O>(f: F) -> O
where F: for<'a> FnOnce(Graph<'a>) -> O
{
f(Graph {id: PhantomData, vertices: 0, edges: HashSet::new()})
}
impl<'a> Graph<'a> {
fn new_vertex(&mut self) -> VertexRef<'a> {
let n = self.vertices;
self.vertices += 1;
VertexRef { graph_id: self.id, index: n }
}
fn add_edge(&mut self, u: VertexRef<'a>, v: VertexRef<'a>) {
self.edges.insert((u.index, v.index));
}
}
fn main() {
with_graph(|mut g1| {
with_graph(|mut g2| {
let v1 = g1.new_vertex(); // error: cannot infer an appropriate lifetime parameter `'a` due to conflicting requirements
let v2 = g2.new_vertex();
g2.add_edge(v1, v2);
})
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment