1use alloc::vec::Vec;
5use core::{
6 cmp::Ordering,
7 fmt,
8 hash::{self, BuildHasher, Hash},
9 iter::{Copied, FromIterator},
10 marker::PhantomData,
11 mem,
12 ops::{Deref, Index, IndexMut},
13 slice::Iter,
14};
15
16use hashbrown::HashSet;
17use indexmap::{
18 map::{Iter as IndexMapIter, IterMut as IndexMapIterMut, Keys},
19 IndexMap,
20};
21
22use crate::{
23 graph::{node_index, Graph},
24 visit, Directed, Direction, EdgeType, Incoming, IntoWeightedEdge, Outgoing, Undirected,
25};
26
27#[cfg(feature = "std")]
28use std::collections::hash_map::RandomState;
29
30#[cfg(feature = "rayon")]
31use {
32 indexmap::map::rayon::{ParIter, ParIterMut, ParKeys},
33 rayon::prelude::*,
34};
35
36pub type UnGraphMap<N, E, #[cfg(not(feature = "std"))] S, #[cfg(feature = "std")] S = RandomState> =
41 GraphMap<N, E, Undirected, S>;
42pub type DiGraphMap<N, E, #[cfg(not(feature = "std"))] S, #[cfg(feature = "std")] S = RandomState> =
47 GraphMap<N, E, Directed, S>;
48
49#[derive(Clone)]
74pub struct GraphMap<
75 N,
76 E,
77 Ty,
78 #[cfg(not(feature = "std"))] S,
79 #[cfg(feature = "std")] S = RandomState,
80> where
81 S: BuildHasher,
82{
83 nodes: IndexMap<N, Vec<(N, CompactDirection)>, S>,
84 edges: IndexMap<(N, N), E, S>,
85 ty: PhantomData<Ty>,
86}
87
88impl<N: Eq + Hash + fmt::Debug, E: fmt::Debug, Ty: EdgeType, S: BuildHasher> fmt::Debug
89 for GraphMap<N, E, Ty, S>
90{
91 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92 self.nodes.fmt(f)
93 }
94}
95
96pub trait NodeTrait: Copy + Ord + Hash {}
98impl<N> NodeTrait for N where N: Copy + Ord + Hash {}
99
100#[derive(Copy, Clone, Debug, PartialEq)]
102enum CompactDirection {
103 Outgoing,
104 Incoming,
105}
106
107impl CompactDirection {
108 #[inline]
110 pub fn opposite(self) -> CompactDirection {
111 match self {
112 CompactDirection::Outgoing => CompactDirection::Incoming,
113 CompactDirection::Incoming => CompactDirection::Outgoing,
114 }
115 }
116}
117
118impl From<Direction> for CompactDirection {
119 fn from(d: Direction) -> Self {
120 match d {
121 Outgoing => CompactDirection::Outgoing,
122 Incoming => CompactDirection::Incoming,
123 }
124 }
125}
126
127impl From<CompactDirection> for Direction {
128 fn from(d: CompactDirection) -> Self {
129 match d {
130 CompactDirection::Outgoing => Outgoing,
131 CompactDirection::Incoming => Incoming,
132 }
133 }
134}
135
136impl PartialEq<Direction> for CompactDirection {
137 fn eq(&self, rhs: &Direction) -> bool {
138 (*self as usize) == (*rhs as usize)
139 }
140}
141
142#[cfg(feature = "serde-1")]
143impl<N, E, Ty, S> serde::Serialize for GraphMap<N, E, Ty, S>
144where
145 Ty: EdgeType,
146 N: NodeTrait + serde::Serialize,
147 E: serde::Serialize,
148 S: BuildHasher,
149 Self: Clone,
150{
151 fn serialize<Ser>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error>
156 where
157 Ser: serde::Serializer,
158 {
159 let cloned_graph: GraphMap<N, E, Ty, S> = GraphMap::clone(self);
160 let equivalent_graph: Graph<N, E, Ty, u32> = cloned_graph.into_graph();
161 equivalent_graph.serialize(serializer)
162 }
163}
164
165#[cfg(feature = "serde-1")]
166impl<'de, N, E, Ty, S> serde::Deserialize<'de> for GraphMap<N, E, Ty, S>
167where
168 Ty: EdgeType,
169 N: NodeTrait + serde::Deserialize<'de>,
170 E: Clone + serde::Deserialize<'de>,
171 S: BuildHasher + Default,
172{
173 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
181 where
182 D: serde::Deserializer<'de>,
183 {
184 let equivalent_graph: Graph<N, E, Ty, u32> = Graph::deserialize(deserializer)?;
185 Ok(GraphMap::from_graph(equivalent_graph))
186 }
187}
188
189impl<N, E, Ty, S> GraphMap<N, E, Ty, S>
190where
191 N: NodeTrait,
192 Ty: EdgeType,
193 S: BuildHasher,
194{
195 pub fn new() -> Self
197 where
198 S: Default,
199 {
200 Self::default()
201 }
202
203 pub fn with_capacity(nodes: usize, edges: usize) -> Self
205 where
206 S: Default,
207 {
208 Self {
209 nodes: IndexMap::with_capacity_and_hasher(nodes, S::default()),
210 edges: IndexMap::with_capacity_and_hasher(edges, S::default()),
211 ty: PhantomData,
212 }
213 }
214
215 pub fn with_capacity_and_hasher(nodes: usize, edges: usize, hasher: S) -> Self
217 where
218 S: Clone,
219 {
220 Self {
221 nodes: IndexMap::with_capacity_and_hasher(nodes, hasher.clone()),
222 edges: IndexMap::with_capacity_and_hasher(edges, hasher),
223 ty: PhantomData,
224 }
225 }
226
227 pub fn capacity(&self) -> (usize, usize) {
229 (self.nodes.capacity(), self.edges.capacity())
230 }
231
232 #[inline]
234 fn edge_key(a: N, b: N) -> (N, N) {
235 if Ty::is_directed() || a <= b {
236 (a, b)
237 } else {
238 (b, a)
239 }
240 }
241
242 pub fn is_directed(&self) -> bool {
244 Ty::is_directed()
245 }
246
247 pub fn from_edges<I>(iterable: I) -> Self
267 where
268 I: IntoIterator,
269 I::Item: IntoWeightedEdge<E, NodeId = N>,
270 S: Default,
271 {
272 Self::from_iter(iterable)
273 }
274
275 pub fn node_count(&self) -> usize {
277 self.nodes.len()
278 }
279
280 pub fn edge_count(&self) -> usize {
282 self.edges.len()
283 }
284
285 pub fn clear(&mut self) {
287 self.nodes.clear();
288 self.edges.clear();
289 }
290
291 pub fn add_node(&mut self, n: N) -> N {
293 self.nodes.entry(n).or_default();
294 n
295 }
296
297 pub fn remove_node(&mut self, n: N) -> bool {
301 let links = match self.nodes.swap_remove(&n) {
302 None => return false,
303 Some(sus) => sus,
304 };
305 for (succ, dir) in links {
306 let edge = if dir == CompactDirection::Outgoing {
307 Self::edge_key(n, succ)
308 } else {
309 Self::edge_key(succ, n)
310 };
311 self.remove_single_edge(&succ, &n, dir.opposite());
313 self.edges.swap_remove(&edge);
315 }
316 true
317 }
318
319 pub fn contains_node(&self, n: N) -> bool {
321 self.nodes.contains_key(&n)
322 }
323
324 pub fn add_edge(&mut self, a: N, b: N, weight: E) -> Option<E> {
346 if let old @ Some(_) = self.edges.insert(Self::edge_key(a, b), weight) {
347 old
348 } else {
349 self.nodes
351 .entry(a)
352 .or_insert_with(|| Vec::with_capacity(1))
353 .push((b, CompactDirection::Outgoing));
354 if a != b {
355 self.nodes
357 .entry(b)
358 .or_insert_with(|| Vec::with_capacity(1))
359 .push((a, CompactDirection::Incoming));
360 }
361 None
362 }
363 }
364
365 fn remove_single_edge(&mut self, a: &N, b: &N, dir: CompactDirection) -> bool {
369 match self.nodes.get_mut(a) {
370 None => false,
371 Some(sus) => {
372 if Ty::is_directed() {
373 match sus.iter().position(|elt| elt == &(*b, dir)) {
374 Some(index) => {
375 sus.swap_remove(index);
376 true
377 }
378 None => false,
379 }
380 } else {
381 match sus.iter().position(|elt| &elt.0 == b) {
382 Some(index) => {
383 sus.swap_remove(index);
384 true
385 }
386 None => false,
387 }
388 }
389 }
390 }
391 }
392
393 pub fn remove_edge(&mut self, a: N, b: N) -> Option<E> {
409 let exist1 = self.remove_single_edge(&a, &b, CompactDirection::Outgoing);
410 let exist2 = if a != b {
411 self.remove_single_edge(&b, &a, CompactDirection::Incoming)
412 } else {
413 exist1
414 };
415 let weight = self.edges.swap_remove(&Self::edge_key(a, b));
416 debug_assert!(exist1 == exist2 && exist1 == weight.is_some());
417 weight
418 }
419
420 pub fn contains_edge(&self, a: N, b: N) -> bool {
422 self.edges.contains_key(&Self::edge_key(a, b))
423 }
424
425 pub fn nodes(&self) -> Nodes<'_, N> {
429 Nodes {
430 iter: self.nodes.keys().copied(),
431 }
432 }
433
434 #[cfg(feature = "rayon")]
438 pub fn par_nodes(&self) -> ParNodes<'_, N>
439 where
440 N: Send + Sync,
441 {
442 ParNodes {
443 iter: self.nodes.par_keys(),
444 }
445 }
446
447 pub fn neighbors(&self, a: N) -> Neighbors<N, Ty> {
455 Neighbors {
456 iter: match self.nodes.get(&a) {
457 Some(neigh) => neigh.iter(),
458 None => [].iter(),
459 },
460 ty: self.ty,
461 }
462 }
463
464 pub fn neighbors_directed(&self, a: N, dir: Direction) -> NeighborsDirected<N, Ty> {
475 NeighborsDirected {
476 iter: match self.nodes.get(&a) {
477 Some(neigh) => neigh.iter(),
478 None => [].iter(),
479 },
480 start_node: a,
481 dir,
482 ty: self.ty,
483 }
484 }
485
486 pub fn edges(&self, a: N) -> Edges<N, E, Ty, S> {
495 Edges {
496 from: a,
497 iter: self.neighbors(a),
498 edges: &self.edges,
499 }
500 }
501
502 pub fn edges_directed(&self, a: N, dir: Direction) -> EdgesDirected<N, E, Ty, S> {
515 EdgesDirected {
516 from: a,
517 iter: self.neighbors_directed(a, dir),
518 dir,
519 edges: &self.edges,
520 }
521 }
522
523 pub fn edge_weight(&self, a: N, b: N) -> Option<&E> {
526 self.edges.get(&Self::edge_key(a, b))
527 }
528
529 pub fn edge_weight_mut(&mut self, a: N, b: N) -> Option<&mut E> {
532 self.edges.get_mut(&Self::edge_key(a, b))
533 }
534
535 pub fn all_edges(&self) -> AllEdges<N, E, Ty> {
539 AllEdges {
540 inner: self.edges.iter(),
541 ty: self.ty,
542 }
543 }
544
545 pub fn all_edges_mut(&mut self) -> AllEdgesMut<N, E, Ty> {
550 AllEdgesMut {
551 inner: self.edges.iter_mut(),
552 ty: self.ty,
553 }
554 }
555
556 #[cfg(feature = "rayon")]
561 pub fn par_all_edges(&self) -> ParAllEdges<N, E, Ty>
562 where
563 N: Send + Sync,
564 E: Sync,
565 {
566 ParAllEdges {
567 inner: self.edges.par_iter(),
568 ty: PhantomData,
569 }
570 }
571
572 #[cfg(feature = "rayon")]
577 pub fn par_all_edges_mut(&mut self) -> ParAllEdgesMut<N, E, Ty>
578 where
579 N: Send + Sync,
580 E: Send,
581 {
582 ParAllEdgesMut {
583 inner: self.edges.par_iter_mut(),
584 ty: PhantomData,
585 }
586 }
587
588 #[track_caller]
600 pub fn into_graph<Ix>(self) -> Graph<N, E, Ty, Ix>
601 where
602 Ix: crate::graph::IndexType,
603 {
604 let mut gr = Graph::with_capacity(self.node_count(), self.edge_count());
606 for (&node, _) in &self.nodes {
607 gr.add_node(node);
608 }
609 for ((a, b), edge_weight) in self.edges {
610 let ai = self.nodes.get_index_of(&a).unwrap();
611 let bi = self.nodes.get_index_of(&b).unwrap();
612 gr.add_edge(node_index(ai), node_index(bi), edge_weight);
613 }
614 gr
615 }
616
617 pub fn from_graph<Ix>(graph: Graph<N, E, Ty, Ix>) -> Self
625 where
626 Ix: crate::graph::IndexType,
627 E: Clone,
628 S: Default,
629 {
630 let mut new_graph: GraphMap<N, E, Ty, S> =
631 GraphMap::with_capacity(graph.node_count(), graph.edge_count());
632
633 for node in graph.raw_nodes() {
634 new_graph.add_node(node.weight);
635 }
636
637 for edge in graph.edge_indices() {
638 let (a, b) = graph.edge_endpoints(edge).unwrap();
639 new_graph.add_edge(
640 *graph.node_weight(a).unwrap(),
641 *graph.node_weight(b).unwrap(),
642 graph.edge_weight(edge).unwrap().clone(),
643 );
644 }
645
646 new_graph
647 }
648}
649
650impl<N, E, Ty, Item, S> FromIterator<Item> for GraphMap<N, E, Ty, S>
652where
653 Item: IntoWeightedEdge<E, NodeId = N>,
654 N: NodeTrait,
655 Ty: EdgeType,
656 S: BuildHasher + Default,
657{
658 fn from_iter<I>(iterable: I) -> Self
659 where
660 I: IntoIterator<Item = Item>,
661 {
662 let iter = iterable.into_iter();
663 let (low, _) = iter.size_hint();
664 let mut g = Self::with_capacity(0, low);
665 g.extend(iter);
666 g
667 }
668}
669
670impl<N, E, Ty, Item, S> Extend<Item> for GraphMap<N, E, Ty, S>
674where
675 Item: IntoWeightedEdge<E, NodeId = N>,
676 N: NodeTrait,
677 Ty: EdgeType,
678 S: BuildHasher,
679{
680 fn extend<I>(&mut self, iterable: I)
681 where
682 I: IntoIterator<Item = Item>,
683 {
684 let iter = iterable.into_iter();
685 let (low, _) = iter.size_hint();
686 self.edges.reserve(low);
687
688 for elt in iter {
689 let (source, target, weight) = elt.into_weighted_edge();
690 self.add_edge(source, target, weight);
691 }
692 }
693}
694
695iterator_wrap! {
696 impl (Iterator DoubleEndedIterator ExactSizeIterator) for
697 #[derive(Debug, Clone)]
698 struct Nodes <'a, N> where { N: 'a + NodeTrait }
699 item: N,
700 iter: Copied<Keys<'a, N, Vec<(N, CompactDirection)>>>,
701}
702
703#[derive(Debug, Clone)]
704pub struct Neighbors<'a, N, Ty = Undirected>
705where
706 N: 'a,
707 Ty: EdgeType,
708{
709 iter: Iter<'a, (N, CompactDirection)>,
710 ty: PhantomData<Ty>,
711}
712
713impl<N, Ty> Iterator for Neighbors<'_, N, Ty>
714where
715 N: NodeTrait,
716 Ty: EdgeType,
717{
718 type Item = N;
719 fn next(&mut self) -> Option<N> {
720 if Ty::is_directed() {
721 (&mut self.iter)
722 .filter_map(|&(n, dir)| if dir == Outgoing { Some(n) } else { None })
723 .next()
724 } else {
725 self.iter.next().map(|&(n, _)| n)
726 }
727 }
728 fn size_hint(&self) -> (usize, Option<usize>) {
729 let (lower, upper) = self.iter.size_hint();
730 if Ty::is_directed() {
731 (0, upper)
732 } else {
733 (lower, upper)
734 }
735 }
736}
737
738#[derive(Debug, Clone)]
739pub struct NeighborsDirected<'a, N, Ty>
740where
741 N: 'a,
742 Ty: EdgeType,
743{
744 iter: Iter<'a, (N, CompactDirection)>,
745 start_node: N,
746 dir: Direction,
747 ty: PhantomData<Ty>,
748}
749
750impl<N, Ty> Iterator for NeighborsDirected<'_, N, Ty>
751where
752 N: NodeTrait,
753 Ty: EdgeType,
754{
755 type Item = N;
756 fn next(&mut self) -> Option<N> {
757 if Ty::is_directed() {
758 let self_dir = self.dir;
759 let start_node = self.start_node;
760 (&mut self.iter)
761 .filter_map(move |&(n, dir)| {
762 if dir == self_dir || n == start_node {
763 Some(n)
764 } else {
765 None
766 }
767 })
768 .next()
769 } else {
770 self.iter.next().map(|&(n, _)| n)
771 }
772 }
773 fn size_hint(&self) -> (usize, Option<usize>) {
774 let (lower, upper) = self.iter.size_hint();
775 if Ty::is_directed() {
776 (0, upper)
777 } else {
778 (lower, upper)
779 }
780 }
781}
782
783#[derive(Debug, Clone)]
784pub struct Edges<
785 'a,
786 N,
787 E: 'a,
788 Ty,
789 #[cfg(not(feature = "std"))] S,
790 #[cfg(feature = "std")] S = RandomState,
791> where
792 N: 'a + NodeTrait,
793 Ty: EdgeType,
794 S: BuildHasher,
795{
796 from: N,
797 edges: &'a IndexMap<(N, N), E, S>,
798 iter: Neighbors<'a, N, Ty>,
799}
800
801impl<'a, N, E, Ty, S> Iterator for Edges<'a, N, E, Ty, S>
802where
803 N: 'a + NodeTrait,
804 E: 'a,
805 Ty: EdgeType,
806 S: BuildHasher,
807{
808 type Item = (N, N, &'a E);
809 fn next(&mut self) -> Option<Self::Item> {
810 self.iter.next().map(|b| {
811 let a = self.from;
812 match self.edges.get(&GraphMap::<N, E, Ty, S>::edge_key(a, b)) {
813 None => unreachable!(),
814 Some(edge) => (a, b, edge),
815 }
816 })
817 }
818 fn size_hint(&self) -> (usize, Option<usize>) {
819 self.iter.size_hint()
820 }
821}
822
823#[derive(Debug, Clone)]
824pub struct EdgesDirected<
825 'a,
826 N,
827 E: 'a,
828 Ty,
829 #[cfg(not(feature = "std"))] S,
830 #[cfg(feature = "std")] S = RandomState,
831> where
832 N: 'a + NodeTrait,
833 Ty: EdgeType,
834 S: BuildHasher,
835{
836 from: N,
837 dir: Direction,
838 edges: &'a IndexMap<(N, N), E, S>,
839 iter: NeighborsDirected<'a, N, Ty>,
840}
841
842impl<'a, N, E, Ty, S> Iterator for EdgesDirected<'a, N, E, Ty, S>
843where
844 N: 'a + NodeTrait,
845 E: 'a,
846 Ty: EdgeType,
847 S: BuildHasher,
848{
849 type Item = (N, N, &'a E);
850 fn next(&mut self) -> Option<Self::Item> {
851 self.iter.next().map(|mut b| {
852 let mut a = self.from;
853 if self.dir == Direction::Incoming {
854 mem::swap(&mut a, &mut b);
855 }
856 match self.edges.get(&GraphMap::<N, E, Ty, S>::edge_key(a, b)) {
857 None => unreachable!(),
858 Some(edge) => (a, b, edge),
859 }
860 })
861 }
862 fn size_hint(&self) -> (usize, Option<usize>) {
863 self.iter.size_hint()
864 }
865}
866
867#[derive(Debug, Clone)]
868pub struct AllEdges<'a, N, E: 'a, Ty>
869where
870 N: 'a + NodeTrait,
871{
872 inner: IndexMapIter<'a, (N, N), E>,
873 ty: PhantomData<Ty>,
874}
875
876impl<'a, N, E, Ty> Iterator for AllEdges<'a, N, E, Ty>
877where
878 N: 'a + NodeTrait,
879 E: 'a,
880 Ty: EdgeType,
881{
882 type Item = (N, N, &'a E);
883 fn next(&mut self) -> Option<Self::Item> {
884 self.inner.next().map(|(&(a, b), v)| (a, b, v))
885 }
886
887 fn size_hint(&self) -> (usize, Option<usize>) {
888 self.inner.size_hint()
889 }
890
891 fn count(self) -> usize {
892 self.inner.count()
893 }
894
895 fn nth(&mut self, n: usize) -> Option<Self::Item> {
896 self.inner
897 .nth(n)
898 .map(|(&(n1, n2), weight)| (n1, n2, weight))
899 }
900
901 fn last(self) -> Option<Self::Item> {
902 self.inner
903 .last()
904 .map(|(&(n1, n2), weight)| (n1, n2, weight))
905 }
906}
907
908impl<'a, N, E, Ty> DoubleEndedIterator for AllEdges<'a, N, E, Ty>
909where
910 N: 'a + NodeTrait,
911 E: 'a,
912 Ty: EdgeType,
913{
914 fn next_back(&mut self) -> Option<Self::Item> {
915 self.inner
916 .next_back()
917 .map(|(&(n1, n2), weight)| (n1, n2, weight))
918 }
919}
920
921pub struct AllEdgesMut<'a, N, E: 'a, Ty>
922where
923 N: 'a + NodeTrait,
924{
925 inner: IndexMapIterMut<'a, (N, N), E>, ty: PhantomData<Ty>,
927}
928
929impl<'a, N, E, Ty> Iterator for AllEdgesMut<'a, N, E, Ty>
930where
931 N: 'a + NodeTrait,
932 E: 'a,
933 Ty: EdgeType,
934{
935 type Item = (N, N, &'a mut E);
936 fn next(&mut self) -> Option<Self::Item> {
937 self.inner
938 .next()
939 .map(|(&(n1, n2), weight)| (n1, n2, weight))
940 }
941
942 fn size_hint(&self) -> (usize, Option<usize>) {
943 self.inner.size_hint()
944 }
945
946 fn count(self) -> usize {
947 self.inner.count()
948 }
949
950 fn nth(&mut self, n: usize) -> Option<Self::Item> {
951 self.inner
952 .nth(n)
953 .map(|(&(n1, n2), weight)| (n1, n2, weight))
954 }
955
956 fn last(self) -> Option<Self::Item> {
957 self.inner
958 .last()
959 .map(|(&(n1, n2), weight)| (n1, n2, weight))
960 }
961}
962
963impl<'a, N, E, Ty> DoubleEndedIterator for AllEdgesMut<'a, N, E, Ty>
964where
965 N: 'a + NodeTrait,
966 E: 'a,
967 Ty: EdgeType,
968{
969 fn next_back(&mut self) -> Option<Self::Item> {
970 self.inner
971 .next_back()
972 .map(|(&(n1, n2), weight)| (n1, n2, weight))
973 }
974}
975
976impl<N, E, Ty, S> Index<(N, N)> for GraphMap<N, E, Ty, S>
978where
979 N: NodeTrait,
980 Ty: EdgeType,
981 S: BuildHasher,
982{
983 type Output = E;
984 fn index(&self, index: (N, N)) -> &E {
985 let index = Self::edge_key(index.0, index.1);
986 self.edge_weight(index.0, index.1)
987 .expect("GraphMap::index: no such edge")
988 }
989}
990
991impl<N, E, Ty, S> IndexMut<(N, N)> for GraphMap<N, E, Ty, S>
993where
994 N: NodeTrait,
995 Ty: EdgeType,
996 S: BuildHasher,
997{
998 fn index_mut(&mut self, index: (N, N)) -> &mut E {
999 let index = Self::edge_key(index.0, index.1);
1000 self.edge_weight_mut(index.0, index.1)
1001 .expect("GraphMap::index: no such edge")
1002 }
1003}
1004
1005impl<N, E, Ty, S> Default for GraphMap<N, E, Ty, S>
1007where
1008 N: NodeTrait,
1009 Ty: EdgeType,
1010 S: BuildHasher + Default,
1011{
1012 fn default() -> Self {
1013 GraphMap::with_capacity(0, 0)
1014 }
1015}
1016
1017pub struct Ptr<'b, T: 'b>(pub &'b T);
1024
1025impl<T> Copy for Ptr<'_, T> {}
1026impl<T> Clone for Ptr<'_, T> {
1027 fn clone(&self) -> Self {
1028 *self
1029 }
1030}
1031
1032fn ptr_eq<T>(a: *const T, b: *const T) -> bool {
1033 a == b
1034}
1035
1036impl<'b, T> PartialEq for Ptr<'b, T> {
1037 fn eq(&self, other: &Ptr<'b, T>) -> bool {
1039 ptr_eq(self.0, other.0)
1040 }
1041}
1042
1043impl<'b, T> PartialOrd for Ptr<'b, T> {
1044 fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> {
1045 Some(self.cmp(other))
1046 }
1047}
1048
1049impl<'b, T> Ord for Ptr<'b, T> {
1050 fn cmp(&self, other: &Ptr<'b, T>) -> Ordering {
1052 let a: *const T = self.0;
1053 let b: *const T = other.0;
1054 a.cmp(&b)
1055 }
1056}
1057
1058impl<T> Deref for Ptr<'_, T> {
1059 type Target = T;
1060 fn deref(&self) -> &T {
1061 self.0
1062 }
1063}
1064
1065impl<T> Eq for Ptr<'_, T> {}
1066
1067impl<T> Hash for Ptr<'_, T> {
1068 fn hash<H: hash::Hasher>(&self, st: &mut H) {
1069 let ptr = (self.0) as *const T;
1070 ptr.hash(st)
1071 }
1072}
1073
1074impl<T: fmt::Debug> fmt::Debug for Ptr<'_, T> {
1075 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1076 self.0.fmt(f)
1077 }
1078}
1079
1080#[derive(Debug, Clone)]
1081pub struct NodeIdentifiers<'a, N, E: 'a, Ty>
1082where
1083 N: 'a + NodeTrait,
1084{
1085 iter: IndexMapIter<'a, N, Vec<(N, CompactDirection)>>,
1086 ty: PhantomData<Ty>,
1087 edge_ty: PhantomData<E>,
1088}
1089
1090impl<'a, N, E, Ty> Iterator for NodeIdentifiers<'a, N, E, Ty>
1091where
1092 N: 'a + NodeTrait,
1093 E: 'a,
1094 Ty: EdgeType,
1095{
1096 type Item = N;
1097 fn next(&mut self) -> Option<Self::Item> {
1098 self.iter.next().map(|(&n, _)| n)
1099 }
1100 fn size_hint(&self) -> (usize, Option<usize>) {
1101 self.iter.size_hint()
1102 }
1103}
1104
1105#[derive(Debug, Clone)]
1106pub struct NodeReferences<'a, N, E: 'a, Ty>
1107where
1108 N: 'a + NodeTrait,
1109{
1110 iter: IndexMapIter<'a, N, Vec<(N, CompactDirection)>>,
1111 ty: PhantomData<Ty>,
1112 edge_ty: PhantomData<E>,
1113}
1114
1115impl<'a, N, E, Ty> Iterator for NodeReferences<'a, N, E, Ty>
1116where
1117 N: 'a + NodeTrait,
1118 E: 'a,
1119 Ty: EdgeType,
1120{
1121 type Item = (N, &'a N);
1122 fn next(&mut self) -> Option<Self::Item> {
1123 self.iter.next().map(|(n, _)| (*n, n))
1124 }
1125 fn size_hint(&self) -> (usize, Option<usize>) {
1126 self.iter.size_hint()
1127 }
1128}
1129
1130impl<N, E, Ty, S> visit::GraphBase for GraphMap<N, E, Ty, S>
1131where
1132 N: Copy + PartialEq,
1133 S: BuildHasher,
1134{
1135 type NodeId = N;
1136 type EdgeId = (N, N);
1137}
1138
1139impl<N, E, Ty, S> visit::Data for GraphMap<N, E, Ty, S>
1140where
1141 N: Copy + PartialEq,
1142 Ty: EdgeType,
1143 S: BuildHasher,
1144{
1145 type NodeWeight = N;
1146 type EdgeWeight = E;
1147}
1148
1149impl<N, E, Ty, S> visit::Visitable for GraphMap<N, E, Ty, S>
1150where
1151 N: Copy + Ord + Hash,
1152 Ty: EdgeType,
1153 S: BuildHasher,
1154{
1155 type Map = HashSet<N>;
1156 fn visit_map(&self) -> HashSet<N> {
1157 HashSet::with_capacity(self.node_count())
1158 }
1159 fn reset_map(&self, map: &mut Self::Map) {
1160 map.clear();
1161 }
1162}
1163
1164impl<N, E, Ty, S> visit::GraphProp for GraphMap<N, E, Ty, S>
1165where
1166 N: NodeTrait,
1167 Ty: EdgeType,
1168 S: BuildHasher,
1169{
1170 type EdgeType = Ty;
1171}
1172
1173impl<'a, N, E, Ty, S> visit::IntoNodeReferences for &'a GraphMap<N, E, Ty, S>
1174where
1175 N: NodeTrait,
1176 Ty: EdgeType,
1177 S: BuildHasher,
1178{
1179 type NodeRef = (N, &'a N);
1180 type NodeReferences = NodeReferences<'a, N, E, Ty>;
1181 fn node_references(self) -> Self::NodeReferences {
1182 NodeReferences {
1183 iter: self.nodes.iter(),
1184 ty: self.ty,
1185 edge_ty: PhantomData,
1186 }
1187 }
1188}
1189
1190impl<'a, N, E: 'a, Ty, S> visit::IntoNodeIdentifiers for &'a GraphMap<N, E, Ty, S>
1191where
1192 N: NodeTrait,
1193 Ty: EdgeType,
1194 S: BuildHasher,
1195{
1196 type NodeIdentifiers = NodeIdentifiers<'a, N, E, Ty>;
1197
1198 fn node_identifiers(self) -> Self::NodeIdentifiers {
1199 NodeIdentifiers {
1200 iter: self.nodes.iter(),
1201 ty: self.ty,
1202 edge_ty: PhantomData,
1203 }
1204 }
1205}
1206
1207impl<N, E, Ty, S> visit::NodeCount for GraphMap<N, E, Ty, S>
1208where
1209 N: NodeTrait,
1210 Ty: EdgeType,
1211 S: BuildHasher,
1212{
1213 fn node_count(&self) -> usize {
1214 (*self).node_count()
1215 }
1216}
1217
1218impl<N, E, Ty, S> visit::NodeIndexable for GraphMap<N, E, Ty, S>
1219where
1220 N: NodeTrait,
1221 Ty: EdgeType,
1222 S: BuildHasher,
1223{
1224 fn node_bound(&self) -> usize {
1225 self.node_count()
1226 }
1227 fn to_index(&self, ix: Self::NodeId) -> usize {
1228 self.nodes.get_index_of(&ix).expect("node not found")
1229 }
1230 fn from_index(&self, ix: usize) -> Self::NodeId {
1231 assert!(
1232 ix < self.nodes.len(),
1233 "The requested index {} is out-of-bounds.",
1234 ix
1235 );
1236 let (&key, _) = self.nodes.get_index(ix).unwrap();
1237 key
1238 }
1239}
1240
1241impl<N, E, Ty, S> visit::NodeCompactIndexable for GraphMap<N, E, Ty, S>
1242where
1243 N: NodeTrait,
1244 Ty: EdgeType,
1245 S: BuildHasher,
1246{
1247}
1248
1249impl<'a, N: 'a, E, Ty, S> visit::IntoNeighbors for &'a GraphMap<N, E, Ty, S>
1250where
1251 N: Copy + Ord + Hash,
1252 Ty: EdgeType,
1253 S: BuildHasher,
1254{
1255 type Neighbors = Neighbors<'a, N, Ty>;
1256 fn neighbors(self, n: Self::NodeId) -> Self::Neighbors {
1257 self.neighbors(n)
1258 }
1259}
1260
1261impl<'a, N: 'a, E, Ty, S> visit::IntoNeighborsDirected for &'a GraphMap<N, E, Ty, S>
1262where
1263 N: Copy + Ord + Hash,
1264 Ty: EdgeType,
1265 S: BuildHasher,
1266{
1267 type NeighborsDirected = NeighborsDirected<'a, N, Ty>;
1268 fn neighbors_directed(self, n: N, dir: Direction) -> Self::NeighborsDirected {
1269 self.neighbors_directed(n, dir)
1270 }
1271}
1272
1273impl<N, E, Ty, S> visit::EdgeIndexable for GraphMap<N, E, Ty, S>
1274where
1275 N: NodeTrait,
1276 Ty: EdgeType,
1277 S: BuildHasher,
1278{
1279 fn edge_bound(&self) -> usize {
1280 self.edge_count()
1281 }
1282
1283 fn to_index(&self, ix: Self::EdgeId) -> usize {
1284 self.edges.get_index_of(&ix).expect("edge not found")
1285 }
1286
1287 fn from_index(&self, ix: usize) -> Self::EdgeId {
1288 assert!(
1289 ix < self.edges.len(),
1290 "The requested index {} is out-of-bounds.",
1291 ix
1292 );
1293 let (&key, _) = self.edges.get_index(ix).unwrap();
1294 key
1295 }
1296}
1297
1298impl<'a, N: 'a, E: 'a, Ty, S> visit::IntoEdges for &'a GraphMap<N, E, Ty, S>
1299where
1300 N: NodeTrait,
1301 Ty: EdgeType,
1302 S: BuildHasher,
1303{
1304 type Edges = Edges<'a, N, E, Ty, S>;
1305 fn edges(self, a: Self::NodeId) -> Self::Edges {
1306 self.edges(a)
1307 }
1308}
1309
1310impl<'a, N: 'a, E: 'a, Ty, S> visit::IntoEdgesDirected for &'a GraphMap<N, E, Ty, S>
1311where
1312 N: NodeTrait,
1313 Ty: EdgeType,
1314 S: BuildHasher,
1315{
1316 type EdgesDirected = EdgesDirected<'a, N, E, Ty, S>;
1317 fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::EdgesDirected {
1318 self.edges_directed(a, dir)
1319 }
1320}
1321
1322impl<'a, N: 'a, E: 'a, Ty, S> visit::IntoEdgeReferences for &'a GraphMap<N, E, Ty, S>
1323where
1324 N: NodeTrait,
1325 Ty: EdgeType,
1326 S: BuildHasher,
1327{
1328 type EdgeRef = (N, N, &'a E);
1329 type EdgeReferences = AllEdges<'a, N, E, Ty>;
1330 fn edge_references(self) -> Self::EdgeReferences {
1331 self.all_edges()
1332 }
1333}
1334
1335impl<N, E, Ty, S> visit::EdgeCount for GraphMap<N, E, Ty, S>
1336where
1337 N: NodeTrait,
1338 Ty: EdgeType,
1339 S: BuildHasher,
1340{
1341 #[inline]
1342 fn edge_count(&self) -> usize {
1343 self.edge_count()
1344 }
1345}
1346
1347impl<N, E, Ty, S> visit::GetAdjacencyMatrix for GraphMap<N, E, Ty, S>
1349where
1350 N: Copy + Ord + Hash,
1351 Ty: EdgeType,
1352 S: BuildHasher,
1353{
1354 type AdjMatrix = ();
1355 #[inline]
1356 fn adjacency_matrix(&self) {}
1357 #[inline]
1358 fn is_adjacent(&self, _: &(), a: N, b: N) -> bool {
1359 self.contains_edge(a, b)
1360 }
1361}
1362
1363#[cfg(feature = "rayon")]
1365pub struct ParNodes<'a, N>
1366where
1367 N: NodeTrait + Send + Sync,
1368{
1369 iter: ParKeys<'a, N, Vec<(N, CompactDirection)>>,
1370}
1371
1372#[cfg(feature = "rayon")]
1373impl<N> ParallelIterator for ParNodes<'_, N>
1374where
1375 N: NodeTrait + Send + Sync,
1376{
1377 type Item = N;
1378
1379 fn drive_unindexed<C>(self, consumer: C) -> C::Result
1380 where
1381 C: rayon::iter::plumbing::UnindexedConsumer<Self::Item>,
1382 {
1383 self.iter.copied().drive_unindexed(consumer)
1384 }
1385
1386 fn opt_len(&self) -> Option<usize> {
1387 self.iter.opt_len()
1388 }
1389}
1390
1391#[cfg(feature = "rayon")]
1392impl<N> IndexedParallelIterator for ParNodes<'_, N>
1393where
1394 N: NodeTrait + Send + Sync,
1395{
1396 fn drive<C>(self, consumer: C) -> C::Result
1397 where
1398 C: rayon::iter::plumbing::Consumer<Self::Item>,
1399 {
1400 self.iter.copied().drive(consumer)
1401 }
1402
1403 fn len(&self) -> usize {
1404 self.iter.len()
1405 }
1406
1407 fn with_producer<CB>(self, callback: CB) -> CB::Output
1408 where
1409 CB: rayon::iter::plumbing::ProducerCallback<Self::Item>,
1410 {
1411 self.iter.copied().with_producer(callback)
1412 }
1413}
1414
1415#[cfg(feature = "rayon")]
1417pub struct ParAllEdges<'a, N, E, Ty>
1418where
1419 N: NodeTrait + Send + Sync,
1420 E: Sync,
1421{
1422 inner: ParIter<'a, (N, N), E>,
1423 ty: PhantomData<fn(Ty)>,
1424}
1425
1426#[cfg(feature = "rayon")]
1427impl<'a, N, E, Ty> ParallelIterator for ParAllEdges<'a, N, E, Ty>
1428where
1429 N: NodeTrait + Send + Sync,
1430 E: Sync,
1431{
1432 type Item = (N, N, &'a E);
1433
1434 fn drive_unindexed<C>(self, c: C) -> C::Result
1435 where
1436 C: rayon::iter::plumbing::UnindexedConsumer<Self::Item>,
1437 {
1438 self.inner.map(|(&(a, b), v)| (a, b, v)).drive_unindexed(c)
1439 }
1440
1441 fn opt_len(&self) -> Option<usize> {
1442 self.inner.opt_len()
1443 }
1444}
1445
1446#[cfg(feature = "rayon")]
1447impl<N, E, Ty> IndexedParallelIterator for ParAllEdges<'_, N, E, Ty>
1448where
1449 N: NodeTrait + Send + Sync,
1450 E: Sync,
1451{
1452 fn drive<C>(self, consumer: C) -> C::Result
1453 where
1454 C: rayon::iter::plumbing::Consumer<Self::Item>,
1455 {
1456 self.inner.map(|(&(a, b), v)| (a, b, v)).drive(consumer)
1457 }
1458
1459 fn len(&self) -> usize {
1460 self.inner.len()
1461 }
1462
1463 fn with_producer<CB>(self, callback: CB) -> CB::Output
1464 where
1465 CB: rayon::iter::plumbing::ProducerCallback<Self::Item>,
1466 {
1467 self.inner
1468 .map(|(&(a, b), v)| (a, b, v))
1469 .with_producer(callback)
1470 }
1471}
1472
1473#[cfg(feature = "rayon")]
1475pub struct ParAllEdgesMut<'a, N, E: 'a, Ty>
1476where
1477 N: NodeTrait + Send + Sync,
1478 E: Send,
1479{
1480 inner: ParIterMut<'a, (N, N), E>,
1481 ty: PhantomData<fn(Ty)>,
1482}
1483
1484#[cfg(feature = "rayon")]
1485impl<'a, N, E, Ty> ParallelIterator for ParAllEdgesMut<'a, N, E, Ty>
1486where
1487 N: NodeTrait + Send + Sync,
1488 E: Send,
1489{
1490 type Item = (N, N, &'a mut E);
1491
1492 fn drive_unindexed<C>(self, c: C) -> C::Result
1493 where
1494 C: rayon::iter::plumbing::UnindexedConsumer<Self::Item>,
1495 {
1496 self.inner.map(|(&(a, b), v)| (a, b, v)).drive_unindexed(c)
1497 }
1498
1499 fn opt_len(&self) -> Option<usize> {
1500 self.inner.opt_len()
1501 }
1502}
1503
1504#[cfg(feature = "rayon")]
1505impl<N, E, Ty> IndexedParallelIterator for ParAllEdgesMut<'_, N, E, Ty>
1506where
1507 N: NodeTrait + Send + Sync,
1508 E: Send,
1509{
1510 fn drive<C>(self, consumer: C) -> C::Result
1511 where
1512 C: rayon::iter::plumbing::Consumer<Self::Item>,
1513 {
1514 self.inner.map(|(&(a, b), v)| (a, b, v)).drive(consumer)
1515 }
1516
1517 fn len(&self) -> usize {
1518 self.inner.len()
1519 }
1520
1521 fn with_producer<CB>(self, callback: CB) -> CB::Output
1522 where
1523 CB: rayon::iter::plumbing::ProducerCallback<Self::Item>,
1524 {
1525 self.inner
1526 .map(|(&(a, b), v)| (a, b, v))
1527 .with_producer(callback)
1528 }
1529}