blob: c0aa4c216cb5f3be3f0e2ab97c3003b8ef400d50 [file] [log] [blame]
//! Compatability implementations for deprecated graph traits.
#![allow(deprecated)]
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[cfg(feature = "alloc")]
use crate::deprecated::data::{Build, Create, DataMap, FromElements};
#[cfg(feature = "fixedbitset")]
use crate::deprecated::visit::GetAdjacencyMatrix;
use crate::{
deprecated::visit::{
Data, EdgeCount, EdgeIndexable, FilterNode, GraphBase, IntoEdgeReferences, IntoEdges,
IntoEdgesDirected, IntoNeighbors, IntoNeighborsDirected, IntoNodeIdentifiers,
IntoNodeReferences, NodeCompactIndexable, NodeCount, NodeIndexable, VisitMap, Visitable,
},
edge::{Direction, Edge, EdgeId},
graph::Graph,
node::{Node, NodeId},
storage::{
auxiliary::{BooleanGraphStorage, Hints},
sequential::GraphIdBijection,
DirectedGraphStorage, GraphStorage,
},
};
impl<S> GraphBase for Graph<S>
where
S: GraphStorage,
{
type EdgeId = EdgeId;
type NodeId = NodeId;
}
// TODO: GraphProp?!
impl<S> NodeCount for Graph<S>
where
S: GraphStorage,
{
fn node_count(&self) -> usize {
self.num_nodes()
}
}
impl<S> NodeIndexable for Graph<S>
where
S: GraphStorage,
{
fn node_bound(&self) -> usize {
self.num_nodes()
}
fn to_index(&self, a: Self::NodeId) -> usize {
self.storage.node_id_bijection().index(a)
}
fn from_index(&self, i: usize) -> Self::NodeId {
self.storage
.node_id_bijection()
.reverse(i)
.expect("unable to determine index")
}
}
impl<S> NodeCompactIndexable for Graph<S> where S: GraphStorage {}
impl<S> EdgeCount for Graph<S>
where
S: GraphStorage,
{
fn edge_count(&self) -> usize {
self.num_edges()
}
}
impl<S> EdgeIndexable for Graph<S>
where
S: GraphStorage,
{
fn edge_bound(&self) -> usize {
self.num_edges()
}
fn to_index(&self, a: Self::EdgeId) -> usize {
self.storage.edge_id_bijection().index(a)
}
fn from_index(&self, i: usize) -> Self::EdgeId {
self.storage
.edge_id_bijection()
.reverse(i)
.expect("unable to determine index")
}
}
impl<S> Data for Graph<S>
where
S: GraphStorage,
{
type EdgeWeight = S::EdgeWeight;
type NodeWeight = S::NodeWeight;
}
impl<S> IntoNodeIdentifiers for &Graph<S>
where
S: GraphStorage,
{
type NodeIdentifiers = impl Iterator<Item = Self::NodeId>;
fn node_identifiers(self) -> Self::NodeIdentifiers {
self.nodes().map(|node| node.id())
}
}
impl<'a, S> IntoNodeReferences for &'a Graph<S>
where
S: GraphStorage,
{
type NodeRef = Node<'a, S>;
type NodeReferences = impl Iterator<Item = Self::NodeRef>;
fn node_references(self) -> Self::NodeReferences {
self.nodes()
}
}
impl<'a, S> IntoEdgeReferences for &'a Graph<S>
where
S: GraphStorage,
{
type EdgeRef = Edge<'a, S>;
type EdgeReferences = impl Iterator<Item = Self::EdgeRef>;
fn edge_references(self) -> Self::EdgeReferences {
self.edges()
}
}
#[cfg(feature = "alloc")]
impl<'a, S> IntoNeighbors for &'a Graph<S>
where
S: GraphStorage,
{
type Neighbors = impl Iterator<Item = Self::NodeId>;
fn neighbors(self, n: Self::NodeId) -> Self::Neighbors {
// This is a bit inefficient, but just glue code to deprecated trait impls, so fine.
// We make use of `&n` in the trait and the iterator is bound to it, which means that we
// need to collect to avoid having a lifetime we created in this code.
// we _could_ in theory also use `Cow` here, but that's a bit overkill.
self.neighbours(n)
.map(|node| node.id())
.collect::<Vec<_>>()
.into_iter()
}
}
#[cfg(feature = "alloc")]
impl<'a, S> IntoNeighborsDirected for &'a Graph<S>
where
S: DirectedGraphStorage,
{
type NeighborsDirected = impl Iterator<Item = Self::NodeId>;
fn neighbors_directed(self, n: Self::NodeId, d: Direction) -> Self::NeighborsDirected {
// see comment in `IntoNeighbors` for why we need to collect here.
self.neighbours_directed(n, d)
.map(|node| node.id())
.collect::<Vec<_>>()
.into_iter()
}
}
#[cfg(feature = "alloc")]
impl<'a, S> IntoEdges for &'a Graph<S>
where
S: GraphStorage,
{
type Edges = impl Iterator<Item = Self::EdgeRef>;
fn edges(self, a: Self::NodeId) -> Self::Edges {
// see comment in `IntoNeighbors` for why we need to collect here.
self.connections(a).collect::<Vec<_>>().into_iter()
}
}
#[cfg(feature = "alloc")]
impl<'a, S> IntoEdgesDirected for &'a Graph<S>
where
S: DirectedGraphStorage,
{
type EdgesDirected = impl Iterator<Item = Self::EdgeRef>;
fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::EdgesDirected {
// see comment in `IntoNeighbors` for why we need to collect here.
self.connections_directed(a, dir)
.collect::<Vec<_>>()
.into_iter()
}
}
pub struct NodeVisitationMap<'a, S>
where
S: GraphStorage + 'a,
{
inner: S::BooleanNodeStorage<'a>,
}
impl<'a, S> VisitMap<NodeId> for NodeVisitationMap<'a, S>
where
S: GraphStorage + 'a,
{
fn visit(&mut self, a: NodeId) -> bool {
self.inner.set(a, true).is_none()
}
fn is_visited(&self, a: &NodeId) -> bool {
self.inner.get(*a).unwrap_or(false)
}
}
impl<'a, S> FilterNode<NodeId> for NodeVisitationMap<'a, S>
where
S: GraphStorage + 'a,
{
fn include_node(&self, node: NodeId) -> bool {
self.is_visited(&node)
}
}
impl<'a, S> Visitable for &'a Graph<S>
where
S: GraphStorage,
{
type Map = NodeVisitationMap<'a, S>;
fn visit_map(&self) -> Self::Map {
NodeVisitationMap {
inner: self.storage.boolean_node_storage(Hints::default()),
}
}
fn reset_map(&self, map: &mut Self::Map) {
map.inner.fill(false);
}
}
#[cfg(feature = "fixedbitset")]
impl<S> GetAdjacencyMatrix for Graph<S>
where
S: GraphStorage,
{
type AdjMatrix = ();
fn adjacency_matrix(&self) -> Self::AdjMatrix {}
fn is_adjacent(&self, (): &Self::AdjMatrix, a: Self::NodeId, b: Self::NodeId) -> bool {
self.edges_between(a, b).next().is_some()
}
}
#[cfg(feature = "alloc")]
impl<S> DataMap for Graph<S>
where
S: GraphStorage,
{
fn node_weight(&self, id: Self::NodeId) -> Option<&Self::NodeWeight> {
self.node(id).map(|node| node.weight())
}
fn edge_weight(&self, id: Self::EdgeId) -> Option<&Self::EdgeWeight> {
self.edge(id).map(|edge| edge.weight())
}
}
#[cfg(feature = "alloc")]
impl<S> Build for Graph<S>
where
S: GraphStorage,
{
fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
self.insert_node(weight).id()
}
fn update_edge(
&mut self,
a: Self::NodeId,
b: Self::NodeId,
weight: Self::EdgeWeight,
) -> Self::EdgeId {
self.insert_edge(weight, a, b).id()
}
}
#[cfg(feature = "alloc")]
impl<S> Create for Graph<S>
where
S: GraphStorage,
{
fn with_capacity(nodes: usize, edges: usize) -> Self {
Self::with_capacity(Some(nodes), Some(edges))
}
}
#[cfg(feature = "alloc")]
impl<S> FromElements for Graph<S> where S: GraphStorage {}