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