use graph::{Graph, Digraph, Network, IndexGraph, IndexNetwork, Node, Edge};
use builder::Builder;
use std::ops::{Deref, DerefMut};
use std::marker::PhantomData;
pub trait AttributedGraph<'a> {
type Graph : Graph<'a>;
type Attributes : Attributes<Node=<Self::Graph as Graph<'a>>::Node,
Edge=<Self::Graph as Graph<'a>>::Edge>;
fn split(&'a mut self) -> (&Self::Graph, Self::Attributes);
fn attr(&'a self) -> &'a <Self::Attributes as Attributes>::GraphAttr;
fn attr_mut(&'a mut self) -> &'a mut <Self::Attributes as Attributes>::GraphAttr;
fn node(&'a self, u: <Self::Graph as Graph<'a>>::Node) -> &'a <Self::Attributes as Attributes>::NodeAttr;
fn node_mut(&'a mut self, u: <Self::Graph as Graph<'a>>::Node) -> &'a mut <Self::Attributes as Attributes>::NodeAttr;
fn edge(&'a self, e: <Self::Graph as Graph<'a>>::Edge) -> &'a <Self::Attributes as Attributes>::EdgeAttr;
fn edge_mut(&'a mut self, e: <Self::Graph as Graph<'a>>::Edge) -> &'a mut <Self::Attributes as Attributes>::EdgeAttr;
}
pub trait AttributedNetwork<'a>: AttributedGraph<'a>
where Self::Graph: Network<'a>,
Self::Attributes: 'a + NetworkAttributes<Node=<<Self as AttributedGraph<'a>>::Graph as Graph<'a>>::Node,
Edge=<<Self as AttributedGraph<'a>>::Graph as Graph<'a>>::Edge>
{
fn biedge(&'a self, e: <Self::Graph as Graph<'a>>::Edge)
-> &'a <Self::Attributes as NetworkAttributes>::BiEdgeAttr;
fn biedge_mut(&'a mut self, e: <Self::Graph as Graph<'a>>::Edge)
-> &'a mut <Self::Attributes as NetworkAttributes>::BiEdgeAttr;
}
pub trait Attributes {
type Node : Node;
type Edge : Edge;
type GraphAttr;
type NodeAttr;
type EdgeAttr;
fn attr(&self) -> &Self::GraphAttr;
fn attr_mut(&mut self) -> &mut Self::GraphAttr;
fn node(&self, u: Self::Node) -> &Self::NodeAttr;
fn node_mut(&mut self, u: Self::Node) -> &mut Self::NodeAttr;
fn edge(&self, e: Self::Edge) -> &Self::EdgeAttr;
fn edge_mut(&mut self, e: Self::Edge) -> &mut Self::EdgeAttr;
}
pub trait NetworkAttributes : Attributes {
type BiEdgeAttr;
fn biedge(&self, e: Self::Edge) -> &Self::BiEdgeAttr;
fn biedge_mut(&mut self, e: Self::Edge) -> &mut Self::BiEdgeAttr;
}
pub struct Attributed<G, Gx=(), Nx=(), Ex=(), Ax=()> {
graph: G,
attrs: AttributedAttrs<Gx, Nx, Ex, Ax>,
}
#[derive(Default)]
pub struct AttributedAttrs<Gx, Nx, Ex, Ax> {
attr: Gx,
nattrs: Vec<Nx>,
eattrs: Vec<Ex>,
aattrs: Vec<Ax>,
}
impl<Gx, Nx, Ex, Ax> AttributedAttrs<Gx, Nx, Ex, Ax>
where Gx: Default,
Nx: Default,
Ex: Default,
Ax: Default,
{
fn with_size(n: usize, m: usize) -> Self {
AttributedAttrs {
attr: Gx::default(),
nattrs: (0..n).map(|_| Default::default()).collect(),
eattrs: (0..m).map(|_| Default::default()).collect(),
aattrs: (0..m*2).map(|_| Default::default()).collect(),
}
}
}
pub struct GraphAttrs<'a, G, Gx, Nx, Ex, Ax>
where G: 'a + Graph<'a>,
Gx: 'a, Nx: 'a, Ex: 'a, Ax: 'a
{
graph: &'a G,
attrs: &'a mut AttributedAttrs<Gx, Nx, Ex, Ax>,
}
impl<'a, G, Gx, Nx, Ex, Ax> Attributes for GraphAttrs<'a, G, Gx, Nx, Ex, Ax>
where G: IndexGraph<'a>
{
type Node = G::Node;
type Edge = G::Edge;
type GraphAttr = Gx;
type NodeAttr = Nx;
type EdgeAttr = Ex;
fn attr(&self) -> &Self::GraphAttr { &self.attrs.attr }
fn attr_mut(&mut self) -> &mut Self::GraphAttr { &mut self.attrs.attr }
fn node(&self, u: Self::Node) -> &Self::NodeAttr {
&self.attrs.nattrs[self.graph.node_id(u)]
}
fn node_mut(&mut self, u: Self::Node) -> &mut Self::NodeAttr {
&mut self.attrs.nattrs[self.graph.node_id(u)]
}
fn edge(&self, e: Self::Edge) -> &Self::EdgeAttr {
&self.attrs.eattrs[self.graph.edge_id(e)]
}
fn edge_mut(&mut self, e: Self::Edge) -> &mut Self::EdgeAttr {
&mut self.attrs.eattrs[self.graph.edge_id(e)]
}
}
impl<'a, G, Gx, Nx, Ex, Ax> Deref for GraphAttrs<'a, G, Gx, Nx, Ex, Ax>
where G: IndexGraph<'a>
{
type Target = Gx;
fn deref(&self) -> &Gx {
&self.attrs.attr
}
}
impl<'a, G, Gx, Nx, Ex, Ax> DerefMut for GraphAttrs<'a, G, Gx, Nx, Ex, Ax>
where G: IndexGraph<'a>
{
fn deref_mut(&mut self) -> &mut Gx {
&mut self.attrs.attr
}
}
impl<'a, G, Gx, Nx, Ex, Ax> NetworkAttributes for GraphAttrs<'a, G, Gx, Nx, Ex, Ax>
where G: IndexNetwork<'a>
{
type BiEdgeAttr = Ax;
fn biedge(&self, e: Self::Edge) -> &Self::BiEdgeAttr {
&self.attrs.aattrs[self.graph.biedge_id(e)]
}
fn biedge_mut(&mut self, e: Self::Edge) -> &mut Self::BiEdgeAttr {
&mut self.attrs.aattrs[self.graph.biedge_id(e)]
}
}
pub struct AttributedBuilder<B, Gx, Nx, Ex, Ax>(B, PhantomData<(Gx, Nx, Ex, Ax)>);
impl<'b, B, G, Gx, Nx, Ex, Ax> Builder for AttributedBuilder<B, Gx, Nx, Ex, Ax>
where B: Builder<Graph=G>,
G: Graph<'b>,
Gx: Default,
Nx: Default,
Ex: Default,
Ax: Default,
{
type Graph = Attributed<G, Gx, Nx, Ex, Ax>;
type Node = B::Node;
type Edge = B::Edge;
fn with_capacities(nnodes: usize, nedges: usize) -> Self {
AttributedBuilder(B::with_capacities(nnodes, nedges), PhantomData)
}
fn reserve(&mut self, nnodes: usize, nedges: usize) {
self.0.reserve(nnodes, nedges)
}
fn add_node(&mut self) -> Self::Node {
self.0.add_node()
}
fn add_nodes(&mut self, n: usize) -> Vec<Self::Node> {
self.0.add_nodes(n)
}
fn add_edge(&mut self, u: Self::Node, v: Self::Node) -> Self::Edge {
self.0.add_edge(u, v)
}
fn node_id(&self, u: Self::Node) -> usize {
self.0.node_id(u)
}
fn edge_id(&self, e: Self::Edge) -> usize {
self.0.edge_id(e)
}
fn to_graph(self) -> Attributed<G, Gx, Nx, Ex, Ax>
{
let graph = self.0.to_graph();
let attrs = AttributedAttrs::with_size(graph.num_nodes(), graph.num_edges());
Attributed {graph, attrs,}
}
}
impl<'a, G, Gx, Nx, Ex, Ax> Graph<'a> for Attributed<G, Gx, Nx, Ex, Ax>
where G: Graph<'a>,
Gx: Default,
Nx: Default,
Ex: Default,
Ax: Default,
{
type Node = <G as Graph<'a>>::Node;
type Edge = <G as Graph<'a>>::Edge;
type NodeIter = <G as Graph<'a>>::NodeIter;
type EdgeIter = <G as Graph<'a>>::EdgeIter;
type NeighIter = <G as Graph<'a>>::NeighIter;
type Builder = AttributedBuilder<G::Builder, Gx, Nx, Ex, Ax>;
fn num_nodes(&self) -> usize { self.graph.num_nodes() }
fn num_edges(&self) -> usize { self.graph.num_edges() }
fn enodes(&'a self, e: Self::Edge) -> (Self::Node, Self::Node) { self.graph.enodes(e) }
fn nodes(&'a self) -> Self::NodeIter { self.graph.nodes() }
fn edges(&'a self) -> Self::EdgeIter { self.graph.edges() }
fn neighs(&'a self, u: Self::Node) -> Self::NeighIter { self.graph.neighs(u) }
}
impl<'a, G, Gx, Nx, Ex, Ax> Digraph<'a> for Attributed<G, Gx, Nx, Ex, Ax>
where G: Digraph<'a>,
Gx: Default,
Nx: Default,
Ex: Default,
Ax: Default,
{
type OutEdgeIter = G::OutEdgeIter;
type InEdgeIter = G::InEdgeIter;
fn src(&'a self, e: Self::Edge) -> Self::Node { self.graph.src(e) }
fn snk(&'a self, e: Self::Edge) -> Self::Node { self.graph.snk(e) }
fn outedges(&'a self, u: Self::Node) -> Self::OutEdgeIter { self.graph.outedges(u) }
fn inedges(&'a self, u: Self::Node) -> Self::InEdgeIter { self.graph.inedges(u) }
}
impl<'a, G, Gx, Nx, Ex, Ax> Network<'a> for Attributed<G, Gx, Nx, Ex, Ax>
where G: Network<'a>,
Gx: Default,
Nx: Default,
Ex: Default,
Ax: Default,
{
fn is_reverse(&self, e: Self::Edge, f: Self::Edge) -> bool { self.graph.is_reverse(e, f) }
fn reverse(&'a self, e: Self::Edge) -> Self::Edge { self.graph.reverse(e) }
fn is_forward(&self, e: Self::Edge) -> bool { self.graph.is_forward(e) }
fn forward(&'a self, e: Self::Edge) -> Self::Edge { self.graph.forward(e) }
fn is_backward(&self, e: Self::Edge) -> bool { self.graph.is_backward(e) }
fn backward(&'a self, e: Self::Edge) -> Self::Edge { self.graph.backward(e) }
}
impl<'a, G, Gx, Nx, Ex, Ax> IndexGraph<'a> for Attributed<G, Gx, Nx, Ex, Ax>
where G: IndexGraph<'a>,
Gx: Default,
Nx: Default,
Ex: Default,
Ax: Default,
{
fn node_id(&self, u: Self::Node) -> usize { self.graph.node_id(u) }
fn id2node(&'a self, id: usize) -> Self::Node { self.graph.id2node(id) }
fn edge_id(&self, e: Self::Edge) -> usize { self.graph.edge_id(e) }
fn id2edge(&'a self, id: usize) -> Self::Edge { self.graph.id2edge(id) }
}
impl<'a, G, Gx, Nx, Ex, Ax> IndexNetwork<'a> for Attributed<G, Gx, Nx, Ex, Ax>
where G: IndexNetwork<'a>,
Gx: Default,
Nx: Default,
Ex: Default,
Ax: Default,
{
fn biedge_id(&self, e: Self::Edge) -> usize { self.graph.biedge_id(e) }
fn id2biedge(&'a self, id: usize) -> Self::Edge { self.graph.id2biedge(id) }
}
impl<'a, G, Gx, Nx, Ex, Ax> AttributedGraph<'a> for Attributed<G, Gx, Nx, Ex, Ax>
where G: 'a + IndexGraph<'a>,
Gx: 'a + Default,
Nx: 'a + Default,
Ex: 'a + Default,
Ax: 'a + Default,
{
type Graph = G;
type Attributes = GraphAttrs<'a, G, Gx, Nx, Ex, Ax>;
fn split(&'a mut self) -> (&G, Self::Attributes) {
(&self.graph, GraphAttrs{ graph: &self.graph, attrs: &mut self.attrs })
}
fn attr(&self) -> &Gx {
&self.attrs.attr
}
fn attr_mut(&mut self) -> &mut Gx {
&mut self.attrs.attr
}
fn node(&self, u: G::Node) -> &Nx {
&self.attrs.nattrs[self.graph.node_id(u)]
}
fn node_mut(&mut self, u: G::Node) -> &mut Nx {
&mut self.attrs.nattrs[self.graph.node_id(u)]
}
fn edge(&self, e: G::Edge) -> &Ex {
&self.attrs.eattrs[self.graph.edge_id(e)]
}
fn edge_mut(&mut self, e: G::Edge) -> &mut Ex {
&mut self.attrs.eattrs[self.graph.edge_id(e)]
}
}
impl<'a, G, Gx, Nx, Ex, Ax> AttributedNetwork<'a> for Attributed<G, Gx, Nx, Ex, Ax>
where G: 'a + IndexNetwork<'a>,
Gx: 'a + Default,
Nx: 'a + Default,
Ex: 'a + Default,
Ax: 'a + Default,
{
fn biedge(&self, e: G::Edge) -> &Ax {
&self.attrs.aattrs[self.graph.biedge_id(e)]
}
fn biedge_mut(&mut self, e: G::Edge) -> &mut Ax {
&mut self.attrs.aattrs[self.graph.biedge_id(e)]
}
}