1use std::{
2 iter::StepBy,
3 slice::{Iter, IterMut},
4};
5
6#[derive(Eq, PartialEq, Clone, Debug)]
7pub struct Grid<T> {
8 width: usize,
9 height: usize,
10 data: Vec<T>,
11}
12
13impl<T> Grid<T> {
14 pub fn new(width: usize, height: usize) -> Self
15 where
16 T: Default,
17 {
18 let mut data = Vec::with_capacity(width * height);
19 data.resize_with(width * height, T::default);
20
21 Self {
22 width,
23 height,
24 data,
25 }
26 }
27
28 pub fn init(width: usize, height: usize, value: T) -> Self
29 where
30 T: Clone,
31 {
32 Self {
33 width,
34 height,
35 data: vec![value; width * height],
36 }
37 }
38
39 pub fn from_vec(vec: Vec<T>, width: usize) -> Self {
40 assert_eq!(vec.len() % width, 0);
41
42 Self {
43 width,
44 height: vec.len() / width,
45 data: vec,
46 }
47 }
48
49 pub unsafe fn get_unchecked(&self, x: usize, y: usize) -> &T {
50 self.data.get_unchecked(x + y * self.width)
51 }
52
53 pub unsafe fn get_unchecked_mut(&mut self, x: usize, y: usize) -> &mut T {
54 self.data.get_unchecked_mut(x + y * self.width)
55 }
56
57 pub fn get(&self, x: usize, y: usize) -> Option<&T> {
58 self.data.get(x + y * self.width)
59 }
60
61 pub fn get_mut(&mut self, x: usize, y: usize) -> Option<&mut T> {
62 self.data.get_mut(x + y * self.width)
63 }
64
65 pub fn size(&self) -> (usize, usize) {
66 (self.width, self.height)
67 }
68
69 pub fn width(&self) -> usize {
70 self.width
71 }
72
73 pub fn height(&self) -> usize {
74 self.height
75 }
76
77 pub fn rows(&self) -> usize {
78 self.height
79 }
80
81 pub fn cols(&self) -> usize {
82 self.width
83 }
84
85 pub fn is_empty(&self) -> bool {
86 self.data.is_empty()
87 }
88
89 pub fn clear(&mut self) {
90 self.width = 0;
91 self.height = 0;
92 self.data.clear();
93 }
94
95 pub fn iter(&self) -> Iter<T> {
96 self.data.iter()
97 }
98
99 pub fn iter_mut(&mut self) -> IterMut<T> {
100 self.data.iter_mut()
101 }
102
103 pub fn iter_col(&self, col: usize) -> StepBy<Iter<T>> {
104 self.data[col..].iter().step_by(self.width)
105 }
106
107 pub fn iter_col_mut(&mut self, col: usize) -> StepBy<IterMut<T>> {
108 self.data[col..].iter_mut().step_by(self.width)
109 }
110
111 pub fn iter_row(&self, row: usize) -> Iter<T> {
112 let start = row * self.width;
113 self.data[start..(start + self.width)].iter()
114 }
115
116 pub fn iter_row_mut(&mut self, row: usize) -> IterMut<T> {
117 let start = row * self.width;
118 self.data[start..(start + self.width)].iter_mut()
119 }
120
121 pub fn flatten(&self) -> &Vec<T> {
122 &self.data
123 }
124
125 pub fn into_vec(self) -> Vec<T> {
126 self.data
127 }
128
129 pub fn fill(&mut self, value: T)
130 where
131 T: Clone,
132 {
133 self.data.fill(value);
134 }
135
136 pub fn fill_with(&mut self, func: impl FnMut() -> T) {
137 self.data.fill_with(func);
138 }
139
140 pub fn map<U>(self, func: impl FnMut(T) -> U) -> Grid<U> {
141 Grid {
142 width: self.width,
143 height: self.height,
144 data: self.data.into_iter().map(func).collect(),
145 }
146 }
147}
148
149impl<T> Grid<Option<T>> {
150 pub fn or(self, other: Self) -> Self {
151 assert_eq!(self.width, other.width);
152 assert_eq!(self.height, other.height);
153
154 Self {
155 width: self.width,
156 height: self.height,
157 data: self
158 .into_vec()
159 .into_iter()
160 .zip(other.into_vec().into_iter())
161 .map(|(a, b)| a.or(b))
162 .collect(),
163 }
164 }
165
166 pub fn and_then<U>(self, f: impl FnOnce(T) -> Option<U> + Clone) -> Grid<Option<U>> {
167 Grid {
168 width: self.width,
169 height: self.height,
170 data: self
171 .into_vec()
172 .into_iter()
173 .map(|a| a.and_then(f.clone()))
174 .collect(),
175 }
176 }
177
178 pub fn option_map<U>(self, f: impl FnOnce(T) -> U + Clone) -> Grid<Option<U>> {
179 Grid {
180 width: self.width,
181 height: self.height,
182 data: self
183 .into_vec()
184 .into_iter()
185 .map(|a| a.map(f.clone()))
186 .collect(),
187 }
188 }
189}
190
191#[cfg(test)]
192mod tests {
193 use super::*;
194
195 #[test]
196 fn and_then_works() {
197 let g = Grid::from_vec(vec![None, Some(2), Some(3), Some(4)], 2);
198 let r = g.and_then(|x| Some(x * x));
199
200 assert_eq!(r, Grid::from_vec(vec![None, Some(4), Some(9), Some(16)], 2));
201 }
202}