use super::*;
pub trait Unique: ConstrainedGraph
where
<Self::VertexIter as IntoIterator>::IntoIter: ExactSizeIterator,
<Self::EdgeIter as IntoIterator>::IntoIter: ExactSizeIterator,
{}
graph_wrapper!{
struct UniqueGraph
}
impl_constraints_for_wrapper!{UniqueGraph : Unique}
impl<G> BaseGraph for UniqueGraph<G>
where
G: ConstrainedGraph,
<G as BaseGraph>::Vertex: Vertex,
<G as BaseGraph>::Weight: Weight,
<<G as BaseGraph>::VertexIter as IntoIterator>::IntoIter: ExactSizeIterator,
<<G as BaseGraph>::EdgeIter as IntoIterator>::IntoIter: ExactSizeIterator,
{
type Vertex = <G as BaseGraph>::Vertex;
type Weight = <G as BaseGraph>::Weight;
type VertexIter = <G as BaseGraph>::VertexIter;
type EdgeIter = <G as BaseGraph>::EdgeIter;
fn empty_graph() -> Self {
UniqueGraph::wrap(G::empty_graph())
}
wrapped_method!{all_vertices(&self) -> Self::VertexIter}
wrapped_method!{all_edges(&self) -> Self::EdgeIter}
wrapped_method!{add_vertex(&mut self, v: Self::Vertex) -> Result<(), ()>}
wrapped_method!{remove_vertex(&mut self, v: Self::Vertex) -> Result<(), ()>}
fn add_edge(&mut self, e: BaseEdge<Self::Vertex, Self::Weight>) -> Result<(), ()> {
if let Some(_) = self.all_edges().into_iter().position(
|edge| edge.source == e.source && edge.sink == e.sink )
{
return Err(());
}
self.wraps.add_edge(e)
}
wrapped_method!{remove_edge(&mut self, e: BaseEdge<Self::Vertex, Self::Weight>) -> Result<(), ()>}
}
impl<G> ConstrainedGraph for UniqueGraph<G>
where
G: ConstrainedGraph,
<G as BaseGraph>::Vertex: Vertex,
<G as BaseGraph>::Weight: Weight,
<<G as BaseGraph>::VertexIter as IntoIterator>::IntoIter: ExactSizeIterator,
<<G as BaseGraph>::EdgeIter as IntoIterator>::IntoIter: ExactSizeIterator,
{
fn invariant_holds(&self) -> bool {
for v1 in self.all_vertices(){
for v2 in self.all_vertices(){
let mut v1_to_v2 = self.all_edges().into_iter().filter(|edge|{
edge.source == v1 && edge.sink == v2
});
v1_to_v2.next();
if let Some(_) = v1_to_v2.next(){
return false;
}
}
}
self.wraps.invariant_holds()
}
wrapped_uncon_methods!{}
}