petgraph/
matrix_graph.rs

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