petgraph/
matrix_graph.rs

1//! `MatrixGraph<N, E, Ty, NullN, NullE, Ix>` is a graph datastructure backed by an adjacency matrix.
2
3#[cfg(feature = "std")]
4use std::{
5    cmp,
6    marker::PhantomData,
7    mem,
8    ops::{Index, IndexMut},
9};
10
11#[cfg(not(feature = "std"))]
12use core::{
13    cmp,
14    marker::PhantomData,
15    mem,
16    ops::{Index, IndexMut},
17};
18
19#[cfg(not(feature = "std"))]
20use alloc::vec::Vec;
21
22use indexmap::IndexSet;
23
24use fixedbitset::FixedBitSet;
25
26use crate::{Directed, Direction, EdgeType, IntoWeightedEdge, Outgoing, Undirected};
27
28use crate::graph::NodeIndex as GraphNodeIndex;
29
30use crate::visit::{
31    Data, GetAdjacencyMatrix, GraphBase, GraphProp, IntoEdgeReferences, IntoEdges, IntoNeighbors,
32    IntoNeighborsDirected, IntoNodeIdentifiers, IntoNodeReferences, NodeCompactIndexable,
33    NodeCount, NodeIndexable, Visitable,
34};
35
36use crate::data::Build;
37
38pub use crate::graph::IndexType;
39
40// The following types are used to control the max size of the adjacency matrix. Since the maximum
41// size of the matrix vector's is the square of the maximum number of nodes, the number of nodes
42// should be reasonably picked.
43type DefaultIx = u16;
44
45/// Node identifier.
46pub type NodeIndex<Ix = DefaultIx> = GraphNodeIndex<Ix>;
47
48mod private {
49    pub trait Sealed {}
50
51    impl<T> Sealed for super::NotZero<T> {}
52    impl<T> Sealed for Option<T> {}
53}
54
55/// Wrapper trait for an `Option`, allowing user-defined structs to be input as containers when
56/// defining a null element.
57///
58/// Note: this trait is currently *sealed* and cannot be implemented for types outside this crate.
59pub trait Nullable: Default + Into<Option<<Self as Nullable>::Wrapped>> + private::Sealed {
60    #[doc(hidden)]
61    type Wrapped;
62
63    #[doc(hidden)]
64    fn new(value: Self::Wrapped) -> Self;
65
66    #[doc(hidden)]
67    fn as_ref(&self) -> Option<&Self::Wrapped>;
68
69    #[doc(hidden)]
70    fn as_mut(&mut self) -> Option<&mut Self::Wrapped>;
71
72    #[doc(hidden)]
73    fn is_null(&self) -> bool {
74        self.as_ref().is_none()
75    }
76}
77
78impl<T> Nullable for Option<T> {
79    type Wrapped = T;
80
81    fn new(value: T) -> Self {
82        Some(value)
83    }
84
85    fn as_ref(&self) -> Option<&Self::Wrapped> {
86        self.as_ref()
87    }
88
89    fn as_mut(&mut self) -> Option<&mut Self::Wrapped> {
90        self.as_mut()
91    }
92}
93
94/// `NotZero` is used to optimize the memory usage of edge weights `E` in a
95/// [`MatrixGraph`](struct.MatrixGraph.html), replacing the default `Option<E>` sentinel.
96///
97/// Pre-requisite: edge weight should implement [`Zero`](trait.Zero.html).
98///
99/// Note that if you're already using the standard non-zero types (such as `NonZeroU32`), you don't
100/// have to use this wrapper and can leave the default `Null` type argument.
101pub struct NotZero<T>(T);
102
103impl<T: Zero> Default for NotZero<T> {
104    fn default() -> Self {
105        NotZero(T::zero())
106    }
107}
108
109impl<T: Zero> Nullable for NotZero<T> {
110    type Wrapped = T;
111
112    fn new(value: T) -> Self {
113        assert!(!value.is_zero());
114        NotZero(value)
115    }
116
117    // implemented here for optimization purposes
118    fn is_null(&self) -> bool {
119        self.0.is_zero()
120    }
121
122    fn as_ref(&self) -> Option<&Self::Wrapped> {
123        if !self.is_null() {
124            Some(&self.0)
125        } else {
126            None
127        }
128    }
129
130    fn as_mut(&mut self) -> Option<&mut Self::Wrapped> {
131        if !self.is_null() {
132            Some(&mut self.0)
133        } else {
134            None
135        }
136    }
137}
138
139impl<T: Zero> Into<Option<T>> for NotZero<T> {
140    fn into(self) -> Option<T> {
141        if !self.is_null() {
142            Some(self.0)
143        } else {
144            None
145        }
146    }
147}
148
149/// Base trait for types that can be wrapped in a [`NotZero`](struct.NotZero.html).
150///
151/// Implementors must provide a singleton object that will be used to mark empty edges in a
152/// [`MatrixGraph`](struct.MatrixGraph.html).
153///
154/// Note that this trait is already implemented for the base numeric types.
155pub trait Zero {
156    /// Return the singleton object which can be used as a sentinel value.
157    fn zero() -> Self;
158
159    /// Return true if `self` is equal to the sentinel value.
160    fn is_zero(&self) -> bool;
161}
162
163macro_rules! not_zero_impl {
164    ($t:ty,$z:expr) => {
165        impl Zero for $t {
166            fn zero() -> Self {
167                $z as $t
168            }
169
170            fn is_zero(&self) -> bool {
171                self == &Self::zero()
172            }
173        }
174    };
175}
176
177macro_rules! not_zero_impls {
178    ($($t:ty),*) => {
179        $(
180            not_zero_impl!($t, 0);
181        )*
182    }
183}
184
185not_zero_impls!(u8, u16, u32, u64, usize);
186not_zero_impls!(i8, i16, i32, i64, isize);
187not_zero_impls!(f32, f64);
188
189/// Short version of `NodeIndex::new` (with Ix = `DefaultIx`)
190#[inline]
191pub fn node_index(ax: usize) -> NodeIndex {
192    NodeIndex::new(ax)
193}
194
195/// `MatrixGraph<N, E, Ty, Null>` is a graph datastructure using an adjacency matrix
196/// representation.
197///
198/// `MatrixGraph` is parameterized over:
199///
200/// - Associated data `N` for nodes and `E` for edges, called *weights*.
201///   The associated data can be of arbitrary type.
202/// - Edge type `Ty` that determines whether the graph edges are directed or undirected.
203/// - Nullable type `Null`, which denotes the edges' presence (defaults to `Option<E>`). You may
204///   specify [`NotZero<E>`](struct.NotZero.html) if you want to use a sentinel value (such as 0)
205///   to mark the absence of an edge.
206/// - Index type `Ix` that sets the maximum size for the graph (defaults to `DefaultIx`).
207///
208/// The graph uses **O(|V^2|)** space, with fast edge insertion & amortized node insertion, as well
209/// as efficient graph search and graph algorithms on dense graphs.
210///
211/// This graph is backed by a flattened 2D array. For undirected graphs, only the lower triangular
212/// matrix is stored. Since the backing array stores edge weights, it is recommended to box large
213/// edge weights.
214#[derive(Clone)]
215pub struct MatrixGraph<N, E, Ty = Directed, Null: Nullable<Wrapped = E> = Option<E>, Ix = DefaultIx>
216{
217    node_adjacencies: Vec<Null>,
218    node_capacity: usize,
219    nodes: IdStorage<N>,
220    nb_edges: usize,
221    ty: PhantomData<Ty>,
222    ix: PhantomData<Ix>,
223}
224
225/// A `MatrixGraph` with directed edges.
226pub type DiMatrix<N, E, Null = Option<E>, Ix = DefaultIx> = MatrixGraph<N, E, Directed, Null, Ix>;
227
228/// A `MatrixGraph` with undirected edges.
229pub type UnMatrix<N, E, Null = Option<E>, Ix = DefaultIx> = MatrixGraph<N, E, Undirected, Null, Ix>;
230
231impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType>
232    MatrixGraph<N, E, Ty, Null, Ix>
233{
234    /// Create a new `MatrixGraph` with estimated capacity for nodes.
235    pub fn with_capacity(node_capacity: usize) -> Self {
236        let mut m = Self {
237            node_adjacencies: vec![],
238            node_capacity: 0,
239            nodes: IdStorage::with_capacity(node_capacity),
240            nb_edges: 0,
241            ty: PhantomData,
242            ix: PhantomData,
243        };
244
245        debug_assert!(node_capacity <= <Ix as IndexType>::max().index());
246        m.extend_capacity_for_node(NodeIndex::new(node_capacity));
247
248        m
249    }
250
251    #[inline]
252    fn to_edge_position(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> usize {
253        to_linearized_matrix_position::<Ty>(a.index(), b.index(), self.node_capacity)
254    }
255
256    /// Remove all nodes and edges.
257    pub fn clear(&mut self) {
258        for edge in self.node_adjacencies.iter_mut() {
259            *edge = Default::default();
260        }
261        self.nodes.clear();
262        self.nb_edges = 0;
263    }
264
265    /// Return the number of nodes (vertices) in the graph.
266    ///
267    /// Computes in **O(1)** time.
268    #[inline]
269    pub fn node_count(&self) -> usize {
270        self.nodes.len()
271    }
272
273    /// Return the number of edges in the graph.
274    ///
275    /// Computes in **O(1)** time.
276    #[inline]
277    pub fn edge_count(&self) -> usize {
278        self.nb_edges
279    }
280
281    /// Return whether the graph has directed edges or not.
282    #[inline]
283    pub fn is_directed(&self) -> bool {
284        Ty::is_directed()
285    }
286
287    /// Add a node (also called vertex) with associated data `weight` to the graph.
288    ///
289    /// Computes in **O(1)** time.
290    ///
291    /// Return the index of the new node.
292    ///
293    /// **Panics** if the MatrixGraph is at the maximum number of nodes for its index type.
294    pub fn add_node(&mut self, weight: N) -> NodeIndex<Ix> {
295        NodeIndex::new(self.nodes.add(weight))
296    }
297
298    /// Remove `a` from the graph.
299    ///
300    /// Computes in **O(V)** time, due to the removal of edges with other nodes.
301    ///
302    /// **Panics** if the node `a` does not exist.
303    pub fn remove_node(&mut self, a: NodeIndex<Ix>) -> N {
304        for id in self.nodes.iter_ids() {
305            let position = self.to_edge_position(a, NodeIndex::new(id));
306            self.node_adjacencies[position] = Default::default();
307
308            if Ty::is_directed() {
309                let position = self.to_edge_position(NodeIndex::new(id), a);
310                self.node_adjacencies[position] = Default::default();
311            }
312        }
313
314        self.nodes.remove(a.index())
315    }
316
317    #[inline]
318    fn extend_capacity_for_node(&mut self, min_node: NodeIndex<Ix>) {
319        self.node_capacity = extend_linearized_matrix::<Ty, _>(
320            &mut self.node_adjacencies,
321            self.node_capacity,
322            min_node.index(),
323        );
324    }
325
326    #[inline]
327    fn extend_capacity_for_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) {
328        let min_node = cmp::max(a, b);
329        if min_node.index() >= self.node_capacity {
330            self.extend_capacity_for_node(min_node);
331        }
332    }
333
334    /// Update the edge from `a` to `b` to the graph, with its associated data `weight`.
335    ///
336    /// Return the previous data, if any.
337    ///
338    /// Computes in **O(1)** time, best case.
339    /// Computes in **O(|V|^2)** time, worst case (matrix needs to be re-allocated).
340    ///
341    /// **Panics** if any of the nodes don't exist.
342    pub fn update_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> Option<E> {
343        self.extend_capacity_for_edge(a, b);
344
345        let p = self.to_edge_position(a, b);
346        let old_weight = mem::replace(&mut self.node_adjacencies[p], Null::new(weight));
347        if old_weight.is_null() {
348            self.nb_edges += 1;
349        }
350        old_weight.into()
351    }
352
353    /// Add an edge from `a` to `b` to the graph, with its associated
354    /// data `weight`.
355    ///
356    /// Return the index of the new edge.
357    ///
358    /// Computes in **O(1)** time, best case.
359    /// Computes in **O(|V|^2)** time, worst case (matrix needs to be re-allocated).
360    ///
361    /// **Panics** if any of the nodes don't exist.
362    /// **Panics** if an edge already exists from `a` to `b`.
363    ///
364    /// **Note:** `MatrixGraph` does not allow adding parallel (“duplicate”) edges. If you want to avoid
365    /// this, use [`.update_edge(a, b, weight)`](#method.update_edge) instead.
366    pub fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) {
367        let old_edge_id = self.update_edge(a, b, weight);
368        assert!(old_edge_id.is_none());
369    }
370
371    /// Remove the edge from `a` to `b` to the graph.
372    ///
373    /// **Panics** if any of the nodes don't exist.
374    /// **Panics** if no edge exists between `a` and `b`.
375    pub fn remove_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> E {
376        let p = self.to_edge_position(a, b);
377        let old_weight = mem::replace(&mut self.node_adjacencies[p], Default::default())
378            .into()
379            .unwrap();
380        let old_weight: Option<_> = old_weight.into();
381        self.nb_edges -= 1;
382        old_weight.unwrap()
383    }
384
385    /// Return true if there is an edge between `a` and `b`.
386    ///
387    /// **Panics** if any of the nodes don't exist.
388    pub fn has_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
389        let p = self.to_edge_position(a, b);
390        !self.node_adjacencies[p].is_null()
391    }
392
393    /// Access the weight for node `a`.
394    ///
395    /// Also available with indexing syntax: `&graph[a]`.
396    ///
397    /// **Panics** if the node doesn't exist.
398    pub fn node_weight(&self, a: NodeIndex<Ix>) -> &N {
399        &self.nodes[a.index()]
400    }
401
402    /// Access the weight for node `a`, mutably.
403    ///
404    /// Also available with indexing syntax: `&mut graph[a]`.
405    ///
406    /// **Panics** if the node doesn't exist.
407    pub fn node_weight_mut(&mut self, a: NodeIndex<Ix>) -> &mut N {
408        &mut self.nodes[a.index()]
409    }
410
411    /// Access the weight for edge `e`.
412    ///
413    /// Also available with indexing syntax: `&graph[e]`.
414    ///
415    /// **Panics** if no edge exists between `a` and `b`.
416    pub fn edge_weight(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> &E {
417        let p = self.to_edge_position(a, b);
418        self.node_adjacencies[p].as_ref().unwrap()
419    }
420
421    /// Access the weight for edge `e`, mutably.
422    ///
423    /// Also available with indexing syntax: `&mut graph[e]`.
424    ///
425    /// **Panics** if no edge exists between `a` and `b`.
426    pub fn edge_weight_mut(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> &mut E {
427        let p = self.to_edge_position(a, b);
428        self.node_adjacencies[p].as_mut().unwrap()
429    }
430
431    /// Return an iterator of all nodes with an edge starting from `a`.
432    ///
433    /// - `Directed`: Outgoing edges from `a`.
434    /// - `Undirected`: All edges from or to `a`.
435    ///
436    /// Produces an empty iterator if the node doesn't exist.<br>
437    /// Iterator element type is [`NodeIndex<Ix>`](../graph/struct.NodeIndex.html).
438    pub fn neighbors(&self, a: NodeIndex<Ix>) -> Neighbors<Ty, Null, Ix> {
439        Neighbors(Edges::on_columns(
440            a.index(),
441            &self.node_adjacencies,
442            self.node_capacity,
443        ))
444    }
445
446    /// Return an iterator of all edges of `a`.
447    ///
448    /// - `Directed`: Outgoing edges from `a`.
449    /// - `Undirected`: All edges connected to `a`.
450    ///
451    /// Produces an empty iterator if the node doesn't exist.<br>
452    /// Iterator element type is [`Edges<E, Ix>`](../graph/struct.Edges.html).
453    pub fn edges(&self, a: NodeIndex<Ix>) -> Edges<Ty, Null, Ix> {
454        Edges::on_columns(a.index(), &self.node_adjacencies, self.node_capacity)
455    }
456
457    /// Create a new `MatrixGraph` from an iterable of edges.
458    ///
459    /// Node weights `N` are set to default values.
460    /// Edge weights `E` may either be specified in the list,
461    /// or they are filled with default values.
462    ///
463    /// Nodes are inserted automatically to match the edges.
464    ///
465    /// ```
466    /// use petgraph::matrix_graph::MatrixGraph;
467    ///
468    /// let gr = MatrixGraph::<(), i32>::from_edges(&[
469    ///     (0, 1), (0, 2), (0, 3),
470    ///     (1, 2), (1, 3),
471    ///     (2, 3),
472    /// ]);
473    /// ```
474    pub fn from_edges<I>(iterable: I) -> Self
475    where
476        I: IntoIterator,
477        I::Item: IntoWeightedEdge<E>,
478        <I::Item as IntoWeightedEdge<E>>::NodeId: Into<NodeIndex<Ix>>,
479        N: Default,
480    {
481        let mut g = Self::default();
482        g.extend_with_edges(iterable);
483        g
484    }
485
486    /// Extend the graph from an iterable of edges.
487    ///
488    /// Node weights `N` are set to default values.
489    /// Edge weights `E` may either be specified in the list,
490    /// or they are filled with default values.
491    ///
492    /// Nodes are inserted automatically to match the edges.
493    pub fn extend_with_edges<I>(&mut self, iterable: I)
494    where
495        I: IntoIterator,
496        I::Item: IntoWeightedEdge<E>,
497        <I::Item as IntoWeightedEdge<E>>::NodeId: Into<NodeIndex<Ix>>,
498        N: Default,
499    {
500        for elt in iterable {
501            let (source, target, weight) = elt.into_weighted_edge();
502            let (source, target) = (source.into(), target.into());
503            let nx = cmp::max(source, target);
504            while nx.index() >= self.node_count() {
505                self.add_node(N::default());
506            }
507            self.add_edge(source, target, weight);
508        }
509    }
510}
511
512impl<N, E, Null: Nullable<Wrapped = E>, Ix: IndexType> MatrixGraph<N, E, Directed, Null, Ix> {
513    /// Return an iterator of all neighbors that have an edge between them and
514    /// `a`, in the specified direction.
515    /// If the graph's edges are undirected, this is equivalent to *.neighbors(a)*.
516    ///
517    /// - `Outgoing`: All edges from `a`.
518    /// - `Incoming`: All edges to `a`.
519    ///
520    /// Produces an empty iterator if the node doesn't exist.<br>
521    /// Iterator element type is [`NodeIndex<Ix>`](../graph/struct.NodeIndex.html).
522    pub fn neighbors_directed(
523        &self,
524        a: NodeIndex<Ix>,
525        d: Direction,
526    ) -> Neighbors<Directed, Null, Ix> {
527        if d == Outgoing {
528            self.neighbors(a)
529        } else {
530            Neighbors(Edges::on_rows(
531                a.index(),
532                &self.node_adjacencies,
533                self.node_capacity,
534            ))
535        }
536    }
537
538    /// Return an iterator of all edges of `a`, in the specified direction.
539    ///
540    /// - `Outgoing`: All edges from `a`.
541    /// - `Incoming`: All edges to `a`.
542    ///
543    /// Produces an empty iterator if the node `a` doesn't exist.<br>
544    /// Iterator element type is [`EdgeReference<E, Ix>`](../graph/struct.EdgeReference.html).
545    pub fn edges_directed(&self, a: NodeIndex<Ix>, d: Direction) -> Edges<Directed, Null, Ix> {
546        if d == Outgoing {
547            self.edges(a)
548        } else {
549            Edges::on_rows(a.index(), &self.node_adjacencies, self.node_capacity)
550        }
551    }
552}
553
554/// Iterator over the node identifiers of a graph.
555///
556/// Created from a call to [`.node_identifiers()`][1] on a [`MatrixGraph`][2].
557///
558/// [1]: ../visit/trait.IntoNodeIdentifiers.html#tymethod.node_identifiers
559/// [2]: struct.MatrixGraph.html
560pub struct NodeIdentifiers<'a, Ix> {
561    iter: IdIterator<'a>,
562    ix: PhantomData<Ix>,
563}
564
565impl<'a, Ix: IndexType> NodeIdentifiers<'a, Ix> {
566    fn new(iter: IdIterator<'a>) -> Self {
567        Self {
568            iter,
569            ix: PhantomData,
570        }
571    }
572}
573
574impl<'a, Ix: IndexType> Iterator for NodeIdentifiers<'a, Ix> {
575    type Item = NodeIndex<Ix>;
576
577    fn next(&mut self) -> Option<Self::Item> {
578        self.iter.next().map(NodeIndex::new)
579    }
580}
581
582/// Iterator over all nodes of a graph.
583///
584/// Created from a call to [`.node_references()`][1] on a [`MatrixGraph`][2].
585///
586/// [1]: ../visit/trait.IntoNodeReferences.html#tymethod.node_references
587/// [2]: struct.MatrixGraph.html
588pub struct NodeReferences<'a, N: 'a, Ix> {
589    nodes: &'a IdStorage<N>,
590    iter: IdIterator<'a>,
591    ix: PhantomData<Ix>,
592}
593
594impl<'a, N: 'a, Ix> NodeReferences<'a, N, Ix> {
595    fn new(nodes: &'a IdStorage<N>) -> Self {
596        NodeReferences {
597            nodes,
598            iter: nodes.iter_ids(),
599            ix: PhantomData,
600        }
601    }
602}
603
604impl<'a, N: 'a, Ix: IndexType> Iterator for NodeReferences<'a, N, Ix> {
605    type Item = (NodeIndex<Ix>, &'a N);
606
607    fn next(&mut self) -> Option<Self::Item> {
608        self.iter
609            .next()
610            .map(|i| (NodeIndex::new(i), &self.nodes[i]))
611    }
612}
613
614/// Iterator over all edges of a graph.
615///
616/// Created from a call to [`.edge_references()`][1] on a [`MatrixGraph`][2].
617///
618/// [1]: ../visit/trait.IntoEdgeReferences.html#tymethod.edge_references
619/// [2]: struct.MatrixGraph.html
620pub struct EdgeReferences<'a, Ty: EdgeType, Null: 'a + Nullable, Ix> {
621    row: usize,
622    column: usize,
623    node_adjacencies: &'a [Null],
624    node_capacity: usize,
625    ty: PhantomData<Ty>,
626    ix: PhantomData<Ix>,
627}
628
629impl<'a, Ty: EdgeType, Null: 'a + Nullable, Ix> EdgeReferences<'a, Ty, Null, Ix> {
630    fn new(node_adjacencies: &'a [Null], node_capacity: usize) -> Self {
631        EdgeReferences {
632            row: 0,
633            column: 0,
634            node_adjacencies,
635            node_capacity,
636            ty: PhantomData,
637            ix: PhantomData,
638        }
639    }
640}
641
642impl<'a, Ty: EdgeType, Null: Nullable, Ix: IndexType> Iterator
643    for EdgeReferences<'a, Ty, Null, Ix>
644{
645    type Item = (NodeIndex<Ix>, NodeIndex<Ix>, &'a Null::Wrapped);
646
647    fn next(&mut self) -> Option<Self::Item> {
648        loop {
649            let (row, column) = (self.row, self.column);
650            if row >= self.node_capacity {
651                return None;
652            }
653
654            // By default, advance the column. Reset and advance the row if the column overflows.
655            //
656            // Note that for undirected graphs, we don't want to yield the same edge twice,
657            // therefore the maximum column length should be the index new after the row index.
658            self.column += 1;
659            let max_column_len = if !Ty::is_directed() {
660                row + 1
661            } else {
662                self.node_capacity
663            };
664            if self.column >= max_column_len {
665                self.column = 0;
666                self.row += 1;
667            }
668
669            let p = to_linearized_matrix_position::<Ty>(row, column, self.node_capacity);
670            if let Some(e) = self.node_adjacencies[p].as_ref() {
671                return Some((NodeIndex::new(row), NodeIndex::new(column), e));
672            }
673        }
674    }
675}
676
677/// Iterator over the neighbors of a node.
678///
679/// Iterator element type is `NodeIndex<Ix>`.
680///
681/// Created with [`.neighbors()`][1], [`.neighbors_directed()`][2].
682///
683/// [1]: struct.MatrixGraph.html#method.neighbors
684/// [2]: struct.MatrixGraph.html#method.neighbors_directed
685pub struct Neighbors<'a, Ty: EdgeType, Null: 'a + Nullable, Ix>(Edges<'a, Ty, Null, Ix>);
686
687impl<'a, Ty: EdgeType, Null: Nullable, Ix: IndexType> Iterator for Neighbors<'a, Ty, Null, Ix> {
688    type Item = NodeIndex<Ix>;
689
690    fn next(&mut self) -> Option<Self::Item> {
691        self.0.next().map(|(_, b, _)| b)
692    }
693}
694
695enum NeighborIterDirection {
696    Rows,
697    Columns,
698}
699
700/// Iterator over the edges of from or to a node
701///
702/// Created with [`.edges()`][1], [`.edges_directed()`][2].
703///
704/// [1]: struct.MatrixGraph.html#method.edges
705/// [2]: struct.MatrixGraph.html#method.edges_directed
706pub struct Edges<'a, Ty: EdgeType, Null: 'a + Nullable, Ix> {
707    iter_direction: NeighborIterDirection,
708    node_adjacencies: &'a [Null],
709    node_capacity: usize,
710    row: usize,
711    column: usize,
712    ty: PhantomData<Ty>,
713    ix: PhantomData<Ix>,
714}
715
716impl<'a, Ty: EdgeType, Null: 'a + Nullable, Ix> Edges<'a, Ty, Null, Ix> {
717    fn on_columns(row: usize, node_adjacencies: &'a [Null], node_capacity: usize) -> Self {
718        Edges {
719            iter_direction: NeighborIterDirection::Columns,
720            node_adjacencies,
721            node_capacity,
722            row,
723            column: 0,
724            ty: PhantomData,
725            ix: PhantomData,
726        }
727    }
728
729    fn on_rows(column: usize, node_adjacencies: &'a [Null], node_capacity: usize) -> Self {
730        Edges {
731            iter_direction: NeighborIterDirection::Rows,
732            node_adjacencies,
733            node_capacity,
734            row: 0,
735            column,
736            ty: PhantomData,
737            ix: PhantomData,
738        }
739    }
740}
741
742impl<'a, Ty: EdgeType, Null: Nullable, Ix: IndexType> Iterator for Edges<'a, Ty, Null, Ix> {
743    type Item = (NodeIndex<Ix>, NodeIndex<Ix>, &'a Null::Wrapped);
744
745    fn next(&mut self) -> Option<Self::Item> {
746        use self::NeighborIterDirection::*;
747
748        loop {
749            let (row, column) = (self.row, self.column);
750            if row >= self.node_capacity || column >= self.node_capacity {
751                return None;
752            }
753
754            match self.iter_direction {
755                Rows => self.row += 1,
756                Columns => self.column += 1,
757            }
758
759            let p = to_linearized_matrix_position::<Ty>(row, column, self.node_capacity);
760            if let Some(e) = self.node_adjacencies[p].as_ref() {
761                let (a, b) = match self.iter_direction {
762                    Rows => (column, row),
763                    Columns => (row, column),
764                };
765
766                return Some((NodeIndex::new(a), NodeIndex::new(b), e));
767            }
768        }
769    }
770}
771
772#[inline]
773fn to_linearized_matrix_position<Ty: EdgeType>(row: usize, column: usize, width: usize) -> usize {
774    if Ty::is_directed() {
775        to_flat_square_matrix_position(row, column, width)
776    } else {
777        to_lower_triangular_matrix_position(row, column)
778    }
779}
780
781#[inline]
782fn extend_linearized_matrix<Ty: EdgeType, T: Default>(
783    node_adjacencies: &mut Vec<T>,
784    old_node_capacity: usize,
785    min_node_capacity: usize,
786) -> usize {
787    if Ty::is_directed() {
788        extend_flat_square_matrix(node_adjacencies, old_node_capacity, min_node_capacity)
789    } else {
790        extend_lower_triangular_matrix(node_adjacencies, min_node_capacity)
791    }
792}
793
794#[inline]
795fn to_flat_square_matrix_position(row: usize, column: usize, width: usize) -> usize {
796    row * width + column
797}
798
799#[inline]
800fn extend_flat_square_matrix<T: Default>(
801    node_adjacencies: &mut Vec<T>,
802    old_node_capacity: usize,
803    min_node_capacity: usize,
804) -> usize {
805    let min_node_capacity = (min_node_capacity + 1).next_power_of_two();
806
807    // Optimization: when resizing the matrix this way we skip the first few grows to make
808    // small matrices a bit faster to work with.
809    const MIN_CAPACITY: usize = 4;
810    let new_node_capacity = cmp::max(min_node_capacity, MIN_CAPACITY);
811
812    let mut new_node_adjacencies = vec![];
813    ensure_len(&mut new_node_adjacencies, new_node_capacity.pow(2));
814
815    for c in 0..old_node_capacity {
816        let pos = c * old_node_capacity;
817        let new_pos = c * new_node_capacity;
818
819        let mut old = &mut node_adjacencies[pos..pos + old_node_capacity];
820        let mut new = &mut new_node_adjacencies[new_pos..new_pos + old_node_capacity];
821
822        mem::swap(&mut old, &mut new);
823    }
824
825    mem::swap(node_adjacencies, &mut new_node_adjacencies);
826
827    new_node_capacity
828}
829
830#[inline]
831fn to_lower_triangular_matrix_position(row: usize, column: usize) -> usize {
832    let (row, column) = if row > column {
833        (row, column)
834    } else {
835        (column, row)
836    };
837    (row * (row + 1)) / 2 + column
838}
839
840#[inline]
841fn extend_lower_triangular_matrix<T: Default>(
842    node_adjacencies: &mut Vec<T>,
843    new_node_capacity: usize,
844) -> usize {
845    let max_pos = to_lower_triangular_matrix_position(new_node_capacity, new_node_capacity);
846    ensure_len(node_adjacencies, max_pos + 1);
847    new_node_capacity + 1
848}
849
850/// Grow a Vec by appending the type's default value until the `size` is reached.
851fn ensure_len<T: Default>(v: &mut Vec<T>, size: usize) {
852    if let Some(n) = size.checked_sub(v.len()) {
853        v.reserve(n);
854        for _ in 0..n {
855            v.push(T::default());
856        }
857    }
858}
859
860#[derive(Clone)]
861struct IdStorage<T> {
862    elements: Vec<Option<T>>,
863    upper_bound: usize,
864    removed_ids: IndexSet<usize>,
865}
866
867impl<T> IdStorage<T> {
868    fn with_capacity(capacity: usize) -> Self {
869        IdStorage {
870            elements: Vec::with_capacity(capacity),
871            upper_bound: 0,
872            removed_ids: IndexSet::new(),
873        }
874    }
875
876    fn add(&mut self, element: T) -> usize {
877        let id = if let Some(id) = self.removed_ids.pop() {
878            id
879        } else {
880            let id = self.upper_bound;
881            self.upper_bound += 1;
882
883            ensure_len(&mut self.elements, id + 1);
884
885            id
886        };
887
888        self.elements[id] = Some(element);
889
890        id
891    }
892
893    fn remove(&mut self, id: usize) -> T {
894        let data = self.elements[id].take().unwrap();
895        if self.upper_bound - id == 1 {
896            self.upper_bound -= 1;
897        } else {
898            self.removed_ids.insert(id);
899        }
900        data
901    }
902
903    fn clear(&mut self) {
904        self.upper_bound = 0;
905        self.elements.clear();
906        self.removed_ids.clear();
907    }
908
909    #[inline]
910    fn len(&self) -> usize {
911        self.upper_bound - self.removed_ids.len()
912    }
913
914    fn iter_ids(&self) -> IdIterator {
915        IdIterator {
916            upper_bound: self.upper_bound,
917            removed_ids: &self.removed_ids,
918            current: None,
919        }
920    }
921}
922
923impl<T> Index<usize> for IdStorage<T> {
924    type Output = T;
925    fn index(&self, index: usize) -> &T {
926        self.elements[index].as_ref().unwrap()
927    }
928}
929
930impl<T> IndexMut<usize> for IdStorage<T> {
931    fn index_mut(&mut self, index: usize) -> &mut T {
932        self.elements[index].as_mut().unwrap()
933    }
934}
935
936struct IdIterator<'a> {
937    upper_bound: usize,
938    removed_ids: &'a IndexSet<usize>,
939    current: Option<usize>,
940}
941
942impl<'a> Iterator for IdIterator<'a> {
943    type Item = usize;
944
945    fn next(&mut self) -> Option<Self::Item> {
946        // initialize / advance
947        let current = {
948            if self.current.is_none() {
949                self.current = Some(0);
950                self.current.as_mut().unwrap()
951            } else {
952                let current = self.current.as_mut().unwrap();
953                *current += 1;
954                current
955            }
956        };
957
958        // skip removed ids
959        while self.removed_ids.contains(current) && *current < self.upper_bound {
960            *current += 1;
961        }
962
963        if *current < self.upper_bound {
964            Some(*current)
965        } else {
966            None
967        }
968    }
969}
970
971/// Create a new empty `MatrixGraph`.
972impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> Default
973    for MatrixGraph<N, E, Ty, Null, Ix>
974{
975    fn default() -> Self {
976        Self::with_capacity(0)
977    }
978}
979
980impl<N, E> MatrixGraph<N, E, Directed> {
981    /// Create a new `MatrixGraph` with directed edges.
982    ///
983    /// This is a convenience method. Use `MatrixGraph::with_capacity` or `MatrixGraph::default` for
984    /// a constructor that is generic in all the type parameters of `MatrixGraph`.
985    pub fn new() -> Self {
986        MatrixGraph::default()
987    }
988}
989
990impl<N, E> MatrixGraph<N, E, Undirected> {
991    /// Create a new `MatrixGraph` with undirected edges.
992    ///
993    /// This is a convenience method. Use `MatrixGraph::with_capacity` or `MatrixGraph::default` for
994    /// a constructor that is generic in all the type parameters of `MatrixGraph`.
995    pub fn new_undirected() -> Self {
996        MatrixGraph::default()
997    }
998}
999
1000/// Index the `MatrixGraph` by `NodeIndex` to access node weights.
1001///
1002/// **Panics** if the node doesn't exist.
1003impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> Index<NodeIndex<Ix>>
1004    for MatrixGraph<N, E, Ty, Null, Ix>
1005{
1006    type Output = N;
1007
1008    fn index(&self, ax: NodeIndex<Ix>) -> &N {
1009        self.node_weight(ax)
1010    }
1011}
1012
1013/// Index the `MatrixGraph` by `NodeIndex` to access node weights.
1014///
1015/// **Panics** if the node doesn't exist.
1016impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> IndexMut<NodeIndex<Ix>>
1017    for MatrixGraph<N, E, Ty, Null, Ix>
1018{
1019    fn index_mut(&mut self, ax: NodeIndex<Ix>) -> &mut N {
1020        self.node_weight_mut(ax)
1021    }
1022}
1023
1024impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> NodeCount
1025    for MatrixGraph<N, E, Ty, Null, Ix>
1026{
1027    fn node_count(&self) -> usize {
1028        MatrixGraph::node_count(self)
1029    }
1030}
1031
1032/// Index the `MatrixGraph` by `NodeIndex` pair to access edge weights.
1033///
1034/// Also available with indexing syntax: `&graph[e]`.
1035///
1036/// **Panics** if no edge exists between `a` and `b`.
1037impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType>
1038    Index<(NodeIndex<Ix>, NodeIndex<Ix>)> for MatrixGraph<N, E, Ty, Null, Ix>
1039{
1040    type Output = E;
1041
1042    fn index(&self, (ax, bx): (NodeIndex<Ix>, NodeIndex<Ix>)) -> &E {
1043        self.edge_weight(ax, bx)
1044    }
1045}
1046
1047/// Index the `MatrixGraph` by `NodeIndex` pair to access edge weights.
1048///
1049/// Also available with indexing syntax: `&mut graph[e]`.
1050///
1051/// **Panics** if no edge exists between `a` and `b`.
1052impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType>
1053    IndexMut<(NodeIndex<Ix>, NodeIndex<Ix>)> for MatrixGraph<N, E, Ty, Null, Ix>
1054{
1055    fn index_mut(&mut self, (ax, bx): (NodeIndex<Ix>, NodeIndex<Ix>)) -> &mut E {
1056        self.edge_weight_mut(ax, bx)
1057    }
1058}
1059
1060impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> GetAdjacencyMatrix
1061    for MatrixGraph<N, E, Ty, Null, Ix>
1062{
1063    type AdjMatrix = ();
1064
1065    fn adjacency_matrix(&self) -> Self::AdjMatrix {}
1066
1067    fn is_adjacent(&self, _: &Self::AdjMatrix, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
1068        MatrixGraph::has_edge(self, a, b)
1069    }
1070}
1071
1072impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> Visitable
1073    for MatrixGraph<N, E, Ty, Null, Ix>
1074{
1075    type Map = FixedBitSet;
1076
1077    fn visit_map(&self) -> FixedBitSet {
1078        FixedBitSet::with_capacity(self.node_count())
1079    }
1080
1081    fn reset_map(&self, map: &mut Self::Map) {
1082        map.clear();
1083        map.grow(self.node_count());
1084    }
1085}
1086
1087impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> GraphBase
1088    for MatrixGraph<N, E, Ty, Null, Ix>
1089{
1090    type NodeId = NodeIndex<Ix>;
1091    type EdgeId = (NodeIndex<Ix>, NodeIndex<Ix>);
1092}
1093
1094impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> GraphProp
1095    for MatrixGraph<N, E, Ty, Null, Ix>
1096{
1097    type EdgeType = Ty;
1098}
1099
1100impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> Data
1101    for MatrixGraph<N, E, Ty, Null, Ix>
1102{
1103    type NodeWeight = N;
1104    type EdgeWeight = E;
1105}
1106
1107impl<'a, N, E: 'a, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> IntoNodeIdentifiers
1108    for &'a MatrixGraph<N, E, Ty, Null, Ix>
1109{
1110    type NodeIdentifiers = NodeIdentifiers<'a, Ix>;
1111
1112    fn node_identifiers(self) -> Self::NodeIdentifiers {
1113        NodeIdentifiers::new(self.nodes.iter_ids())
1114    }
1115}
1116
1117impl<'a, N, E: 'a, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> IntoNeighbors
1118    for &'a MatrixGraph<N, E, Ty, Null, Ix>
1119{
1120    type Neighbors = Neighbors<'a, Ty, Null, Ix>;
1121
1122    fn neighbors(self, a: NodeIndex<Ix>) -> Self::Neighbors {
1123        MatrixGraph::neighbors(self, a)
1124    }
1125}
1126
1127impl<'a, N, E: 'a, Null: Nullable<Wrapped = E>, Ix: IndexType> IntoNeighborsDirected
1128    for &'a MatrixGraph<N, E, Directed, Null, Ix>
1129{
1130    type NeighborsDirected = Neighbors<'a, Directed, Null, Ix>;
1131
1132    fn neighbors_directed(self, a: NodeIndex<Ix>, d: Direction) -> Self::NeighborsDirected {
1133        MatrixGraph::neighbors_directed(self, a, d)
1134    }
1135}
1136
1137impl<'a, N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> IntoNodeReferences
1138    for &'a MatrixGraph<N, E, Ty, Null, Ix>
1139{
1140    type NodeRef = (NodeIndex<Ix>, &'a N);
1141    type NodeReferences = NodeReferences<'a, N, Ix>;
1142    fn node_references(self) -> Self::NodeReferences {
1143        NodeReferences::new(&self.nodes)
1144    }
1145}
1146
1147impl<'a, N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> IntoEdgeReferences
1148    for &'a MatrixGraph<N, E, Ty, Null, Ix>
1149{
1150    type EdgeRef = (NodeIndex<Ix>, NodeIndex<Ix>, &'a E);
1151    type EdgeReferences = EdgeReferences<'a, Ty, Null, Ix>;
1152    fn edge_references(self) -> Self::EdgeReferences {
1153        EdgeReferences::new(&self.node_adjacencies, self.node_capacity)
1154    }
1155}
1156
1157impl<'a, N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> IntoEdges
1158    for &'a MatrixGraph<N, E, Ty, Null, Ix>
1159{
1160    type Edges = Edges<'a, Ty, Null, Ix>;
1161    fn edges(self, a: Self::NodeId) -> Self::Edges {
1162        MatrixGraph::edges(self, a)
1163    }
1164}
1165
1166impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> NodeIndexable
1167    for MatrixGraph<N, E, Ty, Null, Ix>
1168{
1169    fn node_bound(&self) -> usize {
1170        self.node_count()
1171    }
1172
1173    fn to_index(&self, ix: NodeIndex<Ix>) -> usize {
1174        ix.index()
1175    }
1176
1177    fn from_index(&self, ix: usize) -> Self::NodeId {
1178        NodeIndex::new(ix)
1179    }
1180}
1181
1182impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> NodeCompactIndexable
1183    for MatrixGraph<N, E, Ty, Null, Ix>
1184{
1185}
1186
1187impl<N, E, Ty: EdgeType, Null: Nullable<Wrapped = E>, Ix: IndexType> Build
1188    for MatrixGraph<N, E, Ty, Null, Ix>
1189{
1190    fn add_node(&mut self, weight: Self::NodeWeight) -> Self::NodeId {
1191        self.add_node(weight)
1192    }
1193
1194    fn add_edge(
1195        &mut self,
1196        a: Self::NodeId,
1197        b: Self::NodeId,
1198        weight: Self::EdgeWeight,
1199    ) -> Option<Self::EdgeId> {
1200        if !self.has_edge(a, b) {
1201            MatrixGraph::update_edge(self, a, b, weight);
1202            Some((a, b))
1203        } else {
1204            None
1205        }
1206    }
1207
1208    fn update_edge(
1209        &mut self,
1210        a: Self::NodeId,
1211        b: Self::NodeId,
1212        weight: Self::EdgeWeight,
1213    ) -> Self::EdgeId {
1214        MatrixGraph::update_edge(self, a, b, weight);
1215        (a, b)
1216    }
1217}
1218
1219#[cfg(test)]
1220mod tests {
1221    use super::*;
1222    use crate::{Incoming, Outgoing};
1223
1224    #[test]
1225    fn test_new() {
1226        let g = MatrixGraph::<i32, i32>::new();
1227        assert_eq!(g.node_count(), 0);
1228        assert_eq!(g.edge_count(), 0);
1229    }
1230
1231    #[test]
1232    fn test_default() {
1233        let g = MatrixGraph::<i32, i32>::default();
1234        assert_eq!(g.node_count(), 0);
1235        assert_eq!(g.edge_count(), 0);
1236    }
1237
1238    #[test]
1239    fn test_with_capacity() {
1240        let g = MatrixGraph::<i32, i32>::with_capacity(10);
1241        assert_eq!(g.node_count(), 0);
1242        assert_eq!(g.edge_count(), 0);
1243    }
1244
1245    #[test]
1246    fn test_node_indexing() {
1247        let mut g: MatrixGraph<char, ()> = MatrixGraph::new();
1248        let a = g.add_node('a');
1249        let b = g.add_node('b');
1250        assert_eq!(g.node_count(), 2);
1251        assert_eq!(g.edge_count(), 0);
1252        assert_eq!(g[a], 'a');
1253        assert_eq!(g[b], 'b');
1254    }
1255
1256    #[test]
1257    fn test_remove_node() {
1258        let mut g: MatrixGraph<char, ()> = MatrixGraph::new();
1259        let a = g.add_node('a');
1260
1261        g.remove_node(a);
1262
1263        assert_eq!(g.node_count(), 0);
1264        assert_eq!(g.edge_count(), 0);
1265    }
1266
1267    #[test]
1268    fn test_add_edge() {
1269        let mut g = MatrixGraph::new();
1270        let a = g.add_node('a');
1271        let b = g.add_node('b');
1272        let c = g.add_node('c');
1273        g.add_edge(a, b, ());
1274        g.add_edge(b, c, ());
1275        assert_eq!(g.node_count(), 3);
1276        assert_eq!(g.edge_count(), 2);
1277    }
1278
1279    #[test]
1280    fn test_add_edge_with_weights() {
1281        let mut g = MatrixGraph::new();
1282        let a = g.add_node('a');
1283        let b = g.add_node('b');
1284        let c = g.add_node('c');
1285        g.add_edge(a, b, true);
1286        g.add_edge(b, c, false);
1287        assert_eq!(*g.edge_weight(a, b), true);
1288        assert_eq!(*g.edge_weight(b, c), false);
1289    }
1290
1291    #[test]
1292    fn test_add_edge_with_weights_undirected() {
1293        let mut g = MatrixGraph::new_undirected();
1294        let a = g.add_node('a');
1295        let b = g.add_node('b');
1296        let c = g.add_node('c');
1297        let d = g.add_node('d');
1298        g.add_edge(a, b, "ab");
1299        g.add_edge(a, a, "aa");
1300        g.add_edge(b, c, "bc");
1301        g.add_edge(d, d, "dd");
1302        assert_eq!(*g.edge_weight(a, b), "ab");
1303        assert_eq!(*g.edge_weight(b, c), "bc");
1304    }
1305
1306    /// Shorthand for `.collect::<Vec<_>>()`
1307    trait IntoVec<T> {
1308        fn into_vec(self) -> Vec<T>;
1309    }
1310
1311    impl<It, T> IntoVec<T> for It
1312    where
1313        It: Iterator<Item = T>,
1314    {
1315        fn into_vec(self) -> Vec<T> {
1316            self.collect()
1317        }
1318    }
1319
1320    #[test]
1321    fn test_clear() {
1322        let mut g = MatrixGraph::new();
1323        let a = g.add_node('a');
1324        let b = g.add_node('b');
1325        let c = g.add_node('c');
1326        assert_eq!(g.node_count(), 3);
1327
1328        g.add_edge(a, b, ());
1329        g.add_edge(b, c, ());
1330        g.add_edge(c, a, ());
1331        assert_eq!(g.edge_count(), 3);
1332
1333        g.clear();
1334
1335        assert_eq!(g.node_count(), 0);
1336        assert_eq!(g.edge_count(), 0);
1337
1338        let a = g.add_node('a');
1339        let b = g.add_node('b');
1340        let c = g.add_node('c');
1341        assert_eq!(g.node_count(), 3);
1342        assert_eq!(g.edge_count(), 0);
1343
1344        assert_eq!(g.neighbors_directed(a, Incoming).into_vec(), vec![]);
1345        assert_eq!(g.neighbors_directed(b, Incoming).into_vec(), vec![]);
1346        assert_eq!(g.neighbors_directed(c, Incoming).into_vec(), vec![]);
1347
1348        assert_eq!(g.neighbors_directed(a, Outgoing).into_vec(), vec![]);
1349        assert_eq!(g.neighbors_directed(b, Outgoing).into_vec(), vec![]);
1350        assert_eq!(g.neighbors_directed(c, Outgoing).into_vec(), vec![]);
1351    }
1352
1353    #[test]
1354    fn test_clear_undirected() {
1355        let mut g = MatrixGraph::new_undirected();
1356        let a = g.add_node('a');
1357        let b = g.add_node('b');
1358        let c = g.add_node('c');
1359        assert_eq!(g.node_count(), 3);
1360
1361        g.add_edge(a, b, ());
1362        g.add_edge(b, c, ());
1363        g.add_edge(c, a, ());
1364        assert_eq!(g.edge_count(), 3);
1365
1366        g.clear();
1367
1368        assert_eq!(g.node_count(), 0);
1369        assert_eq!(g.edge_count(), 0);
1370
1371        let a = g.add_node('a');
1372        let b = g.add_node('b');
1373        let c = g.add_node('c');
1374        assert_eq!(g.node_count(), 3);
1375        assert_eq!(g.edge_count(), 0);
1376
1377        assert_eq!(g.neighbors(a).into_vec(), vec![]);
1378        assert_eq!(g.neighbors(b).into_vec(), vec![]);
1379        assert_eq!(g.neighbors(c).into_vec(), vec![]);
1380    }
1381
1382    /// Helper trait for always sorting before testing.
1383    trait IntoSortedVec<T> {
1384        fn into_sorted_vec(self) -> Vec<T>;
1385    }
1386
1387    impl<It, T> IntoSortedVec<T> for It
1388    where
1389        It: Iterator<Item = T>,
1390        T: Ord,
1391    {
1392        fn into_sorted_vec(self) -> Vec<T> {
1393            let mut v: Vec<T> = self.collect();
1394            v.sort();
1395            v
1396        }
1397    }
1398
1399    /// Helper macro for always sorting before testing.
1400    macro_rules! sorted_vec {
1401        ($($x:expr),*) => {
1402            {
1403                let mut v = vec![$($x,)*];
1404                v.sort();
1405                v
1406            }
1407        }
1408    }
1409
1410    #[test]
1411    fn test_neighbors() {
1412        let mut g = MatrixGraph::new();
1413        let a = g.add_node('a');
1414        let b = g.add_node('b');
1415        let c = g.add_node('c');
1416        g.add_edge(a, b, ());
1417        g.add_edge(a, c, ());
1418
1419        let a_neighbors = g.neighbors(a).into_sorted_vec();
1420        assert_eq!(a_neighbors, sorted_vec![b, c]);
1421
1422        let b_neighbors = g.neighbors(b).into_sorted_vec();
1423        assert_eq!(b_neighbors, vec![]);
1424
1425        let c_neighbors = g.neighbors(c).into_sorted_vec();
1426        assert_eq!(c_neighbors, vec![]);
1427    }
1428
1429    #[test]
1430    fn test_neighbors_undirected() {
1431        let mut g = MatrixGraph::new_undirected();
1432        let a = g.add_node('a');
1433        let b = g.add_node('b');
1434        let c = g.add_node('c');
1435        g.add_edge(a, b, ());
1436        g.add_edge(a, c, ());
1437
1438        let a_neighbors = g.neighbors(a).into_sorted_vec();
1439        assert_eq!(a_neighbors, sorted_vec![b, c]);
1440
1441        let b_neighbors = g.neighbors(b).into_sorted_vec();
1442        assert_eq!(b_neighbors, sorted_vec![a]);
1443
1444        let c_neighbors = g.neighbors(c).into_sorted_vec();
1445        assert_eq!(c_neighbors, sorted_vec![a]);
1446    }
1447
1448    #[test]
1449    fn test_remove_node_and_edges() {
1450        let mut g = MatrixGraph::new();
1451        let a = g.add_node('a');
1452        let b = g.add_node('b');
1453        let c = g.add_node('c');
1454        g.add_edge(a, b, ());
1455        g.add_edge(b, c, ());
1456        g.add_edge(c, a, ());
1457
1458        // removing b should break the `a -> b` and `b -> c` edges
1459        g.remove_node(b);
1460
1461        assert_eq!(g.node_count(), 2);
1462
1463        let a_neighbors = g.neighbors(a).into_sorted_vec();
1464        assert_eq!(a_neighbors, vec![]);
1465
1466        let c_neighbors = g.neighbors(c).into_sorted_vec();
1467        assert_eq!(c_neighbors, vec![a]);
1468    }
1469
1470    #[test]
1471    fn test_remove_node_and_edges_undirected() {
1472        let mut g = UnMatrix::new_undirected();
1473        let a = g.add_node('a');
1474        let b = g.add_node('b');
1475        let c = g.add_node('c');
1476        g.add_edge(a, b, ());
1477        g.add_edge(b, c, ());
1478        g.add_edge(c, a, ());
1479
1480        // removing a should break the `a - b` and `a - c` edges
1481        g.remove_node(a);
1482
1483        assert_eq!(g.node_count(), 2);
1484
1485        let b_neighbors = g.neighbors(b).into_sorted_vec();
1486        assert_eq!(b_neighbors, vec![c]);
1487
1488        let c_neighbors = g.neighbors(c).into_sorted_vec();
1489        assert_eq!(c_neighbors, vec![b]);
1490    }
1491
1492    #[test]
1493    fn test_node_identifiers() {
1494        let mut g = MatrixGraph::new();
1495        let a = g.add_node('a');
1496        let b = g.add_node('b');
1497        let c = g.add_node('c');
1498        let d = g.add_node('c');
1499        g.add_edge(a, b, ());
1500        g.add_edge(a, c, ());
1501
1502        let node_ids = g.node_identifiers().into_sorted_vec();
1503        assert_eq!(node_ids, sorted_vec![a, b, c, d]);
1504    }
1505
1506    #[test]
1507    fn test_edges_directed() {
1508        let g: MatrixGraph<char, bool> = MatrixGraph::from_edges(&[
1509            (0, 5),
1510            (0, 2),
1511            (0, 3),
1512            (0, 1),
1513            (1, 3),
1514            (2, 3),
1515            (2, 4),
1516            (4, 0),
1517            (6, 6),
1518        ]);
1519
1520        assert_eq!(g.edges_directed(node_index(0), Outgoing).count(), 4);
1521        assert_eq!(g.edges_directed(node_index(1), Outgoing).count(), 1);
1522        assert_eq!(g.edges_directed(node_index(2), Outgoing).count(), 2);
1523        assert_eq!(g.edges_directed(node_index(3), Outgoing).count(), 0);
1524        assert_eq!(g.edges_directed(node_index(4), Outgoing).count(), 1);
1525        assert_eq!(g.edges_directed(node_index(5), Outgoing).count(), 0);
1526        assert_eq!(g.edges_directed(node_index(6), Outgoing).count(), 1);
1527
1528        assert_eq!(g.edges_directed(node_index(0), Incoming).count(), 1);
1529        assert_eq!(g.edges_directed(node_index(1), Incoming).count(), 1);
1530        assert_eq!(g.edges_directed(node_index(2), Incoming).count(), 1);
1531        assert_eq!(g.edges_directed(node_index(3), Incoming).count(), 3);
1532        assert_eq!(g.edges_directed(node_index(4), Incoming).count(), 1);
1533        assert_eq!(g.edges_directed(node_index(5), Incoming).count(), 1);
1534        assert_eq!(g.edges_directed(node_index(6), Incoming).count(), 1);
1535    }
1536
1537    #[test]
1538    fn test_edges_undirected() {
1539        let g: UnMatrix<char, bool> = UnMatrix::from_edges(&[
1540            (0, 5),
1541            (0, 2),
1542            (0, 3),
1543            (0, 1),
1544            (1, 3),
1545            (2, 3),
1546            (2, 4),
1547            (4, 0),
1548            (6, 6),
1549        ]);
1550
1551        assert_eq!(g.edges(node_index(0)).count(), 5);
1552        assert_eq!(g.edges(node_index(1)).count(), 2);
1553        assert_eq!(g.edges(node_index(2)).count(), 3);
1554        assert_eq!(g.edges(node_index(3)).count(), 3);
1555        assert_eq!(g.edges(node_index(4)).count(), 2);
1556        assert_eq!(g.edges(node_index(5)).count(), 1);
1557        assert_eq!(g.edges(node_index(6)).count(), 1);
1558    }
1559
1560    #[test]
1561    fn test_edges_of_absent_node_is_empty_iterator() {
1562        let g: MatrixGraph<char, bool> = MatrixGraph::new();
1563        assert_eq!(g.edges(node_index(0)).count(), 0);
1564    }
1565
1566    #[test]
1567    fn test_neighbors_of_absent_node_is_empty_iterator() {
1568        let g: MatrixGraph<char, bool> = MatrixGraph::new();
1569        assert_eq!(g.neighbors(node_index(0)).count(), 0);
1570    }
1571
1572    #[test]
1573    fn test_edge_references() {
1574        let g: MatrixGraph<char, bool> = MatrixGraph::from_edges(&[
1575            (0, 5),
1576            (0, 2),
1577            (0, 3),
1578            (0, 1),
1579            (1, 3),
1580            (2, 3),
1581            (2, 4),
1582            (4, 0),
1583            (6, 6),
1584        ]);
1585
1586        assert_eq!(g.edge_references().count(), 9);
1587    }
1588
1589    #[test]
1590    fn test_edge_references_undirected() {
1591        let g: UnMatrix<char, bool> = UnMatrix::from_edges(&[
1592            (0, 5),
1593            (0, 2),
1594            (0, 3),
1595            (0, 1),
1596            (1, 3),
1597            (2, 3),
1598            (2, 4),
1599            (4, 0),
1600            (6, 6),
1601        ]);
1602
1603        assert_eq!(g.edge_references().count(), 9);
1604    }
1605
1606    #[test]
1607    fn test_id_storage() {
1608        use super::IdStorage;
1609
1610        let mut storage: IdStorage<char> = IdStorage::with_capacity(0);
1611        let a = storage.add('a');
1612        let b = storage.add('b');
1613        let c = storage.add('c');
1614
1615        assert!(a < b && b < c);
1616
1617        // list IDs
1618        assert_eq!(storage.iter_ids().into_vec(), vec![a, b, c]);
1619
1620        storage.remove(b);
1621
1622        // re-use of IDs
1623        let bb = storage.add('B');
1624        assert_eq!(b, bb);
1625
1626        // list IDs
1627        assert_eq!(storage.iter_ids().into_vec(), vec![a, b, c]);
1628    }
1629
1630    #[test]
1631    fn test_not_zero() {
1632        let mut g: MatrixGraph<(), i32, Directed, NotZero<i32>> = MatrixGraph::default();
1633
1634        let a = g.add_node(());
1635        let b = g.add_node(());
1636
1637        assert!(!g.has_edge(a, b));
1638        assert_eq!(g.edge_count(), 0);
1639
1640        g.add_edge(a, b, 12);
1641
1642        assert!(g.has_edge(a, b));
1643        assert_eq!(g.edge_count(), 1);
1644        assert_eq!(g.edge_weight(a, b), &12);
1645
1646        g.remove_edge(a, b);
1647
1648        assert!(!g.has_edge(a, b));
1649        assert_eq!(g.edge_count(), 0);
1650    }
1651
1652    #[test]
1653    #[should_panic]
1654    fn test_not_zero_asserted() {
1655        let mut g: MatrixGraph<(), i32, Directed, NotZero<i32>> = MatrixGraph::default();
1656
1657        let a = g.add_node(());
1658        let b = g.add_node(());
1659
1660        g.add_edge(a, b, 0); // this should trigger an assertion
1661    }
1662
1663    #[test]
1664    fn test_not_zero_float() {
1665        let mut g: MatrixGraph<(), f32, Directed, NotZero<f32>> = MatrixGraph::default();
1666
1667        let a = g.add_node(());
1668        let b = g.add_node(());
1669
1670        assert!(!g.has_edge(a, b));
1671        assert_eq!(g.edge_count(), 0);
1672
1673        g.add_edge(a, b, 12.);
1674
1675        assert!(g.has_edge(a, b));
1676        assert_eq!(g.edge_count(), 1);
1677        assert_eq!(g.edge_weight(a, b), &12.);
1678
1679        g.remove_edge(a, b);
1680
1681        assert!(!g.has_edge(a, b));
1682        assert_eq!(g.edge_count(), 0);
1683    }
1684}