1use choose::Choose;
6use graphs::common::OutNeighborFromOutEdge;
7use prelude::*;
8use props::{VecEdgeProp, VecVertexProp};
9
10use fera_fun::vec;
11use fera_optional::OptionalMax;
12
13use std::cmp::Ordering;
14use std::fmt::Debug;
15use std::hash::{Hash, Hasher};
16use std::iter::{Cloned, Map};
17use std::marker::PhantomData;
18use std::ops::Range;
19use std::slice::Iter;
20
21use num_traits::Bounded;
22use rand::Rng;
23
24pub type StaticDigraph = Static<u32, (Directed, usize)>;
25
26pub type StaticGraph = Static<u32, (Undirected, usize)>;
27
28pub trait StaticEdgeKind: 'static {
31 type Kind: UniformEdgeKind; type Edge: 'static + GraphItem + Bounded + EdgeImpl;
33}
34
35#[doc(hidden)]
36pub trait EdgeImpl: Sized {
37 fn new(e: usize) -> Self;
38 fn new_checked(e: usize) -> Option<Self>;
39 fn source<T>(self, ends: &[T]) -> &T;
40 fn target<T>(self, ends: &[T]) -> &T;
41 fn to_index(self) -> usize;
42 fn reverse(self) -> Self;
43}
44
45#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
48pub struct StaticDirectedEdge<N: Num>(N);
49
50impl<E: Num> StaticEdgeKind for (Directed, E) {
51 type Kind = Directed;
52 type Edge = StaticDirectedEdge<E>;
53}
54
55impl<N: Num> Bounded for StaticDirectedEdge<N> {
56 fn max_value() -> Self {
57 StaticDirectedEdge(N::max_value())
58 }
59
60 fn min_value() -> Self {
61 StaticDirectedEdge(N::min_value())
62 }
63}
64
65impl<N: Num> EdgeImpl for StaticDirectedEdge<N> {
66 fn new(e: usize) -> Self {
67 StaticDirectedEdge(N::from_usize(e))
68 }
69
70 fn new_checked(e: usize) -> Option<Self> {
71 if N::is_valid(e) {
72 Some(Self::new(e))
73 } else {
74 None
75 }
76 }
77
78 fn source<T>(self, ends: &[T]) -> &T {
79 &ends[2 * N::to_usize(self.0)]
80 }
81
82 fn target<T>(self, ends: &[T]) -> &T {
83 &ends[2 * N::to_usize(self.0) + 1]
84 }
85
86 fn to_index(self) -> usize {
87 N::to_usize(self.0)
88 }
89
90 fn reverse(self) -> Self {
91 panic!("StaticDirectedEdge::reverse should not be called")
92 }
93}
94
95#[derive(Copy, Clone, Debug, Eq)]
98pub struct StaticUndirectedEdge<N: Num>(N);
99
100impl<E: Num> StaticEdgeKind for (Undirected, E) {
101 type Kind = Undirected;
102 type Edge = StaticUndirectedEdge<E>;
103}
104
105impl<N: Num> Bounded for StaticUndirectedEdge<N> {
106 fn max_value() -> Self {
107 StaticUndirectedEdge(N::max_value())
108 }
109
110 fn min_value() -> Self {
111 StaticUndirectedEdge(N::min_value())
112 }
113}
114
115impl<N: Num> EdgeImpl for StaticUndirectedEdge<N> {
117 fn new(e: usize) -> Self {
118 StaticUndirectedEdge(N::from_usize(e << 1))
119 }
120
121 fn new_checked(e: usize) -> Option<Self> {
122 e.checked_mul(2).and_then(|x| {
123 if N::is_valid(x) {
124 Some(Self::new(e))
125 } else {
126 None
127 }
128 })
129 }
130
131 fn source<T>(self, ends: &[T]) -> &T {
132 &ends[N::to_usize(self.0)]
133 }
134
135 fn target<T>(self, ends: &[T]) -> &T {
136 &ends[N::to_usize(self.0) ^ 1]
137 }
138
139 fn to_index(self) -> usize {
140 N::to_usize(self.0) >> 1
141 }
142
143 fn reverse(self) -> Self {
144 StaticUndirectedEdge(N::from_usize(N::to_usize(self.0) ^ 1))
145 }
146}
147
148impl<N: Num> PartialEq for StaticUndirectedEdge<N> {
149 fn eq(&self, other: &Self) -> bool {
150 self.to_index() == other.to_index()
151 }
152}
153
154impl<N: Num> PartialOrd for StaticUndirectedEdge<N> {
155 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
156 self.to_index().partial_cmp(&other.to_index())
157 }
158}
159
160impl<N: Num> Ord for StaticUndirectedEdge<N> {
161 fn cmp(&self, other: &Self) -> Ordering {
162 self.to_index().cmp(&other.to_index())
163 }
164}
165
166impl<N: Num> Hash for StaticUndirectedEdge<N> {
167 fn hash<H>(&self, state: &mut H)
168 where
169 H: Hasher,
170 {
171 self.to_index().hash(state)
172 }
173}
174
175pub type StaticVertex<N> = N;
178
179#[derive(Clone, Debug, PartialEq)]
182pub struct Static<V: Num, K: StaticEdgeKind> {
183 num_vertices: usize,
184 ends: Vec<StaticVertex<V>>,
185 edges: Vec<K::Edge>,
186 edges_start: Vec<usize>,
187}
188
189impl<V: Num, K: StaticEdgeKind> Static<V, K> {
190 fn inc(&self, v: Vertex<Self>) -> &[Edge<Self>] {
191 self.get_inc(v).unwrap()
192 }
193
194 fn get_inc(&self, v: Vertex<Self>) -> Option<&[Edge<Self>]> {
195 let i = V::to_usize(v);
196 self.edges.get(self.edges_start[i]..self.edges_start[i + 1])
197 }
198}
199
200impl<V: Num, K: StaticEdgeKind> WithBuilder for Static<V, K> {
201 type Builder = StaticBuilder<V, K>;
202}
203
204pub struct StaticBuilder<V: Num, K: StaticEdgeKind> {
205 num_vertices: usize,
206 ends: Vec<StaticVertex<V>>,
207 edges: Vec<K::Edge>,
208}
209
210impl<V: Num, K: StaticEdgeKind> Builder for StaticBuilder<V, K> {
211 type Graph = Static<V, K>;
212
213 fn new(num_vertices: usize, num_edges: usize) -> Self {
214 assert!(V::is_valid(num_vertices));
215 StaticBuilder {
216 num_vertices: num_vertices,
217 ends: Vec::with_capacity(2 * num_edges),
218 edges: vec![],
219 }
220 }
221
222 fn add_edge(&mut self, u: usize, v: usize) {
223 self.ends.push(V::from_usize(u));
224 self.ends.push(V::from_usize(v));
225 let e = K::Edge::new_checked((self.ends.len() - 2) / 2).expect("too many edges");
226 self.edges.push(e);
227 if K::Kind::is_undirected() {
228 self.edges.push(e.reverse());
229 }
230 }
231
232 fn finalize(mut self) -> Self::Graph {
233 let ends = self.ends;
235 self.edges
236 .sort_by_key(|e| (e.source(&ends), e.target(&ends)));
237
238 let mut starts = Vec::with_capacity(self.num_vertices.checked_add(1).unwrap());
239 let mut last = V::from_usize(self.num_vertices);
240 for (i, e) in self.edges.iter().enumerate() {
241 let s = *e.source(&ends);
242 if s != last {
243 while starts.len() != V::to_usize(s) {
244 starts.push(i)
245 }
246 assert_eq!(starts.len(), V::to_usize(s));
247 starts.push(i);
248 last = s;
249 }
250 }
251 while starts.len() <= self.num_vertices {
252 starts.push(self.edges.len());
253 }
254
255 Static {
256 num_vertices: self.num_vertices,
257 ends: ends,
258 edges: self.edges,
259 edges_start: starts,
260 }
261 }
262
263 fn finalize_(
264 self,
265 ) -> (
266 Self::Graph,
267 Vec<Vertex<Self::Graph>>,
268 Vec<Edge<Self::Graph>>,
269 ) {
270 let g = self.finalize();
271 let v = vec(g.vertices());
272 let e = vec(g.edges());
273 (g, v, e)
274 }
275}
276
277impl<V: Num, K: StaticEdgeKind> WithVertex for Static<V, K> {
280 type Vertex = StaticVertex<V>;
281 type OptionVertex = OptionalMax<StaticVertex<V>>;
282}
283
284impl<V: Num, K: StaticEdgeKind> WithEdge for Static<V, K> {
285 type Kind = K::Kind;
286 type Edge = K::Edge;
287 type OptionEdge = OptionalMax<Self::Edge>;
288
289 fn orientation(&self, _e: Edge<Self>) -> Orientation {
290 K::Kind::orientation()
291 }
292
293 fn source(&self, e: Edge<Self>) -> Vertex<Self> {
294 *e.source(&self.ends)
295 }
296
297 fn target(&self, e: Edge<Self>) -> Vertex<Self> {
298 *e.target(&self.ends)
299 }
300
301 fn get_reverse(&self, e: Edge<Self>) -> Option<Edge<Self>> {
302 if K::Kind::is_undirected() {
303 Some(e.reverse())
304 } else {
305 let (u, v) = self.ends(e);
306 self.get_edge_by_ends(v, u)
307 }
308 }
309}
310
311impl<'a, V: Num, K: StaticEdgeKind> VertexTypes<'a, Static<V, K>> for Static<V, K> {
312 type VertexIter = V::Range;
313 type OutNeighborIter = OutNeighborFromOutEdge<'a, Self, OutEdgeIter<'a, Self>>;
314}
315
316impl<'a, V: Num, K: StaticEdgeKind> EdgeTypes<'a, Static<V, K>> for Static<V, K> {
317 type EdgeIter = Map<Range<usize>, fn(usize) -> K::Edge>;
318 type OutEdgeIter = Cloned<Iter<'a, Edge<Self>>>;
319}
320
321impl<V: Num, K: StaticEdgeKind> VertexList for Static<V, K> {
322 fn num_vertices(&self) -> usize {
323 self.num_vertices
324 }
325
326 fn vertices(&self) -> VertexIter<Self> {
327 V::range(0, self.num_vertices)
328 }
329}
330
331impl<V: Num, K: StaticEdgeKind> EdgeList for Static<V, K> {
332 fn num_edges(&self) -> usize {
333 self.ends.len() / 2
334 }
335
336 fn edges(&self) -> EdgeIter<Self> {
337 (0..self.num_edges()).map(K::Edge::new)
338 }
339
340 fn get_edge_by_ends(&self, u: Vertex<Self>, v: Vertex<Self>) -> Option<Edge<Self>> {
341 self.get_inc(u).and_then(|out_edges| {
342 out_edges
343 .binary_search_by_key(&v, |e| self.target(*e))
344 .ok()
345 .map(|i| out_edges[i])
346 })
347 }
348}
349
350impl<V: Num, K: StaticEdgeKind> Adjacency for Static<V, K> {
351 fn out_neighbors(&self, v: Vertex<Self>) -> OutNeighborIter<Self> {
352 OutNeighborFromOutEdge::new(self, self.out_edges(v))
353 }
354
355 fn out_degree(&self, v: Vertex<Self>) -> usize {
356 self.inc(v).len()
357 }
358}
359
360impl<V: Num, K: StaticEdgeKind> Incidence for Static<V, K> {
361 fn out_edges(&self, v: Vertex<Self>) -> OutEdgeIter<Self> {
362 self.inc(v).iter().cloned()
363 }
364}
365
366#[derive(Clone, Debug)]
369pub struct SVertexIndexProp;
370
371impl<V: Num> PropGet<StaticVertex<V>> for SVertexIndexProp {
372 type Output = usize;
373
374 fn get(&self, v: StaticVertex<V>) -> usize {
375 v.to_usize()
376 }
377}
378
379impl<V: Num, K: StaticEdgeKind> WithVertexIndexProp for Static<V, K> {
380 type VertexIndexProp = SVertexIndexProp;
381
382 fn vertex_index(&self) -> VertexIndexProp<Self> {
383 SVertexIndexProp
384 }
385}
386
387#[derive(Clone, Debug)]
388pub struct SEdgeIndexProp<K>(PhantomData<K>);
389
390impl<K: StaticEdgeKind> PropGet<K::Edge> for SEdgeIndexProp<K> {
391 type Output = usize;
392
393 fn get(&self, e: K::Edge) -> usize {
394 e.to_index()
395 }
396}
397
398impl<V: Num, K: StaticEdgeKind> WithEdgeIndexProp for Static<V, K> {
399 type EdgeIndexProp = SEdgeIndexProp<K>;
400
401 fn edge_index(&self) -> EdgeIndexProp<Self> {
402 SEdgeIndexProp(PhantomData)
403 }
404}
405
406impl<T, V: Num, K: StaticEdgeKind> WithVertexProp<T> for Static<V, K> {
407 type VertexProp = VecVertexProp<Self, T>;
408}
409
410impl<V: Num, K: StaticEdgeKind> BasicVertexProps for Static<V, K> {}
411
412impl<T, V: Num, K: StaticEdgeKind> WithEdgeProp<T> for Static<V, K> {
413 type EdgeProp = VecEdgeProp<Self, T>;
414}
415
416impl<V: Num, K: StaticEdgeKind> BasicEdgeProps for Static<V, K> {}
417
418impl<V: Num, K: StaticEdgeKind> BasicProps for Static<V, K> {}
419
420impl<V: Num, K: StaticEdgeKind> Choose for Static<V, K> {
423 fn choose_vertex<R: Rng>(&self, mut rng: R) -> Option<Vertex<Self>> {
424 if self.num_vertices() == 0 {
425 None
426 } else {
427 Some(V::from_usize(rng.gen_range(0, self.num_vertices())))
428 }
429 }
430
431 fn choose_out_neighbor<R: Rng>(&self, v: Vertex<Self>, rng: R) -> Option<Vertex<Self>> {
432 self.choose_out_edge(v, rng).map(|e| self.target(e))
433 }
434
435 fn choose_edge<R: Rng>(&self, mut rng: R) -> Option<Edge<Self>> {
436 use graphs::common::gen_range_bool;
437 if self.num_edges() == 0 {
438 None
439 } else if K::Kind::is_undirected() {
440 let (i, rev) = gen_range_bool(self.num_edges(), rng).unwrap();
441 let e = K::Edge::new(i);
442 Some(if rev { e.reverse() } else { e })
443 } else {
444 Some(K::Edge::new(rng.gen_range(0, self.num_edges())))
445 }
446 }
447
448 fn choose_out_edge<R: Rng>(&self, v: Vertex<Self>, mut rng: R) -> Option<Edge<Self>> {
449 if self.out_degree(v) == 0 {
450 None
451 } else {
452 self.inc(v)
453 .get(rng.gen_range(0, self.out_degree(v)))
454 .cloned()
455 }
456 }
457}
458
459pub trait Num: 'static + Eq + Copy + Clone + Debug + Hash + Bounded + Ord {
462 type Range: Iterator<Item = Self>;
463 fn range(a: usize, b: usize) -> Self::Range;
464 fn to_usize(self) -> usize;
465 fn from_usize(v: usize) -> Self;
466 fn is_valid(v: usize) -> bool;
467}
468
469macro_rules! impl_num {
470 ($t:ident) => {
471 impl Num for $t {
472 type Range = Range<$t>;
473
474 #[inline]
475 fn range(a: usize, b: usize) -> Self::Range {
476 Self::from_usize(a)..Self::from_usize(b)
477 }
478
479 #[inline]
480 fn to_usize(self) -> usize {
481 self as usize
482 }
483
484 #[inline]
485 fn from_usize(v: usize) -> Self {
486 v as Self
487 }
488
489 #[inline]
490 fn is_valid(v: usize) -> bool {
491 (v as u64) < (Self::max_value() as u64)
492 }
493 }
494 };
495}
496
497impl_num!(u8);
498impl_num!(u16);
499impl_num!(u32);
500impl_num!(u64);
501impl_num!(usize);
502
503#[cfg(test)]
506mod tests {
507 pub use super::{EdgeImpl, StaticDigraph, StaticGraph, StaticUndirectedEdge};
508 pub use prelude::*;
509 use tests::GraphTests;
510
511 macro_rules! test {
512 ($m:ident, $g:ident) => {
513 mod $m {
514 pub use super::*;
515
516 struct Test;
517
518 impl GraphTests for Test {
519 type G = $g;
520
521 fn new() -> (Self::G, Vec<Vertex<Self::G>>, Vec<Edge<Self::G>>) {
522 Self::new_with_builder()
523 }
524 }
525
526 graph_tests!{Test}
527
528 mod with_builder {
529 use super::*;
530 use builder::BuilderTests;
531
532 struct Test;
533
534 impl BuilderTests for Test {
535 type G = StaticGraph;
536 }
537
538 graph_builder_tests!{Test}
539 }
540 }
541 };
542 }
543
544 test!(directed, StaticDigraph);
545 test!(undirected, StaticGraph);
546}