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