1use indexmap::map::Keys;
5use indexmap::map::{Iter as IndexMapIter, IterMut as IndexMapIterMut};
6use indexmap::IndexMap;
7use std::cmp::Ordering;
8use std::fmt;
9use std::hash::{self, Hash};
10use std::iter::FromIterator;
11use std::iter::{Cloned, DoubleEndedIterator};
12use std::marker::PhantomData;
13use std::ops::{Deref, Index, IndexMut};
14use std::slice::Iter;
15
16use crate::{Directed, Direction, EdgeType, Incoming, Outgoing, Undirected};
17
18use crate::graph::node_index;
19use crate::graph::Graph;
20use crate::visit::{IntoEdgeReferences, IntoEdges, NodeCompactIndexable};
21use crate::visit::{IntoNodeIdentifiers, IntoNodeReferences, NodeCount, NodeIndexable};
22use crate::IntoWeightedEdge;
23
24pub type UnGraphMap<N, E> = GraphMap<N, E, Undirected>;
29pub type DiGraphMap<N, E> = GraphMap<N, E, Directed>;
34
35#[derive(Clone)]
60pub struct GraphMap<N, E, Ty> {
61 nodes: IndexMap<N, Vec<(N, CompactDirection)>>,
62 edges: IndexMap<(N, N), E>,
63 ty: PhantomData<Ty>,
64}
65
66impl<N: Eq + Hash + fmt::Debug, E: fmt::Debug, Ty: EdgeType> fmt::Debug for GraphMap<N, E, Ty> {
67 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
68 self.nodes.fmt(f)
69 }
70}
71
72pub trait NodeTrait: Copy + Ord + Hash {}
74impl<N> NodeTrait for N where N: Copy + Ord + Hash {}
75
76#[derive(Copy, Clone, Debug, PartialEq)]
78enum CompactDirection {
79 Outgoing,
80 Incoming,
81}
82
83impl From<Direction> for CompactDirection {
84 fn from(d: Direction) -> Self {
85 match d {
86 Outgoing => CompactDirection::Outgoing,
87 Incoming => CompactDirection::Incoming,
88 }
89 }
90}
91
92impl PartialEq<Direction> for CompactDirection {
93 fn eq(&self, rhs: &Direction) -> bool {
94 (*self as usize) == (*rhs as usize)
95 }
96}
97
98impl<N, E, Ty> GraphMap<N, E, Ty>
99where
100 N: NodeTrait,
101 Ty: EdgeType,
102{
103 pub fn new() -> Self {
105 Self::default()
106 }
107
108 pub fn with_capacity(nodes: usize, edges: usize) -> Self {
110 GraphMap {
111 nodes: IndexMap::with_capacity(nodes),
112 edges: IndexMap::with_capacity(edges),
113 ty: PhantomData,
114 }
115 }
116
117 pub fn capacity(&self) -> (usize, usize) {
119 (self.nodes.capacity(), self.edges.capacity())
120 }
121
122 #[inline]
124 fn edge_key(a: N, b: N) -> (N, N) {
125 if Ty::is_directed() || a <= b {
126 (a, b)
127 } else {
128 (b, a)
129 }
130 }
131
132 pub fn is_directed(&self) -> bool {
134 Ty::is_directed()
135 }
136
137 pub fn from_edges<I>(iterable: I) -> Self
157 where
158 I: IntoIterator,
159 I::Item: IntoWeightedEdge<E, NodeId = N>,
160 {
161 Self::from_iter(iterable)
162 }
163
164 pub fn node_count(&self) -> usize {
166 self.nodes.len()
167 }
168
169 pub fn edge_count(&self) -> usize {
171 self.edges.len()
172 }
173
174 pub fn clear(&mut self) {
176 self.nodes.clear();
177 self.edges.clear();
178 }
179
180 pub fn add_node(&mut self, n: N) -> N {
182 self.nodes.entry(n).or_insert(Vec::new());
183 n
184 }
185
186 pub fn remove_node(&mut self, n: N) -> bool {
190 let links = match self.nodes.swap_remove(&n) {
191 None => return false,
192 Some(sus) => sus,
193 };
194 for (succ, _) in links {
195 self.remove_single_edge(&succ, &n, Incoming);
197 self.edges.swap_remove(&Self::edge_key(n, succ));
199 }
200 true
201 }
202
203 pub fn contains_node(&self, n: N) -> bool {
205 self.nodes.contains_key(&n)
206 }
207
208 pub fn add_edge(&mut self, a: N, b: N, weight: E) -> Option<E> {
230 if let old @ Some(_) = self.edges.insert(Self::edge_key(a, b), weight) {
231 old
232 } else {
233 self.nodes
235 .entry(a)
236 .or_insert_with(|| Vec::with_capacity(1))
237 .push((b, CompactDirection::Outgoing));
238 if a != b {
239 self.nodes
241 .entry(b)
242 .or_insert_with(|| Vec::with_capacity(1))
243 .push((a, CompactDirection::Incoming));
244 }
245 None
246 }
247 }
248
249 fn remove_single_edge(&mut self, a: &N, b: &N, dir: Direction) -> bool {
253 match self.nodes.get_mut(a) {
254 None => false,
255 Some(sus) => {
256 if Ty::is_directed() {
257 match sus
258 .iter()
259 .position(|elt| elt == &(*b, CompactDirection::from(dir)))
260 {
261 Some(index) => {
262 sus.swap_remove(index);
263 true
264 }
265 None => false,
266 }
267 } else {
268 match sus.iter().position(|elt| &elt.0 == b) {
269 Some(index) => {
270 sus.swap_remove(index);
271 true
272 }
273 None => false,
274 }
275 }
276 }
277 }
278 }
279
280 pub fn remove_edge(&mut self, a: N, b: N) -> Option<E> {
296 let exist1 = self.remove_single_edge(&a, &b, Outgoing);
297 let exist2 = if a != b {
298 self.remove_single_edge(&b, &a, Incoming)
299 } else {
300 exist1
301 };
302 let weight = self.edges.remove(&Self::edge_key(a, b));
303 debug_assert!(exist1 == exist2 && exist1 == weight.is_some());
304 weight
305 }
306
307 pub fn contains_edge(&self, a: N, b: N) -> bool {
309 self.edges.contains_key(&Self::edge_key(a, b))
310 }
311
312 pub fn nodes(&self) -> Nodes<N> {
316 Nodes {
317 iter: self.nodes.keys().cloned(),
318 }
319 }
320
321 pub fn neighbors(&self, a: N) -> Neighbors<N, Ty> {
329 Neighbors {
330 iter: match self.nodes.get(&a) {
331 Some(neigh) => neigh.iter(),
332 None => [].iter(),
333 },
334 ty: self.ty,
335 }
336 }
337
338 pub fn neighbors_directed(&self, a: N, dir: Direction) -> NeighborsDirected<N, Ty> {
349 NeighborsDirected {
350 iter: match self.nodes.get(&a) {
351 Some(neigh) => neigh.iter(),
352 None => [].iter(),
353 },
354 start_node: a,
355 dir,
356 ty: self.ty,
357 }
358 }
359
360 pub fn edges(&self, from: N) -> Edges<N, E, Ty> {
369 Edges {
370 from,
371 iter: self.neighbors(from),
372 edges: &self.edges,
373 }
374 }
375
376 pub fn edge_weight(&self, a: N, b: N) -> Option<&E> {
379 self.edges.get(&Self::edge_key(a, b))
380 }
381
382 pub fn edge_weight_mut(&mut self, a: N, b: N) -> Option<&mut E> {
385 self.edges.get_mut(&Self::edge_key(a, b))
386 }
387
388 pub fn all_edges(&self) -> AllEdges<N, E, Ty> {
392 AllEdges {
393 inner: self.edges.iter(),
394 ty: self.ty,
395 }
396 }
397
398 pub fn all_edges_mut(&mut self) -> AllEdgesMut<N, E, Ty> {
403 AllEdgesMut {
404 inner: self.edges.iter_mut(),
405 ty: self.ty,
406 }
407 }
408
409 pub fn into_graph<Ix>(self) -> Graph<N, E, Ty, Ix>
421 where
422 Ix: crate::graph::IndexType,
423 {
424 let mut gr = Graph::with_capacity(self.node_count(), self.edge_count());
426 for (&node, _) in &self.nodes {
427 gr.add_node(node);
428 }
429 for ((a, b), edge_weight) in self.edges {
430 let (ai, _, _) = self.nodes.get_full(&a).unwrap();
431 let (bi, _, _) = self.nodes.get_full(&b).unwrap();
432 gr.add_edge(node_index(ai), node_index(bi), edge_weight);
433 }
434 gr
435 }
436}
437
438impl<N, E, Ty, Item> FromIterator<Item> for GraphMap<N, E, Ty>
440where
441 Item: IntoWeightedEdge<E, NodeId = N>,
442 N: NodeTrait,
443 Ty: EdgeType,
444{
445 fn from_iter<I>(iterable: I) -> Self
446 where
447 I: IntoIterator<Item = Item>,
448 {
449 let iter = iterable.into_iter();
450 let (low, _) = iter.size_hint();
451 let mut g = Self::with_capacity(0, low);
452 g.extend(iter);
453 g
454 }
455}
456
457impl<N, E, Ty, Item> Extend<Item> for GraphMap<N, E, Ty>
461where
462 Item: IntoWeightedEdge<E, NodeId = N>,
463 N: NodeTrait,
464 Ty: EdgeType,
465{
466 fn extend<I>(&mut self, iterable: I)
467 where
468 I: IntoIterator<Item = Item>,
469 {
470 let iter = iterable.into_iter();
471 let (low, _) = iter.size_hint();
472 self.edges.reserve(low);
473
474 for elt in iter {
475 let (source, target, weight) = elt.into_weighted_edge();
476 self.add_edge(source, target, weight);
477 }
478 }
479}
480
481iterator_wrap! {
482 impl (Iterator DoubleEndedIterator ExactSizeIterator) for
483 struct Nodes <'a, N> where { N: 'a + NodeTrait }
484 item: N,
485 iter: Cloned<Keys<'a, N, Vec<(N, CompactDirection)>>>,
486}
487
488pub struct Neighbors<'a, N, Ty = Undirected>
489where
490 N: 'a,
491 Ty: EdgeType,
492{
493 iter: Iter<'a, (N, CompactDirection)>,
494 ty: PhantomData<Ty>,
495}
496
497impl<'a, N, Ty> Iterator for Neighbors<'a, N, Ty>
498where
499 N: NodeTrait,
500 Ty: EdgeType,
501{
502 type Item = N;
503 fn next(&mut self) -> Option<N> {
504 if Ty::is_directed() {
505 (&mut self.iter)
506 .filter_map(|&(n, dir)| if dir == Outgoing { Some(n) } else { None })
507 .next()
508 } else {
509 self.iter.next().map(|&(n, _)| n)
510 }
511 }
512}
513
514pub struct NeighborsDirected<'a, N, Ty>
515where
516 N: 'a,
517 Ty: EdgeType,
518{
519 iter: Iter<'a, (N, CompactDirection)>,
520 start_node: N,
521 dir: Direction,
522 ty: PhantomData<Ty>,
523}
524
525impl<'a, N, Ty> Iterator for NeighborsDirected<'a, N, Ty>
526where
527 N: NodeTrait,
528 Ty: EdgeType,
529{
530 type Item = N;
531 fn next(&mut self) -> Option<N> {
532 if Ty::is_directed() {
533 let self_dir = self.dir;
534 let start_node = self.start_node;
535 (&mut self.iter)
536 .filter_map(move |&(n, dir)| {
537 if dir == self_dir || n == start_node {
538 Some(n)
539 } else {
540 None
541 }
542 })
543 .next()
544 } else {
545 self.iter.next().map(|&(n, _)| n)
546 }
547 }
548}
549
550pub struct Edges<'a, N, E: 'a, Ty>
551where
552 N: 'a + NodeTrait,
553 Ty: EdgeType,
554{
555 from: N,
556 edges: &'a IndexMap<(N, N), E>,
557 iter: Neighbors<'a, N, Ty>,
558}
559
560impl<'a, N, E, Ty> Iterator for Edges<'a, N, E, Ty>
561where
562 N: 'a + NodeTrait,
563 E: 'a,
564 Ty: EdgeType,
565{
566 type Item = (N, N, &'a E);
567 fn next(&mut self) -> Option<Self::Item> {
568 match self.iter.next() {
569 None => None,
570 Some(b) => {
571 let a = self.from;
572 match self.edges.get(&GraphMap::<N, E, Ty>::edge_key(a, b)) {
573 None => unreachable!(),
574 Some(edge) => Some((a, b, edge)),
575 }
576 }
577 }
578 }
579}
580
581impl<'a, N: 'a, E: 'a, Ty> IntoEdgeReferences for &'a GraphMap<N, E, Ty>
582where
583 N: NodeTrait,
584 Ty: EdgeType,
585{
586 type EdgeRef = (N, N, &'a E);
587 type EdgeReferences = AllEdges<'a, N, E, Ty>;
588 fn edge_references(self) -> Self::EdgeReferences {
589 self.all_edges()
590 }
591}
592
593pub struct AllEdges<'a, N, E: 'a, Ty>
594where
595 N: 'a + NodeTrait,
596{
597 inner: IndexMapIter<'a, (N, N), E>,
598 ty: PhantomData<Ty>,
599}
600
601impl<'a, N, E, Ty> Iterator for AllEdges<'a, N, E, Ty>
602where
603 N: 'a + NodeTrait,
604 E: 'a,
605 Ty: EdgeType,
606{
607 type Item = (N, N, &'a E);
608 fn next(&mut self) -> Option<Self::Item> {
609 match self.inner.next() {
610 None => None,
611 Some((&(a, b), v)) => Some((a, b, v)),
612 }
613 }
614
615 fn size_hint(&self) -> (usize, Option<usize>) {
616 self.inner.size_hint()
617 }
618
619 fn count(self) -> usize {
620 self.inner.count()
621 }
622
623 fn nth(&mut self, n: usize) -> Option<Self::Item> {
624 self.inner
625 .nth(n)
626 .map(|(&(n1, n2), weight)| (n1, n2, weight))
627 }
628
629 fn last(self) -> Option<Self::Item> {
630 self.inner
631 .last()
632 .map(|(&(n1, n2), weight)| (n1, n2, weight))
633 }
634}
635
636impl<'a, N, E, Ty> DoubleEndedIterator for AllEdges<'a, N, E, Ty>
637where
638 N: 'a + NodeTrait,
639 E: 'a,
640 Ty: EdgeType,
641{
642 fn next_back(&mut self) -> Option<Self::Item> {
643 self.inner
644 .next_back()
645 .map(|(&(n1, n2), weight)| (n1, n2, weight))
646 }
647}
648
649pub struct AllEdgesMut<'a, N, E: 'a, Ty>
650where
651 N: 'a + NodeTrait,
652{
653 inner: IndexMapIterMut<'a, (N, N), E>,
654 ty: PhantomData<Ty>,
655}
656
657impl<'a, N, E, Ty> Iterator for AllEdgesMut<'a, N, E, Ty>
658where
659 N: 'a + NodeTrait,
660 E: 'a,
661 Ty: EdgeType,
662{
663 type Item = (N, N, &'a mut E);
664 fn next(&mut self) -> Option<Self::Item> {
665 self.inner
666 .next()
667 .map(|(&(n1, n2), weight)| (n1, n2, weight))
668 }
669
670 fn size_hint(&self) -> (usize, Option<usize>) {
671 self.inner.size_hint()
672 }
673
674 fn count(self) -> usize {
675 self.inner.count()
676 }
677
678 fn nth(&mut self, n: usize) -> Option<Self::Item> {
679 self.inner
680 .nth(n)
681 .map(|(&(n1, n2), weight)| (n1, n2, weight))
682 }
683
684 fn last(self) -> Option<Self::Item> {
685 self.inner
686 .last()
687 .map(|(&(n1, n2), weight)| (n1, n2, weight))
688 }
689}
690
691impl<'a, N, E, Ty> DoubleEndedIterator for AllEdgesMut<'a, N, E, Ty>
692where
693 N: 'a + NodeTrait,
694 E: 'a,
695 Ty: EdgeType,
696{
697 fn next_back(&mut self) -> Option<Self::Item> {
698 self.inner
699 .next_back()
700 .map(|(&(n1, n2), weight)| (n1, n2, weight))
701 }
702}
703
704impl<'a, N: 'a, E: 'a, Ty> IntoEdges for &'a GraphMap<N, E, Ty>
705where
706 N: NodeTrait,
707 Ty: EdgeType,
708{
709 type Edges = Edges<'a, N, E, Ty>;
710 fn edges(self, a: Self::NodeId) -> Self::Edges {
711 self.edges(a)
712 }
713}
714
715impl<N, E, Ty> Index<(N, N)> for GraphMap<N, E, Ty>
717where
718 N: NodeTrait,
719 Ty: EdgeType,
720{
721 type Output = E;
722 fn index(&self, index: (N, N)) -> &E {
723 let index = Self::edge_key(index.0, index.1);
724 self.edge_weight(index.0, index.1)
725 .expect("GraphMap::index: no such edge")
726 }
727}
728
729impl<N, E, Ty> IndexMut<(N, N)> for GraphMap<N, E, Ty>
731where
732 N: NodeTrait,
733 Ty: EdgeType,
734{
735 fn index_mut(&mut self, index: (N, N)) -> &mut E {
736 let index = Self::edge_key(index.0, index.1);
737 self.edge_weight_mut(index.0, index.1)
738 .expect("GraphMap::index: no such edge")
739 }
740}
741
742impl<N, E, Ty> Default for GraphMap<N, E, Ty>
744where
745 N: NodeTrait,
746 Ty: EdgeType,
747{
748 fn default() -> Self {
749 GraphMap::with_capacity(0, 0)
750 }
751}
752
753pub struct Ptr<'b, T: 'b>(pub &'b T);
760
761impl<'b, T> Copy for Ptr<'b, T> {}
762impl<'b, T> Clone for Ptr<'b, T> {
763 fn clone(&self) -> Self {
764 *self
765 }
766}
767
768fn ptr_eq<T>(a: *const T, b: *const T) -> bool {
769 a == b
770}
771
772impl<'b, T> PartialEq for Ptr<'b, T> {
773 fn eq(&self, other: &Ptr<'b, T>) -> bool {
775 ptr_eq(self.0, other.0)
776 }
777}
778
779impl<'b, T> PartialOrd for Ptr<'b, T> {
780 fn partial_cmp(&self, other: &Ptr<'b, T>) -> Option<Ordering> {
781 Some(self.cmp(other))
782 }
783}
784
785impl<'b, T> Ord for Ptr<'b, T> {
786 fn cmp(&self, other: &Ptr<'b, T>) -> Ordering {
788 let a: *const T = self.0;
789 let b: *const T = other.0;
790 a.cmp(&b)
791 }
792}
793
794impl<'b, T> Deref for Ptr<'b, T> {
795 type Target = T;
796 fn deref(&self) -> &T {
797 self.0
798 }
799}
800
801impl<'b, T> Eq for Ptr<'b, T> {}
802
803impl<'b, T> Hash for Ptr<'b, T> {
804 fn hash<H: hash::Hasher>(&self, st: &mut H) {
805 let ptr = (self.0) as *const T;
806 ptr.hash(st)
807 }
808}
809
810impl<'b, T: fmt::Debug> fmt::Debug for Ptr<'b, T> {
811 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
812 self.0.fmt(f)
813 }
814}
815
816impl<'a, N, E: 'a, Ty> IntoNodeIdentifiers for &'a GraphMap<N, E, Ty>
817where
818 N: NodeTrait,
819 Ty: EdgeType,
820{
821 type NodeIdentifiers = NodeIdentifiers<'a, N, E, Ty>;
822
823 fn node_identifiers(self) -> Self::NodeIdentifiers {
824 NodeIdentifiers {
825 iter: self.nodes.iter(),
826 ty: self.ty,
827 edge_ty: PhantomData,
828 }
829 }
830}
831
832impl<N, E, Ty> NodeCount for GraphMap<N, E, Ty>
833where
834 N: NodeTrait,
835 Ty: EdgeType,
836{
837 fn node_count(&self) -> usize {
838 (*self).node_count()
839 }
840}
841
842pub struct NodeIdentifiers<'a, N, E: 'a, Ty>
843where
844 N: 'a + NodeTrait,
845{
846 iter: IndexMapIter<'a, N, Vec<(N, CompactDirection)>>,
847 ty: PhantomData<Ty>,
848 edge_ty: PhantomData<E>,
849}
850
851impl<'a, N, E, Ty> Iterator for NodeIdentifiers<'a, N, E, Ty>
852where
853 N: 'a + NodeTrait,
854 E: 'a,
855 Ty: EdgeType,
856{
857 type Item = N;
858 fn next(&mut self) -> Option<Self::Item> {
859 self.iter.next().map(|(&n, _)| n)
860 }
861}
862
863impl<'a, N, E, Ty> IntoNodeReferences for &'a GraphMap<N, E, Ty>
864where
865 N: NodeTrait,
866 Ty: EdgeType,
867{
868 type NodeRef = (N, &'a N);
869 type NodeReferences = NodeReferences<'a, N, E, Ty>;
870 fn node_references(self) -> Self::NodeReferences {
871 NodeReferences {
872 iter: self.nodes.iter(),
873 ty: self.ty,
874 edge_ty: PhantomData,
875 }
876 }
877}
878
879pub struct NodeReferences<'a, N, E: 'a, Ty>
880where
881 N: 'a + NodeTrait,
882{
883 iter: IndexMapIter<'a, N, Vec<(N, CompactDirection)>>,
884 ty: PhantomData<Ty>,
885 edge_ty: PhantomData<E>,
886}
887
888impl<'a, N, E, Ty> Iterator for NodeReferences<'a, N, E, Ty>
889where
890 N: 'a + NodeTrait,
891 E: 'a,
892 Ty: EdgeType,
893{
894 type Item = (N, &'a N);
895 fn next(&mut self) -> Option<Self::Item> {
896 self.iter.next().map(|(n, _)| (*n, n))
897 }
898}
899
900impl<N, E, Ty> NodeIndexable for GraphMap<N, E, Ty>
901where
902 N: NodeTrait,
903 Ty: EdgeType,
904{
905 fn node_bound(&self) -> usize {
906 self.node_count()
907 }
908 fn to_index(&self, ix: Self::NodeId) -> usize {
909 let (i, _, _) = self.nodes.get_full(&ix).unwrap();
910 i
911 }
912 fn from_index(&self, ix: usize) -> Self::NodeId {
913 let (&key, _) = self.nodes.get_index(ix).unwrap();
914 key
915 }
916}
917
918impl<N, E, Ty> NodeCompactIndexable for GraphMap<N, E, Ty>
919where
920 N: NodeTrait,
921 Ty: EdgeType,
922{
923}