use crate::adjacencies::{InEdges, Neighbors, OutEdges};
pub mod refs;
pub trait GraphType<'a> {
type Node: 'a + Copy + Eq;
type Edge: 'a + Copy + Eq;
}
pub trait GraphSize<'a>: GraphType<'a> {
type NodeIter: 'a + Iterator<Item = Self::Node>;
type EdgeIter: 'a + Iterator<Item = Self::Edge>;
fn num_nodes(&self) -> usize;
fn num_edges(&self) -> usize;
fn nodes(&'a self) -> Self::NodeIter;
fn edges(&'a self) -> Self::EdgeIter;
}
pub struct NeighIter<'a, G>(&'a G, Option<G::Neigh>)
where
G: Undirected<'a>;
impl<'a, G> Iterator for NeighIter<'a, G>
where
G: Undirected<'a>,
{
type Item = (G::Edge, G::Node);
fn next(&mut self) -> Option<Self::Item> {
if let Some(it) = self.1.take() {
let ev = self.0.get_neigh(&it);
self.1 = self.0.next_neigh(it);
Some(ev)
} else {
None
}
}
}
pub trait Undirected<'a>: GraphSize<'a> {
type Neigh: 'a + Clone;
fn enodes(&'a self, e: Self::Edge) -> (Self::Node, Self::Node);
fn first_neigh(&'a self, u: Self::Node) -> Option<Self::Neigh>;
fn next_neigh(&'a self, it: Self::Neigh) -> Option<Self::Neigh>;
fn get_neigh(&'a self, it: &Self::Neigh) -> (Self::Edge, Self::Node);
fn neighs(&'a self, u: Self::Node) -> NeighIter<Self>
where
Self: Sized,
{
NeighIter(self, self.first_neigh(u))
}
fn neighbors(&'a self) -> Neighbors<'a, Self>
where
Self: Sized,
{
Neighbors(self)
}
}
pub trait DirectedEdge {
type Edge;
fn is_incoming(&self) -> bool;
fn is_outgoing(&self) -> bool {
!self.is_incoming()
}
fn edge(&self) -> Self::Edge;
}
pub struct OutEdgeIter<'a, G>(pub &'a G, pub Option<G::OutEdge>)
where
G: Directed<'a>;
impl<'a, G> Iterator for OutEdgeIter<'a, G>
where
G: Directed<'a>,
{
type Item = (G::Edge, G::Node);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.1.take().map(|it| {
let ev = self.0.get_out(&it);
self.1 = self.0.next_out(it);
ev
})
}
}
pub struct InEdgeIter<'a, G>(&'a G, Option<G::InEdge>)
where
G: Directed<'a>;
impl<'a, G> Iterator for InEdgeIter<'a, G>
where
G: Directed<'a>,
{
type Item = (G::Edge, G::Node);
fn next(&mut self) -> Option<Self::Item> {
if let Some(it) = self.1.take() {
let ev = self.0.get_in(&it);
self.1 = self.0.next_in(it);
Some(ev)
} else {
None
}
}
}
pub struct IncidentEdgeIter<'a, G>(&'a G, Option<G::IncidentEdge>)
where
G: Directed<'a>;
impl<'a, G> Iterator for IncidentEdgeIter<'a, G>
where
G: Directed<'a>,
{
type Item = (G::DirectedEdge, G::Node);
fn next(&mut self) -> Option<Self::Item> {
if let Some(it) = self.1.take() {
let ev = self.0.get_incident(&it);
self.1 = self.0.next_incident(it);
Some(ev)
} else {
None
}
}
}
pub trait Directed<'a>: Undirected<'a> {
type OutEdge: 'a + Clone;
type InEdge: 'a + Clone;
type IncidentEdge: 'a + Clone;
type DirectedEdge: 'a + DirectedEdge<Edge = Self::Edge> + Copy + Eq;
fn src(&'a self, e: Self::Edge) -> Self::Node;
fn snk(&'a self, e: Self::Edge) -> Self::Node;
fn first_out(&'a self, u: Self::Node) -> Option<Self::OutEdge>;
fn next_out(&'a self, it: Self::OutEdge) -> Option<Self::OutEdge>;
fn get_out(&'a self, it: &Self::OutEdge) -> (Self::Edge, Self::Node);
fn outedges(&'a self, u: Self::Node) -> OutEdgeIter<'a, Self>
where
Self: Sized,
{
OutEdgeIter(self, self.first_out(u))
}
fn outgoing(&'a self) -> OutEdges<'a, Self>
where
Self: Sized,
{
OutEdges(self)
}
fn first_in(&'a self, u: Self::Node) -> Option<Self::InEdge>;
fn next_in(&'a self, it: Self::InEdge) -> Option<Self::InEdge>;
fn get_in(&'a self, it: &Self::InEdge) -> (Self::Edge, Self::Node);
fn inedges(&'a self, u: Self::Node) -> InEdgeIter<'a, Self>
where
Self: Sized,
{
InEdgeIter(self, self.first_in(u))
}
fn incoming(&'a self) -> InEdges<'a, Self>
where
Self: Sized,
{
InEdges(self)
}
fn first_incident(&'a self, u: Self::Node) -> Option<Self::IncidentEdge>;
fn next_incident(&'a self, it: Self::IncidentEdge) -> Option<Self::IncidentEdge>;
fn get_incident(&'a self, it: &Self::IncidentEdge) -> (Self::DirectedEdge, Self::Node);
fn incident_edges(&'a self, u: Self::Node) -> IncidentEdgeIter<'a, Self>
where
Self: Sized,
{
IncidentEdgeIter(self, self.first_incident(u))
}
}
pub trait Graph<'a>: GraphSize<'a> + Undirected<'a> {}
impl<'a, G> Graph<'a> for G where G: GraphSize<'a> + Undirected<'a> {}
pub trait Digraph<'a>: Graph<'a> + Directed<'a> {}
impl<'a, G> Digraph<'a> for G where G: GraphSize<'a> + Directed<'a> {}
pub trait Indexable {
fn index(&self) -> usize;
}
pub trait IndexGraph<'a>: Graph<'a> {
fn node_id(&self, u: Self::Node) -> usize;
fn id2node(&'a self, id: usize) -> Self::Node;
fn edge_id(&self, e: Self::Edge) -> usize;
fn id2edge(&'a self, id: usize) -> Self::Edge;
}
pub trait IndexDigraph<'a>: IndexGraph<'a> + Digraph<'a> {}
impl<'a, T> IndexDigraph<'a> for T where T: IndexGraph<'a> + Digraph<'a> {}
pub trait NumberedGraph<'a>: Graph<'a>
where
<Self as GraphType<'a>>::Node: Indexable,
<Self as GraphType<'a>>::Edge: Indexable,
{
}
impl<'a, G> NumberedGraph<'a> for G
where
G: Graph<'a>,
G::Node: Indexable,
G::Edge: Indexable,
{
}
pub trait NumberedDigraph<'a>: NumberedGraph<'a> + Digraph<'a>
where
<Self as GraphType<'a>>::Node: Indexable,
<Self as GraphType<'a>>::Edge: Indexable,
{
}
impl<'a, G> NumberedDigraph<'a> for G
where
G: Digraph<'a> + NumberedGraph<'a>,
G::Node: Indexable,
G::Edge: Indexable,
{
}
impl<'a, 'g: 'a, G> GraphType<'a> for &'g G
where
G: GraphType<'g>,
{
type Node = G::Node;
type Edge = G::Edge;
}
impl<'a, 'g: 'a, G> GraphSize<'a> for &'g G
where
G: GraphSize<'g>,
{
type NodeIter = G::NodeIter;
type EdgeIter = G::EdgeIter;
fn num_nodes(&self) -> usize {
(*self).num_nodes()
}
fn num_edges(&self) -> usize {
(*self).num_edges()
}
fn nodes(&'a self) -> Self::NodeIter {
(*self).nodes()
}
fn edges(&'a self) -> Self::EdgeIter {
(*self).edges()
}
}
impl<'a, 'g: 'a, G> Undirected<'a> for &'g G
where
G: Undirected<'g>,
{
type Neigh = G::Neigh;
fn enodes(&'a self, e: Self::Edge) -> (Self::Node, Self::Node) {
(*self).enodes(e)
}
fn first_neigh(&'a self, u: Self::Node) -> Option<Self::Neigh> {
(*self).first_neigh(u)
}
fn next_neigh(&'a self, it: Self::Neigh) -> Option<Self::Neigh> {
(*self).next_neigh(it)
}
fn get_neigh(&'a self, it: &Self::Neigh) -> (Self::Edge, Self::Node) {
(*self).get_neigh(it)
}
}
impl<'a, 'g: 'a, G> IndexGraph<'a> for &'g G
where
G: IndexGraph<'g>,
{
fn node_id(&self, u: Self::Node) -> usize {
(*self).node_id(u)
}
fn id2node(&'a self, id: usize) -> Self::Node {
(*self).id2node(id)
}
fn edge_id(&self, e: Self::Edge) -> usize {
(*self).edge_id(e)
}
fn id2edge(&'a self, id: usize) -> Self::Edge {
(*self).id2edge(id)
}
}
impl<'a, 'g: 'a, G> Directed<'a> for &'g G
where
G: Directed<'g>,
{
type OutEdge = G::OutEdge;
type InEdge = G::InEdge;
type IncidentEdge = G::IncidentEdge;
type DirectedEdge = G::DirectedEdge;
fn src(&'a self, e: Self::Edge) -> Self::Node {
(*self).src(e)
}
fn snk(&'a self, e: Self::Edge) -> Self::Node {
(*self).snk(e)
}
fn first_out(&'a self, u: Self::Node) -> Option<Self::OutEdge> {
(*self).first_out(u)
}
fn next_out(&'a self, it: Self::OutEdge) -> Option<Self::OutEdge> {
(*self).next_out(it)
}
fn get_out(&'a self, it: &Self::OutEdge) -> (Self::Edge, Self::Node) {
(*self).get_out(it)
}
fn first_in(&'a self, u: Self::Node) -> Option<Self::InEdge> {
(*self).first_in(u)
}
fn next_in(&'a self, it: Self::InEdge) -> Option<Self::InEdge> {
(*self).next_in(it)
}
fn get_in(&'a self, it: &Self::InEdge) -> (Self::Edge, Self::Node) {
(*self).get_in(it)
}
fn first_incident(&'a self, u: Self::Node) -> Option<Self::IncidentEdge> {
(*self).first_incident(u)
}
fn next_incident(&'a self, it: Self::IncidentEdge) -> Option<Self::IncidentEdge> {
(*self).next_incident(it)
}
fn get_incident(&'a self, it: &Self::IncidentEdge) -> (Self::DirectedEdge, Self::Node) {
(*self).get_incident(it)
}
}
impl<'a, G> refs::GraphSizeRef<'a> for &'a G
where
G: GraphSize<'a>,
{
fn nodes(&self) -> Self::NodeIter {
(*self).nodes()
}
fn edges(&self) -> Self::EdgeIter {
(*self).edges()
}
}
impl<'a, G> refs::UndirectedRef<'a> for &'a G
where
G: Undirected<'a>,
{
fn enodes(&self, e: Self::Edge) -> (Self::Node, Self::Node) {
(*self).enodes(e)
}
fn first_neigh(&self, u: Self::Node) -> Option<Self::Neigh> {
(*self).first_neigh(u)
}
fn next_neigh(&self, it: Self::Neigh) -> Option<Self::Neigh> {
(*self).next_neigh(it)
}
fn get_neigh(&self, it: &Self::Neigh) -> (Self::Edge, Self::Node) {
(*self).get_neigh(it)
}
}
impl<'a, G> refs::DirectedRef<'a> for &'a G
where
G: Directed<'a>,
{
fn src(&self, u: Self::Edge) -> Self::Node {
(*self).src(u)
}
fn snk(&self, u: Self::Edge) -> Self::Node {
(*self).snk(u)
}
fn first_out(&self, u: Self::Node) -> Option<Self::OutEdge> {
(*self).first_out(u)
}
fn next_out(&self, it: Self::OutEdge) -> Option<Self::OutEdge> {
(*self).next_out(it)
}
fn get_out(&self, it: &Self::OutEdge) -> (Self::Edge, Self::Node) {
(*self).get_out(it)
}
fn first_in(&self, u: Self::Node) -> Option<Self::InEdge> {
(*self).first_in(u)
}
fn next_in(&self, it: Self::InEdge) -> Option<Self::InEdge> {
(*self).next_in(it)
}
fn get_in(&self, it: &Self::InEdge) -> (Self::Edge, Self::Node) {
(*self).get_in(it)
}
fn first_incident(&self, u: Self::Node) -> Option<Self::IncidentEdge> {
(*self).first_incident(u)
}
fn next_incident(&self, it: Self::IncidentEdge) -> Option<Self::IncidentEdge> {
(*self).next_incident(it)
}
fn get_incident(&self, it: &Self::IncidentEdge) -> (Self::DirectedEdge, Self::Node) {
(*self).get_incident(it)
}
}
impl<'a, G> refs::IndexGraphRef<'a> for &'a G
where
G: IndexGraph<'a>,
{
fn id2node(&self, id: usize) -> Self::Node {
(*self).id2node(id)
}
fn id2edge(&self, id: usize) -> Self::Edge {
(*self).id2edge(id)
}
}