pub use self::filter::*;
pub use self::reversed::*;
pub use self::undirected_adaptor::*;
#[macro_use]
mod macros;
mod dfsvisit;
mod traversal;
pub use self::dfsvisit::*;
pub use self::traversal::*;
use core::hash::{BuildHasher, Hash};
use fixedbitset::FixedBitSet;
use hashbrown::HashSet;
use super::EdgeType;
use crate::prelude::Direction;
use crate::graph::IndexType;
trait_template! {
pub trait GraphBase {
@escape [type NodeId]
@escape [type EdgeId]
@section nodelegate
type EdgeId: Copy + PartialEq;
type NodeId: Copy + PartialEq;
}
}
GraphBase! {delegate_impl []}
GraphBase! {delegate_impl [['a, G], G, &'a mut G, deref]}
pub trait GraphRef: Copy + GraphBase {}
impl<G> GraphRef for &G where G: GraphBase {}
trait_template! {
pub trait IntoNeighbors : GraphRef {
@section type
type Neighbors: Iterator<Item=Self::NodeId>;
@section self
fn neighbors(self, a: Self::NodeId) -> Self::Neighbors;
}
}
IntoNeighbors! {delegate_impl []}
trait_template! {
pub trait IntoNeighborsDirected : IntoNeighbors {
@section type
type NeighborsDirected: Iterator<Item=Self::NodeId>;
@section self
fn neighbors_directed(self, n: Self::NodeId, d: Direction)
-> Self::NeighborsDirected;
}
}
trait_template! {
pub trait IntoEdges : IntoEdgeReferences + IntoNeighbors {
@section type
type Edges: Iterator<Item=Self::EdgeRef>;
@section self
fn edges(self, a: Self::NodeId) -> Self::Edges;
}
}
IntoEdges! {delegate_impl []}
trait_template! {
pub trait IntoEdgesDirected : IntoEdges + IntoNeighborsDirected {
@section type
type EdgesDirected: Iterator<Item=Self::EdgeRef>;
@section self
fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::EdgesDirected;
}
}
IntoEdgesDirected! {delegate_impl []}
trait_template! {
pub trait IntoNodeIdentifiers : GraphRef {
@section type
type NodeIdentifiers: Iterator<Item=Self::NodeId>;
@section self
fn node_identifiers(self) -> Self::NodeIdentifiers;
}
}
IntoNodeIdentifiers! {delegate_impl []}
IntoNeighborsDirected! {delegate_impl []}
trait_template! {
pub trait Data : GraphBase {
@section type
type NodeWeight;
type EdgeWeight;
}
}
Data! {delegate_impl []}
Data! {delegate_impl [['a, G], G, &'a mut G, deref]}
pub trait EdgeRef: Copy {
type NodeId;
type EdgeId;
type Weight;
fn source(&self) -> Self::NodeId;
fn target(&self) -> Self::NodeId;
fn weight(&self) -> &Self::Weight;
fn id(&self) -> Self::EdgeId;
}
impl<N, E> EdgeRef for (N, N, &E)
where
N: Copy,
{
type NodeId = N;
type EdgeId = (N, N);
type Weight = E;
fn source(&self) -> N {
self.0
}
fn target(&self) -> N {
self.1
}
fn weight(&self) -> &E {
self.2
}
fn id(&self) -> (N, N) {
(self.0, self.1)
}
}
pub trait NodeRef: Copy {
type NodeId;
type Weight;
fn id(&self) -> Self::NodeId;
fn weight(&self) -> &Self::Weight;
}
trait_template! {
pub trait IntoNodeReferences : Data + IntoNodeIdentifiers {
@section type
type NodeRef: NodeRef<NodeId=Self::NodeId, Weight=Self::NodeWeight>;
type NodeReferences: Iterator<Item=Self::NodeRef>;
@section self
fn node_references(self) -> Self::NodeReferences;
}
}
IntoNodeReferences! {delegate_impl []}
impl<Id> NodeRef for (Id, ())
where
Id: Copy,
{
type NodeId = Id;
type Weight = ();
fn id(&self) -> Self::NodeId {
self.0
}
fn weight(&self) -> &Self::Weight {
static DUMMY: () = ();
&DUMMY
}
}
impl<Id, W> NodeRef for (Id, &W)
where
Id: Copy,
{
type NodeId = Id;
type Weight = W;
fn id(&self) -> Self::NodeId {
self.0
}
fn weight(&self) -> &Self::Weight {
self.1
}
}
trait_template! {
pub trait IntoEdgeReferences : Data + GraphRef {
@section type
type EdgeRef: EdgeRef<NodeId=Self::NodeId, EdgeId=Self::EdgeId,
Weight=Self::EdgeWeight>;
type EdgeReferences: Iterator<Item=Self::EdgeRef>;
@section self
fn edge_references(self) -> Self::EdgeReferences;
}
}
IntoEdgeReferences! {delegate_impl [] }
trait_template! {
pub trait GraphProp : GraphBase {
@section type
type EdgeType: EdgeType;
@section nodelegate
fn is_directed(&self) -> bool {
<Self::EdgeType>::is_directed()
}
}
}
GraphProp! {delegate_impl []}
trait_template! {
#[allow(clippy::needless_arbitrary_self_type)]
pub trait NodeIndexable : GraphBase {
@section self
fn node_bound(self: &Self) -> usize;
#[track_caller]
fn to_index(self: &Self, a: Self::NodeId) -> usize;
#[track_caller]
fn from_index(self: &Self, i: usize) -> Self::NodeId;
}
}
NodeIndexable! {delegate_impl []}
trait_template! {
#[allow(clippy::needless_arbitrary_self_type)]
pub trait EdgeIndexable : GraphBase {
@section self
fn edge_bound(self: &Self) -> usize;
#[track_caller]
fn to_index(self: &Self, a: Self::EdgeId) -> usize;
#[track_caller]
fn from_index(self: &Self, i: usize) -> Self::EdgeId;
}
}
EdgeIndexable! {delegate_impl []}
trait_template! {
#[allow(clippy::needless_arbitrary_self_type)]
pub trait NodeCount : GraphBase {
@section self
fn node_count(self: &Self) -> usize;
}
}
NodeCount! {delegate_impl []}
trait_template! {
pub trait NodeCompactIndexable : NodeIndexable + NodeCount { }
}
NodeCompactIndexable! {delegate_impl []}
pub trait VisitMap<N> {
fn visit(&mut self, a: N) -> bool;
fn is_visited(&self, a: &N) -> bool;
fn unvisit(&mut self, _a: N) -> bool;
}
impl<Ix> VisitMap<Ix> for FixedBitSet
where
Ix: IndexType,
{
fn visit(&mut self, x: Ix) -> bool {
!self.put(x.index())
}
fn is_visited(&self, x: &Ix) -> bool {
self.contains(x.index())
}
fn unvisit(&mut self, x: Ix) -> bool {
if self.is_visited(&x) {
self.toggle(x.index());
return true;
}
false
}
}
impl<N, S> VisitMap<N> for HashSet<N, S>
where
N: Hash + Eq,
S: BuildHasher,
{
fn visit(&mut self, x: N) -> bool {
self.insert(x)
}
fn is_visited(&self, x: &N) -> bool {
self.contains(x)
}
fn unvisit(&mut self, x: N) -> bool {
self.remove(&x)
}
}
#[cfg(feature = "std")]
impl<N, S> VisitMap<N> for std::collections::HashSet<N, S>
where
N: Hash + Eq,
S: BuildHasher,
{
fn visit(&mut self, x: N) -> bool {
self.insert(x)
}
fn is_visited(&self, x: &N) -> bool {
self.contains(x)
}
fn unvisit(&mut self, x: N) -> bool {
self.remove(&x)
}
}
trait_template! {
#[allow(clippy::needless_arbitrary_self_type)]
pub trait Visitable : GraphBase {
@section type
type Map: VisitMap<Self::NodeId>;
@section self
fn visit_map(self: &Self) -> Self::Map;
fn reset_map(self: &Self, map: &mut Self::Map);
}
}
Visitable! {delegate_impl []}
trait_template! {
#[allow(clippy::needless_arbitrary_self_type)]
pub trait GetAdjacencyMatrix : GraphBase {
@section type
type AdjMatrix;
@section self
fn adjacency_matrix(self: &Self) -> Self::AdjMatrix;
fn is_adjacent(self: &Self, matrix: &Self::AdjMatrix, a: Self::NodeId, b: Self::NodeId) -> bool;
}
}
GetAdjacencyMatrix! {delegate_impl []}
trait_template! {
#[allow(clippy::needless_arbitrary_self_type)]
pub trait EdgeCount : GraphBase {
@section self
fn edge_count(self: &Self) -> usize;
}
}
EdgeCount! {delegate_impl []}
mod filter;
mod reversed;
mod undirected_adaptor;