1use petgraph::{
2 graph::IndexType,
3 visit::{NodeCompactIndexable, NodeCount},
4};
5
6use super::*;
7use ndarray;
8
9impl<N, E, Ix, S> IntoNodeIdentifiers for &SquareGraph<N, E, Ix, S>
10where
11 Ix: IndexType,
12 Range<Ix>: Iterator<Item = Ix>,
13{
14 type NodeIdentifiers = NodeIndices<Ix>;
15
16 fn node_identifiers(self) -> Self::NodeIdentifiers {
17 NodeIndices::new(self.horizontal_node_count(), self.vertical_node_count())
18 }
19}
20
21#[derive(Clone, Debug)]
23pub struct NodeIndices<Ix> {
24 pub(crate) h_max: usize,
25 h: usize,
26 pub(crate) v_max: usize,
27 v: usize,
28 pd: PhantomData<Ix>,
29}
30
31impl<Ix> NodeIndices<Ix> {
32 pub(crate) fn new(h: usize, v: usize) -> Self {
33 Self {
34 h_max: h,
35 h: 0,
36 v_max: v,
37 v: 0,
38 pd: PhantomData,
39 }
40 }
41}
42
43impl<Ix: IndexType> Iterator for NodeIndices<Ix> {
44 type Item = NodeIndex<Ix>;
45
46 fn next(&mut self) -> Option<Self::Item> {
47 let nv: usize;
48 if self.v < self.v_max {
49 nv = self.v;
50 self.v += 1;
51 } else if self.h + 1 < self.h_max {
52 nv = 0;
53 self.v = 1;
54 self.h += 1;
55 } else {
56 return None;
57 }
58 Some(NodeIndex::new(Ix::new(self.h), Ix::new(nv)))
59 }
60
61 fn size_hint(&self) -> (usize, Option<usize>) {
62 let len = self.v_max * (self.h_max - self.h) - self.v;
63 (len, Some(len))
64 }
65}
66
67impl<Ix: IndexType> FusedIterator for NodeIndices<Ix> {}
68impl<Ix: IndexType> ExactSizeIterator for NodeIndices<Ix> {}
69
70impl<'a, N: Clone, E, Ix, S> IntoNodeReferences for &'a SquareGraph<N, E, Ix, S>
71where
72 Ix: IndexType,
73 Range<Ix>: Iterator<Item = Ix>,
74{
75 type NodeRef = (NodeIndex<Ix>, &'a N);
76 type NodeReferences = NodeReferences<'a, N, Ix>;
77
78 fn node_references(self) -> Self::NodeReferences {
79 NodeReferences {
80 indices: self.node_identifiers(),
81 nodes: self.nodes.iter(),
82 }
83 }
84}
85
86#[derive(Clone)]
88pub struct NodeReferences<'a, N, Ix> {
89 indices: NodeIndices<Ix>,
90 nodes: ndarray::iter::Iter<'a, N, ndarray::Dim<[usize; 2]>>,
91}
92
93impl<'a, N, Ix> Iterator for NodeReferences<'a, N, Ix>
94where
95 Ix: IndexType,
96 Range<Ix>: Iterator<Item = Ix>,
97{
98 type Item = (NodeIndex<Ix>, &'a N);
99
100 fn next(&mut self) -> Option<Self::Item> {
101 let n = self.nodes.next()?;
102 Some((self.indices.next()?, n))
103 }
104
105 fn size_hint(&self) -> (usize, Option<usize>) {
106 self.nodes.size_hint()
107 }
108
109 fn count(self) -> usize
110 where
111 Self: Sized,
112 {
113 self.nodes.count()
114 }
115}
116
117impl<'a, N, Ix> FusedIterator for NodeReferences<'a, N, Ix>
118where
119 Ix: IndexType,
120 Range<Ix>: Iterator<Item = Ix>,
121{
122}
123
124impl<'a, N, Ix> ExactSizeIterator for NodeReferences<'a, N, Ix>
125where
126 Ix: IndexType,
127 Range<Ix>: Iterator<Item = Ix>,
128{
129}
130
131impl<N, E, Ix, S> NodeCompactIndexable for SquareGraph<N, E, Ix, S> where Ix: IndexType {}
132
133impl<N, E, Ix, S> NodeCount for SquareGraph<N, E, Ix, S>
134where
135 Ix: IndexType,
136{
137 fn node_count(&self) -> usize {
138 self.nodes.len()
139 }
140}
141
142impl<N, E, Ix, S> NodeIndexable for SquareGraph<N, E, Ix, S>
143where
144 Ix: IndexType,
145{
146 fn node_bound(&self) -> usize {
147 self.nodes.len()
148 }
149
150 fn to_index(&self, a: Self::NodeId) -> usize {
151 a.horizontal.index() * self.vertical_node_count() + a.vertical.index()
152 }
153
154 fn from_index(&self, i: usize) -> Self::NodeId {
155 let h = self.vertical_node_count();
156 (i / h, i % h).into()
157 }
158}