1use std::mem;
4
5pub struct Grid2D<T: Copy + Default> {
10 width: u32,
11 height: u32,
12 current: Vec<T>,
13 next: Vec<T>,
14}
15
16impl<T: Copy + Default> std::fmt::Debug for Grid2D<T> {
18 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19 f.debug_struct("Grid2D")
20 .field("width", &self.width)
21 .field("height", &self.height)
22 .finish_non_exhaustive()
23 }
24}
25
26impl<T: Copy + Default> Grid2D<T> {
27 pub fn new(width: u32, height: u32) -> Self {
29 let len = (width as usize) * (height as usize);
30 Self {
31 width,
32 height,
33 current: vec![T::default(); len],
34 next: vec![T::default(); len],
35 }
36 }
37
38 pub fn width(&self) -> u32 {
40 self.width
41 }
42
43 pub fn height(&self) -> u32 {
45 self.height
46 }
47
48 pub fn heap_bytes(&self) -> usize {
50 (self.current.capacity() + self.next.capacity()) * mem::size_of::<T>()
51 }
52
53 pub fn len(&self) -> usize {
55 self.current.len()
56 }
57
58 pub fn is_empty(&self) -> bool {
60 self.current.is_empty()
61 }
62
63 pub fn current(&self) -> &[T] {
65 &self.current
66 }
67
68 pub fn current_mut(&mut self) -> &mut [T] {
72 &mut self.current
73 }
74
75 pub fn next_mut(&mut self) -> &mut [T] {
77 &mut self.next
78 }
79
80 pub fn current_and_next_mut(&mut self) -> (&[T], &mut [T]) {
82 (&self.current, &mut self.next)
83 }
84
85 pub fn swap(&mut self) {
87 mem::swap(&mut self.current, &mut self.next);
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[test]
96 fn grid_new_and_size() {
97 let grid: Grid2D<u8> = Grid2D::new(10, 20);
98 assert_eq!(grid.width(), 10);
99 assert_eq!(grid.height(), 20);
100 assert_eq!(grid.len(), 200);
101 assert!(!grid.is_empty());
102 assert!(grid.current().iter().all(|&v| v == 0));
103 }
104
105 #[test]
106 fn grid_swap() {
107 let mut grid: Grid2D<u8> = Grid2D::new(3, 3);
108 grid.next_mut()[0] = 42;
109 assert_eq!(grid.current()[0], 0);
110 grid.swap();
111 assert_eq!(grid.current()[0], 42);
112 }
113
114 #[test]
115 fn current_and_next_mut_split_borrow() {
116 let mut grid: Grid2D<u8> = Grid2D::new(3, 3);
117 grid.current_mut()[4] = 10;
118 let (cur, nxt) = grid.current_and_next_mut();
119 nxt[4] = cur[4] + 1;
120 assert_eq!(grid.next_mut()[4], 11);
121 }
122}