use common::adjacency_list::*;
use core::*;
impl<V,W> BaseGraph for AdjListGraph<V,W>
where
V: Vertex,
W: Weight,
{
type Vertex = V;
type Weight = W;
type VertexIter = Vec<V>;
type EdgeIter = Vec<BaseEdge<V,W>>;
fn empty_graph() -> AdjListGraph<V,W>{
AdjListGraph{values: Vec::new(), edges: Vec::new()}
}
fn all_vertices(&self) -> Vec<V> {
let mut result = Vec::new();
for i in 0..self.values.len() {
result.push(self.values[i]);
}
result
}
fn all_edges(& self) -> Vec<BaseEdge<V,W>> {
let mut result = Vec::new();
for (source_i, ref out) in self.edges.iter().enumerate() {
let source_value = self.values[source_i];
for &(sink_i, weight ) in out.iter() {
let sink_value = self.values[sink_i];
result.push(BaseEdge::new(source_value, sink_value, weight));
}
}
result
}
fn add_vertex(&mut self, v: V) -> Result<(),()>{
if self.values.contains(&v){
Err(())
}else{
self.values.push(v);
self.edges.push(Vec::new());
Ok(())
}
}
fn remove_vertex(&mut self, v: V) -> Result<(),()>{
if let Some(v_i) = self.get_index(v){
for t_v_i in 0..self.values.len(){
let mut to_remove = Vec::new();
let ref mut t_v_out = self.edges[t_v_i];
for i in 0..t_v_out.len() {
if t_v_out[i].0 == v_i {
to_remove.push(i);
}
}
for i in (0..to_remove.len()).rev() {
t_v_out.remove(to_remove[i]);
}
}
let last_i = self.values.len() - 1;
for t_v_i in 0..self.edges.len() {
let ref mut t_v_out = self.edges[t_v_i];
for edge_i in 0..t_v_out.len(){
if t_v_out[edge_i].0 == last_i {
t_v_out[edge_i].0 = v_i
}
}
}
self.values.swap_remove(v_i);
self.edges.swap_remove(v_i);
return Ok(());
}
Err(())
}
fn add_edge(&mut self, e: BaseEdge<V,W>) -> Result<(), ()>{
self.if_valid_edge( e, |s, source_i, sink_i, weight|{
s.edges[source_i].push((sink_i,weight));
Ok(())
})
}
fn remove_edge(&mut self, e: BaseEdge<V,W>)-> Result<(), ()>{
self.if_valid_edge(e, |s, source_i, sink_i, weight|{
if let Some(i) = s.edges[source_i].iter().position(|&(sink_cand, w )| {
sink_cand == sink_i && w == weight
}) {
s.edges[source_i].remove(i);
return Ok(());
}
Err(())
})
}
}
impl<V,W> ConstrainedGraph for AdjListGraph<V,W>
where
V: Vertex,
W: Weight,
{
impl_base_constraint!{}
}
#[test]
fn empty_has_no_vertices(){
assert_eq!(0, AdjListGraph::<u32,u32>::empty_graph().all_vertices().len());
}
#[test]
fn empty_has_no_edges(){
assert_eq!(0, AdjListGraph::<u32,u32>::empty_graph().all_edges().len());
}