-
Notifications
You must be signed in to change notification settings - Fork 4
/
pos.rs
73 lines (63 loc) · 1.96 KB
/
pos.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use std::ops::{Sub, Add};
use std::iter::once;
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub(crate) struct Pos(pub u32, pub u32);
impl Pos {
#[inline(always)]
pub fn before(self, max: Pos) -> bool {
self.0 < max.0 && self.1 < max.1
}
pub fn successors(self, width: u32, height: u32)
-> impl Iterator<Item=Pos> {
let Pos(x, y) = self;
once(y + 1)
.filter(move |&y| y < height)
.flat_map(move |y| once(x.checked_sub(1))
.flatten()
.chain(once(x))
.chain(once(x + 1)
.filter(move |&x| x < width)
)
.map(move |x| Pos(x, y)))
}
pub fn predecessors(self, size: Pos)
-> impl Iterator<Item=Pos> {
let Pos(x, y) = self;
once(y)
.flat_map(|y| y.checked_sub(1))
.flat_map(move |y|
once(x.checked_sub(1))
.flatten()
.chain(once(x))
.chain(once(x + 1)
.filter(move |&x| x < size.0)
)
.map(move |x| Pos(x, y)))
}
pub fn iter_in_rect(end: Pos) -> impl Iterator<Item=Pos> {
(0..end.0 * end.1)
.map(move |i| Pos(i % end.0, i / end.0))
}
/// Returns the top,bottom,left and right positions, in this order
pub fn surrounding(self) -> [Pos; 4] {
let Pos(x, y) = self;
[
Pos(x, y.saturating_sub(1)), Pos(x, y + 1),
Pos(x.saturating_sub(1), y), Pos(x + 1, y)
]
}
}
impl Add<Pos> for Pos {
type Output = Pos;
#[inline(always)]
fn add(self, rhs: Pos) -> Self::Output {
Pos(self.0 + rhs.0, self.1 + rhs.1)
}
}
impl Sub<Pos> for Pos {
type Output = Pos;
#[inline(always)]
fn sub(self, rhs: Pos) -> Self::Output {
Pos(self.0.saturating_sub(rhs.0), self.1.saturating_sub(rhs.1))
}
}