use crate::traits::refs::{DirectedRef, GraphSizeRef, IndexGraphRef, UndirectedRef};
use crate::traits::{Directed, DirectedEdge, GraphIterator, GraphSize, GraphType, IndexGraph, Undirected};
#[derive(Clone, Copy)]
pub struct ReverseDigraph<'a, G>(&'a G);
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct ReverseDirectedEdge<E>(E);
#[derive(Clone)]
pub struct ReverseWrapIt<I>(I);
impl<'a, G, I> GraphIterator<ReverseDigraph<'a, G>> for ReverseWrapIt<I>
where
I: GraphIterator<G>,
{
type Item = I::Item;
fn next(&mut self, g: &ReverseDigraph<'a, G>) -> Option<I::Item> {
self.0.next(g.0)
}
fn size_hint(&self, g: &ReverseDigraph<'a, G>) -> (usize, Option<usize>) {
self.0.size_hint(g.0)
}
fn count(self, g: &ReverseDigraph<'a, G>) -> usize {
self.0.count(g.0)
}
}
impl<E> DirectedEdge for ReverseDirectedEdge<E>
where
E: DirectedEdge,
{
type Edge = E::Edge;
fn is_incoming(&self) -> bool {
self.0.is_outgoing()
}
fn is_outgoing(&self) -> bool {
self.0.is_incoming()
}
fn edge(&self) -> Self::Edge {
self.0.edge()
}
}
impl<'a, 'g: 'a, G> GraphType<'a> for ReverseDigraph<'g, G>
where
G: GraphType<'g>,
{
type Node = G::Node;
type Edge = G::Edge;
}
impl<'a, 'g: 'a, G> GraphSize<'a> for ReverseDigraph<'g, G>
where
G: GraphSize<'g>,
{
type NodeIt = ReverseWrapIt<G::NodeIt>;
type EdgeIt = ReverseWrapIt<G::EdgeIt>;
fn num_nodes(&self) -> usize {
self.0.num_nodes()
}
fn num_edges(&self) -> usize {
self.0.num_edges()
}
fn nodes_iter(&self) -> Self::NodeIt {
ReverseWrapIt(self.0.nodes_iter())
}
fn edges_iter(&self) -> Self::EdgeIt {
ReverseWrapIt(self.0.edges_iter())
}
}
impl<'a, 'g: 'a, G> Undirected<'a> for ReverseDigraph<'g, G>
where
G: Undirected<'g>,
{
type NeighIt = ReverseWrapIt<G::NeighIt>;
fn enodes(&self, e: Self::Edge) -> (Self::Node, Self::Node) {
self.0.enodes(e)
}
fn neigh_iter(&self, u: Self::Node) -> Self::NeighIt {
ReverseWrapIt(self.0.neigh_iter(u))
}
}
impl<'a, 'g: 'a, G> IndexGraph<'a> for ReverseDigraph<'g, G>
where
G: IndexGraph<'g>,
{
fn node_id(&self, u: Self::Node) -> usize {
self.0.node_id(u)
}
fn id2node(&self, id: usize) -> Self::Node {
self.0.id2node(id)
}
fn edge_id(&self, e: Self::Edge) -> usize {
self.0.edge_id(e)
}
fn id2edge(&self, id: usize) -> Self::Edge {
self.0.id2edge(id)
}
}
#[derive(Clone)]
pub struct ReverseIncidentIt<I>(I);
impl<'a, G, I, N, D> GraphIterator<ReverseDigraph<'a, G>> for ReverseIncidentIt<I>
where
I: GraphIterator<G, Item = (D, N)>,
D: DirectedEdge,
{
type Item = (ReverseDirectedEdge<D>, N);
fn next(&mut self, g: &ReverseDigraph<G>) -> Option<Self::Item> {
self.0.next(&g.0).map(|(e, v)| (ReverseDirectedEdge(e), v))
}
fn size_hint(&self, g: &ReverseDigraph<G>) -> (usize, Option<usize>) {
self.0.size_hint(&g.0)
}
fn count(self, g: &ReverseDigraph<G>) -> usize {
self.0.count(&g.0)
}
}
impl<'a, G> Directed<'a> for ReverseDigraph<'a, G>
where
G: Directed<'a>,
{
type OutIt = ReverseWrapIt<G::InIt>;
type InIt = ReverseWrapIt<G::OutIt>;
type IncidentIt = ReverseIncidentIt<G::IncidentIt>;
type DirectedEdge = ReverseDirectedEdge<G::DirectedEdge>;
fn src(&'a self, e: Self::Edge) -> Self::Node {
self.0.snk(e)
}
fn snk(&'a self, e: Self::Edge) -> Self::Node {
self.0.src(e)
}
fn out_iter(&'a self, u: Self::Node) -> Self::OutIt {
ReverseWrapIt(self.0.in_iter(u))
}
fn in_iter(&'a self, u: Self::Node) -> Self::InIt {
ReverseWrapIt(self.0.out_iter(u))
}
fn incident_iter(&'a self, u: Self::Node) -> Self::IncidentIt {
ReverseIncidentIt(self.0.incident_iter(u))
}
}
pub fn reverse<'a, G: Directed<'a>>(g: &'a G) -> ReverseDigraph<'a, G> {
ReverseDigraph(g)
}
impl<'a, G> GraphSizeRef<'a> for ReverseDigraph<'a, G>
where
G: GraphSizeRef<'a>,
{
fn nodes_iter(&self) -> Self::NodeIt {
ReverseWrapIt(GraphSize::nodes_iter(self.0))
}
fn edges_iter(&self) -> Self::EdgeIt {
ReverseWrapIt(GraphSize::edges_iter(self.0))
}
}
impl<'a, G> UndirectedRef<'a> for ReverseDigraph<'a, G>
where
G: UndirectedRef<'a>,
{
fn enodes(&self, e: Self::Edge) -> (Self::Node, Self::Node) {
Undirected::enodes(self.0, e)
}
fn neigh_iter(&self, u: Self::Node) -> Self::NeighIt {
ReverseWrapIt(Undirected::neigh_iter(self.0, u))
}
}
impl<'a, G> DirectedRef<'a> for ReverseDigraph<'a, G>
where
G: DirectedRef<'a>,
{
fn src(&self, u: Self::Edge) -> Self::Node {
DirectedRef::snk(&self.0, u)
}
fn snk(&self, u: Self::Edge) -> Self::Node {
DirectedRef::src(&self.0, u)
}
fn out_iter(&self, u: Self::Node) -> Self::OutIt {
ReverseWrapIt(Directed::in_iter(self.0, u))
}
fn in_iter(&self, u: Self::Node) -> Self::InIt {
ReverseWrapIt(Directed::out_iter(self.0, u))
}
fn incident_iter(&self, u: Self::Node) -> Self::IncidentIt {
ReverseIncidentIt(Directed::incident_iter(self.0, u))
}
}
impl<'a, G> IndexGraphRef<'a> for ReverseDigraph<'a, G>
where
G: IndexGraphRef<'a>,
{
fn id2node(&self, id: usize) -> Self::Node {
IndexGraph::id2node(self.0, id)
}
fn id2edge(&self, id: usize) -> Self::Edge {
IndexGraph::id2edge(self.0, id)
}
}
#[cfg(test)]
mod tests {
use super::reverse;
use crate::classes;
use crate::traits::GraphSize;
use crate::vec::EdgeVec;
use crate::LinkedListGraph;
#[test]
fn test_vec() {
let g = classes::peterson::<LinkedListGraph>();
let r = reverse(&g);
let weights = EdgeVec::new(&r, 42);
for e in r.edges() {
assert_eq!(weights[e], 42);
}
}
}