use std::cmp;
use std::fmt;
use std::hash::Hash;
use std::iter;
use std::marker::PhantomData;
use std::mem::size_of;
use std::ops::{Index, IndexMut, Range};
use std::slice;
use fixedbitset::FixedBitSet;
use crate::{Directed, Direction, EdgeType, Incoming, IntoWeightedEdge, Outgoing, Undirected};
use crate::iter_format::{DebugMap, IterFormatExt, NoPretty};
use crate::util::enumerate;
use crate::visit;
#[cfg(feature = "serde-1")]
mod serialization;
pub type DefaultIx = u32;
pub unsafe trait IndexType: Copy + Default + Hash + Ord + fmt::Debug + 'static {
fn new(x: usize) -> Self;
fn index(&self) -> usize;
fn max() -> Self;
}
unsafe impl IndexType for usize {
#[inline(always)]
fn new(x: usize) -> Self {
x
}
#[inline(always)]
fn index(&self) -> Self {
*self
}
#[inline(always)]
fn max() -> Self {
::std::usize::MAX
}
}
unsafe impl IndexType for u32 {
#[inline(always)]
fn new(x: usize) -> Self {
x as u32
}
#[inline(always)]
fn index(&self) -> usize {
*self as usize
}
#[inline(always)]
fn max() -> Self {
::std::u32::MAX
}
}
unsafe impl IndexType for u16 {
#[inline(always)]
fn new(x: usize) -> Self {
x as u16
}
#[inline(always)]
fn index(&self) -> usize {
*self as usize
}
#[inline(always)]
fn max() -> Self {
::std::u16::MAX
}
}
unsafe impl IndexType for u8 {
#[inline(always)]
fn new(x: usize) -> Self {
x as u8
}
#[inline(always)]
fn index(&self) -> usize {
*self as usize
}
#[inline(always)]
fn max() -> Self {
::std::u8::MAX
}
}
#[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub struct NodeIndex<Ix = DefaultIx>(Ix);
impl<Ix: IndexType> NodeIndex<Ix> {
#[inline]
pub fn new(x: usize) -> Self {
NodeIndex(IndexType::new(x))
}
#[inline]
pub fn index(self) -> usize {
self.0.index()
}
#[inline]
pub fn end() -> Self {
NodeIndex(IndexType::max())
}
fn _into_edge(self) -> EdgeIndex<Ix> {
EdgeIndex(self.0)
}
}
unsafe impl<Ix: IndexType> IndexType for NodeIndex<Ix> {
fn index(&self) -> usize {
self.0.index()
}
fn new(x: usize) -> Self {
NodeIndex::new(x)
}
fn max() -> Self {
NodeIndex(<Ix as IndexType>::max())
}
}
impl<Ix: IndexType> From<Ix> for NodeIndex<Ix> {
fn from(ix: Ix) -> Self {
NodeIndex(ix)
}
}
impl<Ix: fmt::Debug> fmt::Debug for NodeIndex<Ix> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "NodeIndex({:?})", self.0)
}
}
pub fn node_index<Ix: IndexType>(index: usize) -> NodeIndex<Ix> {
NodeIndex::new(index)
}
pub fn edge_index<Ix: IndexType>(index: usize) -> EdgeIndex<Ix> {
EdgeIndex::new(index)
}
#[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub struct EdgeIndex<Ix = DefaultIx>(Ix);
impl<Ix: IndexType> EdgeIndex<Ix> {
#[inline]
pub fn new(x: usize) -> Self {
EdgeIndex(IndexType::new(x))
}
#[inline]
pub fn index(self) -> usize {
self.0.index()
}
#[inline]
pub fn end() -> Self {
EdgeIndex(IndexType::max())
}
fn _into_node(self) -> NodeIndex<Ix> {
NodeIndex(self.0)
}
}
impl<Ix: IndexType> From<Ix> for EdgeIndex<Ix> {
fn from(ix: Ix) -> Self {
EdgeIndex(ix)
}
}
impl<Ix: fmt::Debug> fmt::Debug for EdgeIndex<Ix> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "EdgeIndex({:?})", self.0)
}
}
const DIRECTIONS: [Direction; 2] = [Outgoing, Incoming];
#[derive(Debug)]
pub struct Node<N, Ix = DefaultIx> {
pub weight: N,
next: [EdgeIndex<Ix>; 2],
}
impl<E, Ix> Clone for Node<E, Ix>
where
E: Clone,
Ix: Copy,
{
clone_fields!(Node, weight, next,);
}
impl<N, Ix: IndexType> Node<N, Ix> {
pub fn next_edge(&self, dir: Direction) -> EdgeIndex<Ix> {
self.next[dir.index()]
}
}
#[derive(Debug)]
pub struct Edge<E, Ix = DefaultIx> {
pub weight: E,
next: [EdgeIndex<Ix>; 2],
node: [NodeIndex<Ix>; 2],
}
impl<E, Ix> Clone for Edge<E, Ix>
where
E: Clone,
Ix: Copy,
{
clone_fields!(Edge, weight, next, node,);
}
impl<E, Ix: IndexType> Edge<E, Ix> {
pub fn next_edge(&self, dir: Direction) -> EdgeIndex<Ix> {
self.next[dir.index()]
}
pub fn source(&self) -> NodeIndex<Ix> {
self.node[0]
}
pub fn target(&self) -> NodeIndex<Ix> {
self.node[1]
}
}
pub struct Graph<N, E, Ty = Directed, Ix = DefaultIx> {
nodes: Vec<Node<N, Ix>>,
edges: Vec<Edge<E, Ix>>,
ty: PhantomData<Ty>,
}
pub type DiGraph<N, E, Ix = DefaultIx> = Graph<N, E, Directed, Ix>;
pub type UnGraph<N, E, Ix = DefaultIx> = Graph<N, E, Undirected, Ix>;
impl<N, E, Ty, Ix: IndexType> Clone for Graph<N, E, Ty, Ix>
where
N: Clone,
E: Clone,
{
fn clone(&self) -> Self {
Graph {
nodes: self.nodes.clone(),
edges: self.edges.clone(),
ty: self.ty,
}
}
fn clone_from(&mut self, rhs: &Self) {
self.nodes.clone_from(&rhs.nodes);
self.edges.clone_from(&rhs.edges);
self.ty = rhs.ty;
}
}
impl<N, E, Ty, Ix> fmt::Debug for Graph<N, E, Ty, Ix>
where
N: fmt::Debug,
E: fmt::Debug,
Ty: EdgeType,
Ix: IndexType,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let etype = if self.is_directed() {
"Directed"
} else {
"Undirected"
};
let mut fmt_struct = f.debug_struct("Graph");
fmt_struct.field("Ty", &etype);
fmt_struct.field("node_count", &self.node_count());
fmt_struct.field("edge_count", &self.edge_count());
if self.edge_count() > 0 {
fmt_struct.field(
"edges",
&self
.edges
.iter()
.map(|e| NoPretty((e.source().index(), e.target().index())))
.format(", "),
);
}
if size_of::<N>() != 0 {
fmt_struct.field(
"node weights",
&DebugMap(|| self.nodes.iter().map(|n| &n.weight).enumerate()),
);
}
if size_of::<E>() != 0 {
fmt_struct.field(
"edge weights",
&DebugMap(|| self.edges.iter().map(|n| &n.weight).enumerate()),
);
}
fmt_struct.finish()
}
}
enum Pair<T> {
Both(T, T),
One(T),
None,
}
use std::cmp::max;
fn index_twice<T>(slc: &mut [T], a: usize, b: usize) -> Pair<&mut T> {
if max(a, b) >= slc.len() {
Pair::None
} else if a == b {
Pair::One(&mut slc[max(a, b)])
} else {
unsafe {
let ptr = slc.as_mut_ptr();
let ar = &mut *ptr.add(a);
let br = &mut *ptr.add(b);
Pair::Both(ar, br)
}
}
}
impl<N, E> Graph<N, E, Directed> {
pub fn new() -> Self {
Graph {
nodes: Vec::new(),
edges: Vec::new(),
ty: PhantomData,
}
}
}
impl<N, E> Graph<N, E, Undirected> {
pub fn new_undirected() -> Self {
Graph {
nodes: Vec::new(),
edges: Vec::new(),
ty: PhantomData,
}
}
}
impl<N, E, Ty, Ix> Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
pub fn with_capacity(nodes: usize, edges: usize) -> Self {
Graph {
nodes: Vec::with_capacity(nodes),
edges: Vec::with_capacity(edges),
ty: PhantomData,
}
}
pub fn node_count(&self) -> usize {
self.nodes.len()
}
pub fn edge_count(&self) -> usize {
self.edges.len()
}
#[inline]
pub fn is_directed(&self) -> bool {
Ty::is_directed()
}
pub fn add_node(&mut self, weight: N) -> NodeIndex<Ix> {
let node = Node {
weight,
next: [EdgeIndex::end(), EdgeIndex::end()],
};
let node_idx = NodeIndex::new(self.nodes.len());
assert!(<Ix as IndexType>::max().index() == !0 || NodeIndex::end() != node_idx);
self.nodes.push(node);
node_idx
}
pub fn node_weight(&self, a: NodeIndex<Ix>) -> Option<&N> {
self.nodes.get(a.index()).map(|n| &n.weight)
}
pub fn node_weight_mut(&mut self, a: NodeIndex<Ix>) -> Option<&mut N> {
self.nodes.get_mut(a.index()).map(|n| &mut n.weight)
}
pub fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
let edge_idx = EdgeIndex::new(self.edges.len());
assert!(<Ix as IndexType>::max().index() == !0 || EdgeIndex::end() != edge_idx);
let mut edge = Edge {
weight,
node: [a, b],
next: [EdgeIndex::end(); 2],
};
match index_twice(&mut self.nodes, a.index(), b.index()) {
Pair::None => panic!("Graph::add_edge: node indices out of bounds"),
Pair::One(an) => {
edge.next = an.next;
an.next[0] = edge_idx;
an.next[1] = edge_idx;
}
Pair::Both(an, bn) => {
edge.next = [an.next[0], bn.next[1]];
an.next[0] = edge_idx;
bn.next[1] = edge_idx;
}
}
self.edges.push(edge);
edge_idx
}
pub fn update_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
if let Some(ix) = self.find_edge(a, b) {
if let Some(ed) = self.edge_weight_mut(ix) {
*ed = weight;
return ix;
}
}
self.add_edge(a, b, weight)
}
pub fn edge_weight(&self, e: EdgeIndex<Ix>) -> Option<&E> {
self.edges.get(e.index()).map(|ed| &ed.weight)
}
pub fn edge_weight_mut(&mut self, e: EdgeIndex<Ix>) -> Option<&mut E> {
self.edges.get_mut(e.index()).map(|ed| &mut ed.weight)
}
pub fn edge_endpoints(&self, e: EdgeIndex<Ix>) -> Option<(NodeIndex<Ix>, NodeIndex<Ix>)> {
self.edges
.get(e.index())
.map(|ed| (ed.source(), ed.target()))
}
pub fn remove_node(&mut self, a: NodeIndex<Ix>) -> Option<N> {
self.nodes.get(a.index())?;
for d in &DIRECTIONS {
let k = d.index();
loop {
let next = self.nodes[a.index()].next[k];
if next == EdgeIndex::end() {
break;
}
let ret = self.remove_edge(next);
debug_assert!(ret.is_some());
let _ = ret;
}
}
let node = self.nodes.swap_remove(a.index());
let swap_edges = match self.nodes.get(a.index()) {
None => return Some(node.weight),
Some(ed) => ed.next,
};
let old_index = NodeIndex::new(self.nodes.len());
let new_index = a;
for &d in &DIRECTIONS {
let k = d.index();
let mut edges = edges_walker_mut(&mut self.edges, swap_edges[k], d);
while let Some(curedge) = edges.next_edge() {
debug_assert!(curedge.node[k] == old_index);
curedge.node[k] = new_index;
}
}
Some(node.weight)
}
fn change_edge_links(
&mut self,
edge_node: [NodeIndex<Ix>; 2],
e: EdgeIndex<Ix>,
edge_next: [EdgeIndex<Ix>; 2],
) {
for &d in &DIRECTIONS {
let k = d.index();
let node = match self.nodes.get_mut(edge_node[k].index()) {
Some(r) => r,
None => {
debug_assert!(
false,
"Edge's endpoint dir={:?} index={:?} not found",
d, edge_node[k]
);
return;
}
};
let fst = node.next[k];
if fst == e {
node.next[k] = edge_next[k];
} else {
let mut edges = edges_walker_mut(&mut self.edges, fst, d);
while let Some(curedge) = edges.next_edge() {
if curedge.next[k] == e {
curedge.next[k] = edge_next[k];
break; }
}
}
}
}
pub fn remove_edge(&mut self, e: EdgeIndex<Ix>) -> Option<E> {
let (edge_node, edge_next) = match self.edges.get(e.index()) {
None => return None,
Some(x) => (x.node, x.next),
};
self.change_edge_links(edge_node, e, edge_next);
self.remove_edge_adjust_indices(e)
}
fn remove_edge_adjust_indices(&mut self, e: EdgeIndex<Ix>) -> Option<E> {
let edge = self.edges.swap_remove(e.index());
let swap = match self.edges.get(e.index()) {
None => return Some(edge.weight),
Some(ed) => ed.node,
};
let swapped_e = EdgeIndex::new(self.edges.len());
self.change_edge_links(swap, swapped_e, [e, e]);
Some(edge.weight)
}
pub fn neighbors(&self, a: NodeIndex<Ix>) -> Neighbors<E, Ix> {
self.neighbors_directed(a, Outgoing)
}
pub fn neighbors_directed(&self, a: NodeIndex<Ix>, dir: Direction) -> Neighbors<E, Ix> {
let mut iter = self.neighbors_undirected(a);
if self.is_directed() {
let k = dir.index();
iter.next[1 - k] = EdgeIndex::end();
iter.skip_start = NodeIndex::end();
}
iter
}
pub fn neighbors_undirected(&self, a: NodeIndex<Ix>) -> Neighbors<E, Ix> {
Neighbors {
skip_start: a,
edges: &self.edges,
next: match self.nodes.get(a.index()) {
None => [EdgeIndex::end(), EdgeIndex::end()],
Some(n) => n.next,
},
}
}
pub fn edges(&self, a: NodeIndex<Ix>) -> Edges<E, Ty, Ix> {
self.edges_directed(a, Outgoing)
}
pub fn edges_directed(&self, a: NodeIndex<Ix>, dir: Direction) -> Edges<E, Ty, Ix> {
Edges {
skip_start: a,
edges: &self.edges,
direction: dir,
next: match self.nodes.get(a.index()) {
None => [EdgeIndex::end(), EdgeIndex::end()],
Some(n) => n.next,
},
ty: PhantomData,
}
}
pub fn edges_connecting(
&self,
a: NodeIndex<Ix>,
b: NodeIndex<Ix>,
) -> EdgesConnecting<E, Ty, Ix> {
EdgesConnecting {
target_node: b,
edges: self.edges_directed(a, Direction::Outgoing),
ty: PhantomData,
}
}
pub fn contains_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
self.find_edge(a, b).is_some()
}
pub fn find_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> Option<EdgeIndex<Ix>> {
if !self.is_directed() {
self.find_edge_undirected(a, b).map(|(ix, _)| ix)
} else {
match self.nodes.get(a.index()) {
None => None,
Some(node) => self.find_edge_directed_from_node(node, b),
}
}
}
fn find_edge_directed_from_node(
&self,
node: &Node<N, Ix>,
b: NodeIndex<Ix>,
) -> Option<EdgeIndex<Ix>> {
let mut edix = node.next[0];
while let Some(edge) = self.edges.get(edix.index()) {
if edge.node[1] == b {
return Some(edix);
}
edix = edge.next[0];
}
None
}
pub fn find_edge_undirected(
&self,
a: NodeIndex<Ix>,
b: NodeIndex<Ix>,
) -> Option<(EdgeIndex<Ix>, Direction)> {
match self.nodes.get(a.index()) {
None => None,
Some(node) => self.find_edge_undirected_from_node(node, b),
}
}
fn find_edge_undirected_from_node(
&self,
node: &Node<N, Ix>,
b: NodeIndex<Ix>,
) -> Option<(EdgeIndex<Ix>, Direction)> {
for &d in &DIRECTIONS {
let k = d.index();
let mut edix = node.next[k];
while let Some(edge) = self.edges.get(edix.index()) {
if edge.node[1 - k] == b {
return Some((edix, d));
}
edix = edge.next[k];
}
}
None
}
pub fn externals(&self, dir: Direction) -> Externals<N, Ty, Ix> {
Externals {
iter: self.nodes.iter().enumerate(),
dir,
ty: PhantomData,
}
}
pub fn node_indices(&self) -> NodeIndices<Ix> {
NodeIndices {
r: 0..self.node_count(),
ty: PhantomData,
}
}
pub fn node_weights_mut(&mut self) -> NodeWeightsMut<N, Ix> {
NodeWeightsMut {
nodes: self.nodes.iter_mut(),
}
}
pub fn node_weights(&self) -> NodeWeights<N, Ix> {
NodeWeights {
nodes: self.nodes.iter(),
}
}
pub fn edge_indices(&self) -> EdgeIndices<Ix> {
EdgeIndices {
r: 0..self.edge_count(),
ty: PhantomData,
}
}
pub fn edge_references(&self) -> EdgeReferences<E, Ix> {
EdgeReferences {
iter: self.edges.iter().enumerate(),
}
}
pub fn edge_weights(&self) -> EdgeWeights<E, Ix> {
EdgeWeights {
edges: self.edges.iter(),
}
}
pub fn edge_weights_mut(&mut self) -> EdgeWeightsMut<E, Ix> {
EdgeWeightsMut {
edges: self.edges.iter_mut(),
}
}
pub fn raw_nodes(&self) -> &[Node<N, Ix>] {
&self.nodes
}
pub fn raw_edges(&self) -> &[Edge<E, Ix>] {
&self.edges
}
#[allow(clippy::type_complexity)]
pub fn into_nodes_edges(self) -> (Vec<Node<N, Ix>>, Vec<Edge<E, Ix>>) {
(self.nodes, self.edges)
}
pub fn first_edge(&self, a: NodeIndex<Ix>, dir: Direction) -> Option<EdgeIndex<Ix>> {
match self.nodes.get(a.index()) {
None => None,
Some(node) => {
let edix = node.next[dir.index()];
if edix == EdgeIndex::end() {
None
} else {
Some(edix)
}
}
}
}
pub fn next_edge(&self, e: EdgeIndex<Ix>, dir: Direction) -> Option<EdgeIndex<Ix>> {
match self.edges.get(e.index()) {
None => None,
Some(node) => {
let edix = node.next[dir.index()];
if edix == EdgeIndex::end() {
None
} else {
Some(edix)
}
}
}
}
pub fn index_twice_mut<T, U>(
&mut self,
i: T,
j: U,
) -> (
&mut <Self as Index<T>>::Output,
&mut <Self as Index<U>>::Output,
)
where
Self: IndexMut<T> + IndexMut<U>,
T: GraphIndex,
U: GraphIndex,
{
assert!(T::is_node_index() != U::is_node_index() || i.index() != j.index());
unsafe {
let self_mut = self as *mut _;
(
<Self as IndexMut<T>>::index_mut(&mut *self_mut, i),
<Self as IndexMut<U>>::index_mut(&mut *self_mut, j),
)
}
}
pub fn reverse(&mut self) {
for edge in &mut self.edges {
edge.node.swap(0, 1);
edge.next.swap(0, 1);
}
for node in &mut self.nodes {
node.next.swap(0, 1);
}
}
pub fn clear(&mut self) {
self.nodes.clear();
self.edges.clear();
}
pub fn clear_edges(&mut self) {
self.edges.clear();
for node in &mut self.nodes {
node.next = [EdgeIndex::end(), EdgeIndex::end()];
}
}
pub fn capacity(&self) -> (usize, usize) {
(self.nodes.capacity(), self.edges.capacity())
}
pub fn reserve_nodes(&mut self, additional: usize) {
self.nodes.reserve(additional);
}
pub fn reserve_edges(&mut self, additional: usize) {
self.edges.reserve(additional);
}
pub fn reserve_exact_nodes(&mut self, additional: usize) {
self.nodes.reserve_exact(additional);
}
pub fn reserve_exact_edges(&mut self, additional: usize) {
self.edges.reserve_exact(additional);
}
pub fn shrink_to_fit_nodes(&mut self) {
self.nodes.shrink_to_fit();
}
pub fn shrink_to_fit_edges(&mut self) {
self.edges.shrink_to_fit();
}
pub fn shrink_to_fit(&mut self) {
self.nodes.shrink_to_fit();
self.edges.shrink_to_fit();
}
pub fn retain_nodes<F>(&mut self, mut visit: F)
where
F: FnMut(Frozen<Self>, NodeIndex<Ix>) -> bool,
{
for index in self.node_indices().rev() {
if !visit(Frozen(self), index) {
let ret = self.remove_node(index);
debug_assert!(ret.is_some());
let _ = ret;
}
}
}
pub fn retain_edges<F>(&mut self, mut visit: F)
where
F: FnMut(Frozen<Self>, EdgeIndex<Ix>) -> bool,
{
for index in self.edge_indices().rev() {
if !visit(Frozen(self), index) {
let ret = self.remove_edge(index);
debug_assert!(ret.is_some());
let _ = ret;
}
}
}
pub fn from_edges<I>(iterable: I) -> Self
where
I: IntoIterator,
I::Item: IntoWeightedEdge<E>,
<I::Item as IntoWeightedEdge<E>>::NodeId: Into<NodeIndex<Ix>>,
N: Default,
{
let mut g = Self::with_capacity(0, 0);
g.extend_with_edges(iterable);
g
}
pub fn extend_with_edges<I>(&mut self, iterable: I)
where
I: IntoIterator,
I::Item: IntoWeightedEdge<E>,
<I::Item as IntoWeightedEdge<E>>::NodeId: Into<NodeIndex<Ix>>,
N: Default,
{
let iter = iterable.into_iter();
let (low, _) = iter.size_hint();
self.edges.reserve(low);
for elt in iter {
let (source, target, weight) = elt.into_weighted_edge();
let (source, target) = (source.into(), target.into());
let nx = cmp::max(source, target);
while nx.index() >= self.node_count() {
self.add_node(N::default());
}
self.add_edge(source, target, weight);
}
}
pub fn map<'a, F, G, N2, E2>(
&'a self,
mut node_map: F,
mut edge_map: G,
) -> Graph<N2, E2, Ty, Ix>
where
F: FnMut(NodeIndex<Ix>, &'a N) -> N2,
G: FnMut(EdgeIndex<Ix>, &'a E) -> E2,
{
let mut g = Graph::with_capacity(self.node_count(), self.edge_count());
g.nodes.extend(enumerate(&self.nodes).map(|(i, node)| Node {
weight: node_map(NodeIndex::new(i), &node.weight),
next: node.next,
}));
g.edges.extend(enumerate(&self.edges).map(|(i, edge)| Edge {
weight: edge_map(EdgeIndex::new(i), &edge.weight),
next: edge.next,
node: edge.node,
}));
g
}
pub fn filter_map<'a, F, G, N2, E2>(
&'a self,
mut node_map: F,
mut edge_map: G,
) -> Graph<N2, E2, Ty, Ix>
where
F: FnMut(NodeIndex<Ix>, &'a N) -> Option<N2>,
G: FnMut(EdgeIndex<Ix>, &'a E) -> Option<E2>,
{
let mut g = Graph::with_capacity(0, 0);
let mut node_index_map = vec![NodeIndex::end(); self.node_count()];
for (i, node) in enumerate(&self.nodes) {
if let Some(nw) = node_map(NodeIndex::new(i), &node.weight) {
node_index_map[i] = g.add_node(nw);
}
}
for (i, edge) in enumerate(&self.edges) {
let source = node_index_map[edge.source().index()];
let target = node_index_map[edge.target().index()];
if source != NodeIndex::end() && target != NodeIndex::end() {
if let Some(ew) = edge_map(EdgeIndex::new(i), &edge.weight) {
g.add_edge(source, target, ew);
}
}
}
g
}
pub fn into_edge_type<NewTy>(self) -> Graph<N, E, NewTy, Ix>
where
NewTy: EdgeType,
{
Graph {
nodes: self.nodes,
edges: self.edges,
ty: PhantomData,
}
}
#[cfg(feature = "serde-1")]
fn link_edges(&mut self) -> Result<(), NodeIndex<Ix>> {
for (edge_index, edge) in enumerate(&mut self.edges) {
let a = edge.source();
let b = edge.target();
let edge_idx = EdgeIndex::new(edge_index);
match index_twice(&mut self.nodes, a.index(), b.index()) {
Pair::None => return Err(if a > b { a } else { b }),
Pair::One(an) => {
edge.next = an.next;
an.next[0] = edge_idx;
an.next[1] = edge_idx;
}
Pair::Both(an, bn) => {
edge.next = [an.next[0], bn.next[1]];
an.next[0] = edge_idx;
bn.next[1] = edge_idx;
}
}
}
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct Externals<'a, N: 'a, Ty, Ix: IndexType = DefaultIx> {
iter: iter::Enumerate<slice::Iter<'a, Node<N, Ix>>>,
dir: Direction,
ty: PhantomData<Ty>,
}
impl<'a, N: 'a, Ty, Ix> Iterator for Externals<'a, N, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
type Item = NodeIndex<Ix>;
fn next(&mut self) -> Option<NodeIndex<Ix>> {
let k = self.dir.index();
loop {
match self.iter.next() {
None => return None,
Some((index, node)) => {
if node.next[k] == EdgeIndex::end()
&& (Ty::is_directed() || node.next[1 - k] == EdgeIndex::end())
{
return Some(NodeIndex::new(index));
} else {
continue;
}
}
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
}
#[derive(Debug)]
pub struct Neighbors<'a, E: 'a, Ix: 'a = DefaultIx> {
skip_start: NodeIndex<Ix>,
edges: &'a [Edge<E, Ix>],
next: [EdgeIndex<Ix>; 2],
}
impl<'a, E, Ix> Iterator for Neighbors<'a, E, Ix>
where
Ix: IndexType,
{
type Item = NodeIndex<Ix>;
fn next(&mut self) -> Option<NodeIndex<Ix>> {
match self.edges.get(self.next[0].index()) {
None => {}
Some(edge) => {
self.next[0] = edge.next[0];
return Some(edge.node[1]);
}
}
while let Some(edge) = self.edges.get(self.next[1].index()) {
self.next[1] = edge.next[1];
if edge.node[0] != self.skip_start {
return Some(edge.node[0]);
}
}
None
}
}
impl<'a, E, Ix> Clone for Neighbors<'a, E, Ix>
where
Ix: IndexType,
{
clone_fields!(Neighbors, skip_start, edges, next,);
}
impl<'a, E, Ix> Neighbors<'a, E, Ix>
where
Ix: IndexType,
{
pub fn detach(&self) -> WalkNeighbors<Ix> {
WalkNeighbors {
skip_start: self.skip_start,
next: self.next,
}
}
}
struct EdgesWalkerMut<'a, E: 'a, Ix: IndexType = DefaultIx> {
edges: &'a mut [Edge<E, Ix>],
next: EdgeIndex<Ix>,
dir: Direction,
}
fn edges_walker_mut<E, Ix>(
edges: &mut [Edge<E, Ix>],
next: EdgeIndex<Ix>,
dir: Direction,
) -> EdgesWalkerMut<E, Ix>
where
Ix: IndexType,
{
EdgesWalkerMut { edges, next, dir }
}
impl<'a, E, Ix> EdgesWalkerMut<'a, E, Ix>
where
Ix: IndexType,
{
fn next_edge(&mut self) -> Option<&mut Edge<E, Ix>> {
self.next().map(|t| t.1)
}
fn next(&mut self) -> Option<(EdgeIndex<Ix>, &mut Edge<E, Ix>)> {
let this_index = self.next;
let k = self.dir.index();
match self.edges.get_mut(self.next.index()) {
None => None,
Some(edge) => {
self.next = edge.next[k];
Some((this_index, edge))
}
}
}
}
impl<'a, N, E, Ty, Ix> visit::IntoEdges for &'a Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
type Edges = Edges<'a, E, Ty, Ix>;
fn edges(self, a: Self::NodeId) -> Self::Edges {
self.edges(a)
}
}
impl<'a, N, E, Ty, Ix> visit::IntoEdgesDirected for &'a Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
type EdgesDirected = Edges<'a, E, Ty, Ix>;
fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::EdgesDirected {
self.edges_directed(a, dir)
}
}
#[derive(Debug)]
pub struct Edges<'a, E: 'a, Ty, Ix: 'a = DefaultIx>
where
Ty: EdgeType,
Ix: IndexType,
{
skip_start: NodeIndex<Ix>,
edges: &'a [Edge<E, Ix>],
next: [EdgeIndex<Ix>; 2],
direction: Direction,
ty: PhantomData<Ty>,
}
impl<'a, E, Ty, Ix> Iterator for Edges<'a, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
type Item = EdgeReference<'a, E, Ix>;
fn next(&mut self) -> Option<Self::Item> {
let (iterate_over, reverse) = if Ty::is_directed() {
(Some(self.direction), None)
} else {
(None, Some(self.direction.opposite()))
};
if iterate_over.unwrap_or(Outgoing) == Outgoing {
let i = self.next[0].index();
if let Some(Edge { node, weight, next }) = self.edges.get(i) {
self.next[0] = next[0];
return Some(EdgeReference {
index: edge_index(i),
node: if reverse == Some(Outgoing) {
swap_pair(*node)
} else {
*node
},
weight,
});
}
}
if iterate_over.unwrap_or(Incoming) == Incoming {
while let Some(Edge { node, weight, next }) = self.edges.get(self.next[1].index()) {
let edge_index = self.next[1];
self.next[1] = next[1];
if iterate_over.is_none() && node[0] == self.skip_start {
continue;
}
return Some(EdgeReference {
index: edge_index,
node: if reverse == Some(Incoming) {
swap_pair(*node)
} else {
*node
},
weight,
});
}
}
None
}
}
#[derive(Debug, Clone)]
pub struct EdgesConnecting<'a, E: 'a, Ty, Ix: 'a = DefaultIx>
where
Ty: EdgeType,
Ix: IndexType,
{
target_node: NodeIndex<Ix>,
edges: Edges<'a, E, Ty, Ix>,
ty: PhantomData<Ty>,
}
impl<'a, E, Ty, Ix> Iterator for EdgesConnecting<'a, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
type Item = EdgeReference<'a, E, Ix>;
fn next(&mut self) -> Option<EdgeReference<'a, E, Ix>> {
while let Some(edge) = self.edges.next() {
if edge.node[1] == self.target_node {
return Some(edge);
}
}
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.edges.size_hint();
(0, upper)
}
}
fn swap_pair<T>(mut x: [T; 2]) -> [T; 2] {
x.swap(0, 1);
x
}
impl<'a, E, Ty, Ix> Clone for Edges<'a, E, Ty, Ix>
where
Ix: IndexType,
Ty: EdgeType,
{
fn clone(&self) -> Self {
Edges {
skip_start: self.skip_start,
edges: self.edges,
next: self.next,
direction: self.direction,
ty: self.ty,
}
}
}
pub struct NodeWeights<'a, N: 'a, Ix: IndexType = DefaultIx> {
nodes: ::std::slice::Iter<'a, Node<N, Ix>>,
}
impl<'a, N, Ix> Iterator for NodeWeights<'a, N, Ix>
where
Ix: IndexType,
{
type Item = &'a N;
fn next(&mut self) -> Option<&'a N> {
self.nodes.next().map(|node| &node.weight)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.nodes.size_hint()
}
}
#[derive(Debug)]
pub struct NodeWeightsMut<'a, N: 'a, Ix: IndexType = DefaultIx> {
nodes: ::std::slice::IterMut<'a, Node<N, Ix>>, }
impl<'a, N, Ix> Iterator for NodeWeightsMut<'a, N, Ix>
where
Ix: IndexType,
{
type Item = &'a mut N;
fn next(&mut self) -> Option<&'a mut N> {
self.nodes.next().map(|node| &mut node.weight)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.nodes.size_hint()
}
}
pub struct EdgeWeights<'a, E: 'a, Ix: IndexType = DefaultIx> {
edges: ::std::slice::Iter<'a, Edge<E, Ix>>,
}
impl<'a, E, Ix> Iterator for EdgeWeights<'a, E, Ix>
where
Ix: IndexType,
{
type Item = &'a E;
fn next(&mut self) -> Option<&'a E> {
self.edges.next().map(|edge| &edge.weight)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.edges.size_hint()
}
}
#[derive(Debug)]
pub struct EdgeWeightsMut<'a, E: 'a, Ix: IndexType = DefaultIx> {
edges: ::std::slice::IterMut<'a, Edge<E, Ix>>, }
impl<'a, E, Ix> Iterator for EdgeWeightsMut<'a, E, Ix>
where
Ix: IndexType,
{
type Item = &'a mut E;
fn next(&mut self) -> Option<&'a mut E> {
self.edges.next().map(|edge| &mut edge.weight)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.edges.size_hint()
}
}
impl<N, E, Ty, Ix> Index<NodeIndex<Ix>> for Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
type Output = N;
fn index(&self, index: NodeIndex<Ix>) -> &N {
&self.nodes[index.index()].weight
}
}
impl<N, E, Ty, Ix> IndexMut<NodeIndex<Ix>> for Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
fn index_mut(&mut self, index: NodeIndex<Ix>) -> &mut N {
&mut self.nodes[index.index()].weight
}
}
impl<N, E, Ty, Ix> Index<EdgeIndex<Ix>> for Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
type Output = E;
fn index(&self, index: EdgeIndex<Ix>) -> &E {
&self.edges[index.index()].weight
}
}
impl<N, E, Ty, Ix> IndexMut<EdgeIndex<Ix>> for Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
fn index_mut(&mut self, index: EdgeIndex<Ix>) -> &mut E {
&mut self.edges[index.index()].weight
}
}
impl<N, E, Ty, Ix> Default for Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
fn default() -> Self {
Self::with_capacity(0, 0)
}
}
pub trait GraphIndex: Copy {
#[doc(hidden)]
fn index(&self) -> usize;
#[doc(hidden)]
fn is_node_index() -> bool;
}
impl<Ix: IndexType> GraphIndex for NodeIndex<Ix> {
#[inline]
#[doc(hidden)]
fn index(&self) -> usize {
NodeIndex::index(*self)
}
#[inline]
#[doc(hidden)]
fn is_node_index() -> bool {
true
}
}
impl<Ix: IndexType> GraphIndex for EdgeIndex<Ix> {
#[inline]
#[doc(hidden)]
fn index(&self) -> usize {
EdgeIndex::index(*self)
}
#[inline]
#[doc(hidden)]
fn is_node_index() -> bool {
false
}
}
pub struct WalkNeighbors<Ix> {
skip_start: NodeIndex<Ix>,
next: [EdgeIndex<Ix>; 2],
}
impl<Ix> Clone for WalkNeighbors<Ix>
where
Ix: IndexType,
{
fn clone(&self) -> Self {
WalkNeighbors {
skip_start: self.skip_start,
next: self.next,
}
}
}
impl<Ix: IndexType> WalkNeighbors<Ix> {
pub fn next<N, E, Ty: EdgeType>(
&mut self,
g: &Graph<N, E, Ty, Ix>,
) -> Option<(EdgeIndex<Ix>, NodeIndex<Ix>)> {
match g.edges.get(self.next[0].index()) {
None => {}
Some(edge) => {
let ed = self.next[0];
self.next[0] = edge.next[0];
return Some((ed, edge.node[1]));
}
}
while let Some(edge) = g.edges.get(self.next[1].index()) {
let ed = self.next[1];
self.next[1] = edge.next[1];
if edge.node[0] != self.skip_start {
return Some((ed, edge.node[0]));
}
}
None
}
pub fn next_node<N, E, Ty: EdgeType>(
&mut self,
g: &Graph<N, E, Ty, Ix>,
) -> Option<NodeIndex<Ix>> {
self.next(g).map(|t| t.1)
}
pub fn next_edge<N, E, Ty: EdgeType>(
&mut self,
g: &Graph<N, E, Ty, Ix>,
) -> Option<EdgeIndex<Ix>> {
self.next(g).map(|t| t.0)
}
}
#[derive(Clone, Debug)]
pub struct NodeIndices<Ix = DefaultIx> {
r: Range<usize>,
ty: PhantomData<fn() -> Ix>,
}
impl<Ix: IndexType> Iterator for NodeIndices<Ix> {
type Item = NodeIndex<Ix>;
fn next(&mut self) -> Option<Self::Item> {
self.r.next().map(node_index)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.r.size_hint()
}
}
impl<Ix: IndexType> DoubleEndedIterator for NodeIndices<Ix> {
fn next_back(&mut self) -> Option<Self::Item> {
self.r.next_back().map(node_index)
}
}
impl<Ix: IndexType> ExactSizeIterator for NodeIndices<Ix> {}
#[derive(Clone, Debug)]
pub struct EdgeIndices<Ix = DefaultIx> {
r: Range<usize>,
ty: PhantomData<fn() -> Ix>,
}
impl<Ix: IndexType> Iterator for EdgeIndices<Ix> {
type Item = EdgeIndex<Ix>;
fn next(&mut self) -> Option<Self::Item> {
self.r.next().map(edge_index)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.r.size_hint()
}
}
impl<Ix: IndexType> DoubleEndedIterator for EdgeIndices<Ix> {
fn next_back(&mut self) -> Option<Self::Item> {
self.r.next_back().map(edge_index)
}
}
impl<Ix: IndexType> ExactSizeIterator for EdgeIndices<Ix> {}
#[derive(Debug)]
pub struct EdgeReference<'a, E: 'a, Ix = DefaultIx> {
index: EdgeIndex<Ix>,
node: [NodeIndex<Ix>; 2],
weight: &'a E,
}
impl<'a, E, Ix: IndexType> Clone for EdgeReference<'a, E, Ix> {
fn clone(&self) -> Self {
*self
}
}
impl<'a, E, Ix: IndexType> Copy for EdgeReference<'a, E, Ix> {}
impl<'a, E, Ix: IndexType> PartialEq for EdgeReference<'a, E, Ix>
where
E: PartialEq,
{
fn eq(&self, rhs: &Self) -> bool {
self.index == rhs.index && self.weight == rhs.weight
}
}
impl<N, E, Ty, Ix> visit::GraphBase for Graph<N, E, Ty, Ix>
where
Ix: IndexType,
{
type NodeId = NodeIndex<Ix>;
type EdgeId = EdgeIndex<Ix>;
}
impl<N, E, Ty, Ix> visit::Visitable for Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
type Map = FixedBitSet;
fn visit_map(&self) -> FixedBitSet {
FixedBitSet::with_capacity(self.node_count())
}
fn reset_map(&self, map: &mut Self::Map) {
map.clear();
map.grow(self.node_count());
}
}
impl<N, E, Ty, Ix> visit::GraphProp for Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
type EdgeType = Ty;
}
impl<'a, N, E: 'a, Ty, Ix> visit::IntoNodeIdentifiers for &'a Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
type NodeIdentifiers = NodeIndices<Ix>;
fn node_identifiers(self) -> NodeIndices<Ix> {
Graph::node_indices(self)
}
}
impl<N, E, Ty, Ix> visit::NodeCount for Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
fn node_count(&self) -> usize {
self.node_count()
}
}
impl<N, E, Ty, Ix> visit::NodeIndexable for Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
#[inline]
fn node_bound(&self) -> usize {
self.node_count()
}
#[inline]
fn to_index(&self, ix: NodeIndex<Ix>) -> usize {
ix.index()
}
#[inline]
fn from_index(&self, ix: usize) -> Self::NodeId {
NodeIndex::new(ix)
}
}
impl<N, E, Ty, Ix> visit::NodeCompactIndexable for Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
}
impl<'a, N, E: 'a, Ty, Ix> visit::IntoNeighbors for &'a Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
type Neighbors = Neighbors<'a, E, Ix>;
fn neighbors(self, n: NodeIndex<Ix>) -> Neighbors<'a, E, Ix> {
Graph::neighbors(self, n)
}
}
impl<'a, N, E: 'a, Ty, Ix> visit::IntoNeighborsDirected for &'a Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
type NeighborsDirected = Neighbors<'a, E, Ix>;
fn neighbors_directed(self, n: NodeIndex<Ix>, d: Direction) -> Neighbors<'a, E, Ix> {
Graph::neighbors_directed(self, n, d)
}
}
impl<'a, N: 'a, E: 'a, Ty, Ix> visit::IntoEdgeReferences for &'a Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
type EdgeRef = EdgeReference<'a, E, Ix>;
type EdgeReferences = EdgeReferences<'a, E, Ix>;
fn edge_references(self) -> Self::EdgeReferences {
(*self).edge_references()
}
}
impl<N, E, Ty, Ix> visit::EdgeCount for Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
#[inline]
fn edge_count(&self) -> usize {
self.edge_count()
}
}
impl<'a, N, E, Ty, Ix> visit::IntoNodeReferences for &'a Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
type NodeRef = (NodeIndex<Ix>, &'a N);
type NodeReferences = NodeReferences<'a, N, Ix>;
fn node_references(self) -> Self::NodeReferences {
NodeReferences {
iter: self.nodes.iter().enumerate(),
}
}
}
#[derive(Debug, Clone)]
pub struct NodeReferences<'a, N: 'a, Ix: IndexType = DefaultIx> {
iter: iter::Enumerate<slice::Iter<'a, Node<N, Ix>>>,
}
impl<'a, N, Ix> Iterator for NodeReferences<'a, N, Ix>
where
Ix: IndexType,
{
type Item = (NodeIndex<Ix>, &'a N);
fn next(&mut self) -> Option<Self::Item> {
self.iter
.next()
.map(|(i, node)| (node_index(i), &node.weight))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, N, Ix> DoubleEndedIterator for NodeReferences<'a, N, Ix>
where
Ix: IndexType,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.iter
.next_back()
.map(|(i, node)| (node_index(i), &node.weight))
}
}
impl<'a, N, Ix> ExactSizeIterator for NodeReferences<'a, N, Ix> where Ix: IndexType {}
impl<'a, Ix, E> EdgeReference<'a, E, Ix>
where
Ix: IndexType,
{
pub fn weight(&self) -> &'a E {
self.weight
}
}
impl<'a, Ix, E> visit::EdgeRef for EdgeReference<'a, E, Ix>
where
Ix: IndexType,
{
type NodeId = NodeIndex<Ix>;
type EdgeId = EdgeIndex<Ix>;
type Weight = E;
fn source(&self) -> Self::NodeId {
self.node[0]
}
fn target(&self) -> Self::NodeId {
self.node[1]
}
fn weight(&self) -> &E {
self.weight
}
fn id(&self) -> Self::EdgeId {
self.index
}
}
#[derive(Debug, Clone)]
pub struct EdgeReferences<'a, E: 'a, Ix: IndexType = DefaultIx> {
iter: iter::Enumerate<slice::Iter<'a, Edge<E, Ix>>>,
}
impl<'a, E, Ix> Iterator for EdgeReferences<'a, E, Ix>
where
Ix: IndexType,
{
type Item = EdgeReference<'a, E, Ix>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(i, edge)| EdgeReference {
index: edge_index(i),
node: edge.node,
weight: &edge.weight,
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, E, Ix> DoubleEndedIterator for EdgeReferences<'a, E, Ix>
where
Ix: IndexType,
{
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back().map(|(i, edge)| EdgeReference {
index: edge_index(i),
node: edge.node,
weight: &edge.weight,
})
}
}
impl<'a, E, Ix> ExactSizeIterator for EdgeReferences<'a, E, Ix> where Ix: IndexType {}
impl<N, E, Ty, Ix> visit::EdgeIndexable for Graph<N, E, Ty, Ix>
where
Ty: EdgeType,
Ix: IndexType,
{
fn edge_bound(&self) -> usize {
self.edge_count()
}
fn to_index(&self, ix: EdgeIndex<Ix>) -> usize {
ix.index()
}
fn from_index(&self, ix: usize) -> Self::EdgeId {
EdgeIndex::new(ix)
}
}
mod frozen;
#[cfg(feature = "stable_graph")]
pub mod stable_graph;
pub struct Frozen<'a, G: 'a>(&'a mut G);