use super::{
Directed, DirectedEdge, FiniteGraph, GraphIter, GraphIterator, GraphType, IndexDigraph, IndexGraph, Undirected,
};
use std::ptr::NonNull;
pub trait GraphTypeRef<'a>: Clone {
type Node: Copy + Eq;
type Edge: Copy + Eq;
}
pub trait FiniteGraphRef<'a>: GraphTypeRef<'a> {
type NodeIt: GraphIterator<Self, Item = Self::Node>;
type EdgeIt: GraphIterator<Self, Item = Self::Edge>;
fn num_nodes(&self) -> usize;
fn nodes_iter(&self) -> Self::NodeIt;
fn nodes(&self) -> GraphIter<Self, Self::NodeIt>
where
Self: Sized,
{
GraphIter(FiniteGraphRef::nodes_iter(self), self)
}
fn num_edges(&self) -> usize;
fn edges_iter(&self) -> Self::EdgeIt;
fn edges(&self) -> GraphIter<Self, Self::EdgeIt>
where
Self: Sized,
{
GraphIter(FiniteGraphRef::edges_iter(self), self)
}
fn enodes(&self, e: Self::Edge) -> (Self::Node, Self::Node);
}
pub trait FiniteDigraphRef<'a>: FiniteGraphRef<'a> {
fn src(&self, e: Self::Edge) -> Self::Node;
fn snk(&self, e: Self::Edge) -> Self::Node;
}
pub trait UndirectedRef<'a>: GraphTypeRef<'a> {
type NeighIt: GraphIterator<Self, Item = (Self::Edge, Self::Node)>;
fn neigh_iter(&self, u: Self::Node) -> Self::NeighIt;
fn neighs(&self, u: Self::Node) -> super::GraphIter<Self, Self::NeighIt>
where
Self: Sized,
{
GraphIter(UndirectedRef::neigh_iter(self, u), self)
}
}
pub trait DirectedRef<'a>: UndirectedRef<'a> {
type OutIt: GraphIterator<Self, Item = (Self::Edge, Self::Node)>;
type InIt: GraphIterator<Self, Item = (Self::Edge, Self::Node)>;
type IncidentIt: GraphIterator<Self, Item = (Self::DirectedEdge, Self::Node)>;
type DirectedEdge: DirectedEdge<Edge = Self::Edge> + Copy + Eq;
fn out_iter(&self, u: Self::Node) -> Self::OutIt;
fn outedges(&self, u: Self::Node) -> super::GraphIter<Self, Self::OutIt>
where
Self: Sized,
{
GraphIter(DirectedRef::out_iter(self, u), self)
}
fn in_iter(&self, u: Self::Node) -> Self::InIt;
fn inedges(&self, u: Self::Node) -> super::GraphIter<Self, Self::InIt>
where
Self: Sized,
{
GraphIter(DirectedRef::in_iter(self, u), self)
}
fn incident_iter(&self, u: Self::Node) -> Self::IncidentIt;
fn incident_edges(&self, u: Self::Node) -> super::GraphIter<Self, Self::IncidentIt>
where
Self: Sized,
{
GraphIter(DirectedRef::incident_iter(self, u), self)
}
}
pub trait IndexGraphRef<'a>: UndirectedRef<'a> {
fn node_id(&self, u: Self::Node) -> usize;
fn id2node(&self, id: usize) -> Self::Node;
fn edge_id(&self, e: Self::Edge) -> usize;
fn id2edge(&self, id: usize) -> Self::Edge;
}
pub trait IndexDigraphRef<'a>: IndexGraphRef<'a> + DirectedRef<'a> {}
#[derive(Clone)]
pub struct WrapIt<I>(pub I);
impl<'a, G, I> GraphIterator<&'a G> for WrapIt<I>
where
I: GraphIterator<G>,
{
type Item = I::Item;
fn next(&mut self, g: &&'a G) -> Option<Self::Item> {
self.0.next(*g)
}
fn size_hint(&self, g: &&'a G) -> (usize, Option<usize>) {
self.0.size_hint(*g)
}
fn count(self, g: &&'a G) -> usize {
self.0.count(*g)
}
}
impl<I> From<I> for WrapIt<I> {
fn from(it: I) -> WrapIt<I> {
WrapIt(it)
}
}
impl<'a, G> GraphTypeRef<'a> for &'a G
where
G: GraphType,
{
type Node = G::Node<'a>;
type Edge = G::Edge<'a>;
}
impl<'a, G> FiniteGraphRef<'a> for &'a G
where
G: FiniteGraph,
{
type NodeIt = WrapIt<G::NodeIt<'a>>;
type EdgeIt = WrapIt<G::EdgeIt<'a>>;
fn num_nodes(&self) -> usize {
(*self).num_nodes()
}
fn nodes_iter(&self) -> Self::NodeIt {
(*self).nodes_iter().into()
}
fn num_edges(&self) -> usize {
(*self).num_edges()
}
fn edges_iter(&self) -> Self::EdgeIt {
(*self).edges_iter().into()
}
fn enodes(&self, e: Self::Edge) -> (Self::Node, Self::Node) {
(*self).enodes(e)
}
}
impl<'a, G> UndirectedRef<'a> for &'a G
where
G: Undirected,
{
type NeighIt = WrapIt<G::NeighIt<'a>>;
fn neigh_iter(&self, u: Self::Node) -> Self::NeighIt {
(*self).neigh_iter(u).into()
}
}
impl<'a, G> DirectedRef<'a> for &'a G
where
G: Directed,
{
type OutIt = WrapIt<G::OutIt<'a>>;
type InIt = WrapIt<G::InIt<'a>>;
type IncidentIt = WrapIt<G::IncidentIt<'a>>;
type DirectedEdge = G::DirectedEdge<'a>;
fn out_iter(&self, u: Self::Node) -> Self::OutIt {
(*self).out_iter(u).into()
}
fn in_iter(&self, u: Self::Node) -> Self::InIt {
(*self).in_iter(u).into()
}
fn incident_iter(&self, u: Self::Node) -> Self::IncidentIt {
(*self).incident_iter(u).into()
}
}
impl<'a, G> IndexGraphRef<'a> for &'a G
where
G: IndexGraph,
{
fn node_id(&self, u: Self::Node) -> usize {
(*self).node_id(u)
}
fn edge_id(&self, e: Self::Edge) -> usize {
(*self).edge_id(e)
}
fn id2node(&self, id: usize) -> Self::Node {
(*self).id2node(id)
}
fn id2edge(&self, id: usize) -> Self::Edge {
(*self).id2edge(id)
}
}
impl<'a, G> IndexDigraphRef<'a> for &'a G where G: IndexDigraph {}
impl<G, I> GraphIterator<NonNull<G>> for WrapIt<I>
where
I: GraphIterator<G>,
{
type Item = I::Item;
fn next(&mut self, g: &NonNull<G>) -> Option<Self::Item> {
unsafe { self.0.next(g.as_ref()) }
}
fn size_hint(&self, g: &NonNull<G>) -> (usize, Option<usize>) {
unsafe { self.0.size_hint(g.as_ref()) }
}
fn count(self, g: &NonNull<G>) -> usize {
unsafe { self.0.count(g.as_ref()) }
}
}
impl<'a, G> GraphTypeRef<'a> for NonNull<G>
where
G: GraphType,
{
type Node = G::Node<'a>;
type Edge = G::Edge<'a>;
}
impl<'a, G> FiniteGraphRef<'a> for NonNull<G>
where
G: FiniteGraph + 'a,
{
type NodeIt = WrapIt<G::NodeIt<'a>>;
type EdgeIt = WrapIt<G::EdgeIt<'a>>;
fn num_nodes(&self) -> usize {
unsafe { self.as_ref().num_nodes() }
}
fn nodes_iter(&self) -> Self::NodeIt {
unsafe { self.as_ref().nodes_iter().into() }
}
fn num_edges(&self) -> usize {
unsafe { self.as_ref().num_edges() }
}
fn edges_iter(&self) -> Self::EdgeIt {
unsafe { self.as_ref().edges_iter().into() }
}
fn enodes(&self, e: Self::Edge) -> (Self::Node, Self::Node) {
unsafe { self.as_ref().enodes(e) }
}
}
impl<'a, G> UndirectedRef<'a> for NonNull<G>
where
G: Undirected + 'a,
{
type NeighIt = WrapIt<G::NeighIt<'a>>;
fn neigh_iter(&self, u: Self::Node) -> Self::NeighIt {
unsafe { self.as_ref().neigh_iter(u).into() }
}
}
impl<'a, G> DirectedRef<'a> for NonNull<G>
where
G: Directed + 'a,
{
type OutIt = WrapIt<G::OutIt<'a>>;
type InIt = WrapIt<G::InIt<'a>>;
type IncidentIt = WrapIt<G::IncidentIt<'a>>;
type DirectedEdge = G::DirectedEdge<'a>;
fn out_iter(&self, u: Self::Node) -> Self::OutIt {
unsafe { self.as_ref().out_iter(u).into() }
}
fn in_iter(&self, u: Self::Node) -> Self::InIt {
unsafe { self.as_ref().in_iter(u).into() }
}
fn incident_iter(&self, u: Self::Node) -> Self::IncidentIt {
unsafe { self.as_ref().incident_iter(u).into() }
}
}
impl<'a, G> IndexGraphRef<'a> for NonNull<G>
where
G: IndexGraph + 'a,
{
fn node_id(&self, u: Self::Node) -> usize {
unsafe { self.as_ref().node_id(u) }
}
fn edge_id(&self, e: Self::Edge) -> usize {
unsafe { self.as_ref().edge_id(e) }
}
fn id2node(&self, id: usize) -> Self::Node {
unsafe { self.as_ref().id2node(id) }
}
fn id2edge(&self, id: usize) -> Self::Edge {
unsafe { self.as_ref().id2edge(id) }
}
}
impl<'a, G> IndexDigraphRef<'a> for NonNull<G> where G: IndexDigraph + 'a {}