1pub mod combinate;
5
6pub mod backends;
8
9use crate::{
10 range::{
11 Range0To,
12 RangeBoundsTimes,
13 RangeBoundsPlus,
14 BoundRange,
15 },
16};
17use mint::Vector2;
18use std::{
19 ops::RangeBounds,
20 fmt::Debug,
21};
22
23pub fn alloc<I, T>(x_len: i32, y_len: i32, startval: T) -> backends::heap::ArrayGrid2<T>
25where
26 T: Clone
27{
28 backends::heap::ArrayGrid2::broadcast(x_len, y_len, startval)
29}
30
31pub fn alloc_gen<I, T, F>(x_len: i32, y_len: i32, generator: F) -> backends::heap::ArrayGrid2<T>
33where
34 I: From<Vector2<i32>>,
35 F: FnMut(I) -> T,
36{
37 backends::heap::ArrayGrid2::new(x_len, y_len, generator)
38}
39
40pub fn array3x3<I, T>(startval: T) -> backends::inline3x3::Inline3x3Grid<T>
42where
43 T: Clone
44{
45 backends::inline3x3::Inline3x3Grid::broadcast(startval)
46}
47
48pub fn array3x3_gen<I, T, F>(generator: F) -> backends::inline3x3::Inline3x3Grid<T>
50where
51 I: From<Vector2<i32>>,
52 F: FnMut(I) -> T,
53{
54 backends::inline3x3::Inline3x3Grid::new(generator)
55}
56
57pub fn value_fn<I, T, F>(f: F) -> backends::kolmo::KolmoGrid2<F, I, T>
59where
60 I: From<Vector2<i32>>,
61 F: Fn(I) -> T,
62{
63 backends::kolmo::KolmoGrid2::new(f)
64}
65
66pub fn ref_fn<'a, I, T, F>(f: F) -> backends::kolmoref::KolmoRefGrid2<'a, F, I, T>
68where
69 I: From<Vector2<i32>>,
70 T: 'a,
71 F: Fn(I) -> &'a T,
72{
73 backends::kolmoref::KolmoRefGrid2::new(f)
74}
75
76pub fn mut_fn<'a, I, T, F>(f: F) -> backends::kolmomut::KolmoMutGrid2<'a, F, I, T>
78where
79 I: From<Vector2<i32>>,
80 T: 'a,
81 F: Fn(I) -> &'a mut T,
82{
83 backends::kolmomut::KolmoMutGrid2::new(f)
84}
85
86pub fn reader_writer<I, R, T, Fr, Fw>(referent: R, reader: Fr, writer: Fw) -> backends::kolmorw::KolmoRwGrid2<I, R, T, Fr, Fw>
94where
95 I: From<Vector2<i32>>,
96 Fr: Fn(I, &R) -> &T,
97 Fw: Fn(I, &mut R) -> &mut T,
98{
99 backends::kolmorw::KolmoRwGrid2::new(referent, reader, writer)
100}
101
102pub trait Grid2 {
104 type Item;
105 type XBound: RangeBounds<i32>;
106 type YBound: RangeBounds<i32>;
107
108 fn x_bound(&self) -> Self::XBound;
109 fn y_bound(&self) -> Self::YBound;
110
111 fn in_bounds<I>(&self, coord: I) -> bool
112 where
113 I: Into<Vector2<i32>>
114 {
115 let Vector2 { x, y } = coord.into();
116
117 self.x_bound().contains(&x)
118 && self.y_bound().contains(&y)
119 }
120
121 fn map<F, T>(self, func: F) -> combinate::map::Grid2Map<Self, F, T>
123 where
124 Self: Sized,
125 F: Fn(Self::Item) -> T,
126 {
127 combinate::map::Grid2Map::new(self, func)
128 }
129
130 fn enumap<I, F, T>(self, func: F) -> combinate::enumap::Grid2EnuMap<Self, F, T, I>
132 where
133 Self: Sized,
134 I: From<Vector2<i32>>,
135 F: Fn(I, Self::Item) -> T,
136 {
137 combinate::enumap::Grid2EnuMap::new(self, func)
138 }
139
140 fn flatten<I>(self, stride: I) -> combinate::flatten::Grid2Flat<Self>
142 where
143 Self: Sized,
144 Self::Item: Grid2,
145 Self::XBound: Clone + RangeBoundsTimes,
146 Self::YBound: Clone + RangeBoundsTimes,
147 I: Into<Vector2<i32>>,
148 {
149 combinate::flatten::Grid2Flat::new(self, stride)
150 }
151
152 fn new_origin<I>(self, new_origin: I) -> combinate::neworigin::Grid2NewOrigin<Self>
154 where
155 Self: Sized,
156 Self::XBound: RangeBoundsPlus,
157 Self::YBound: RangeBoundsPlus,
158 I: Into<Vector2<i32>>,
159 {
160 combinate::neworigin::Grid2NewOrigin::new(self, new_origin)
161 }
162
163 fn oob_handler<I, F>(self, handler: F) -> combinate::oobhandler::Grid2OobHandler<Self, I, F>
167 where
168 Self: Sized,
169 I: From<Vector2<i32>>,
170 F: Fn(I) -> Self::Item,
171 {
172 combinate::oobhandler::Grid2OobHandler::new(self, handler)
173 }
174
175 fn subview<X, Y>(self, new_x: X, new_y: Y) -> combinate::slice::Grid2Slice<Self, X, Y>
180 where
181 Self: Sized,
182 Self::XBound: Debug,
183 Self::YBound: Debug,
184 X: RangeBounds<i32> + Clone + Debug,
185 Y: RangeBounds<i32> + Clone + Debug,
186 {
187 combinate::slice::Grid2Slice::new(self, new_x, new_y)
188 }
189
190 fn try_subview<X, Y>(self, new_x: X, new_y: Y) -> Result<combinate::slice::Grid2Slice<Self, X, Y>, Self>
195 where
196 Self: Sized,
197 Self::XBound: Debug,
198 Self::YBound: Debug,
199 X: RangeBounds<i32> + Clone + Debug,
200 Y: RangeBounds<i32> + Clone + Debug,
201 {
202 combinate::slice::Grid2Slice::try_new(self, new_x, new_y)
203 }
204
205 fn subview_0to(self, new_x_len: i32, new_y_len: i32) -> combinate::slice::Grid2Slice<Self, Range0To, Range0To>
210 where
211 Self: Sized,
212 Self::XBound: Debug,
213 Self::YBound: Debug,
214 {
215 combinate::slice::Grid2Slice::new(
216 self,
217 Range0To { end: new_x_len },
218 Range0To { end: new_y_len })
219 }
220
221 fn try_subview_0to(self, new_x_len: i32, new_y_len: i32) -> Result<combinate::slice::Grid2Slice<Self, Range0To, Range0To>, Self>
226 where
227 Self: Sized,
228 Self::XBound: Debug,
229 Self::YBound: Debug,
230 {
231 combinate::slice::Grid2Slice::try_new(
232 self,
233 Range0To { end: new_x_len },
234 Range0To { end: new_y_len })
235 }
236
237 fn wrapping(self) -> combinate::wrapping::Grid2Wrapping<Self>
242 where
243 Self: Sized,
244 Self::XBound: BoundRange,
245 Self::YBound: BoundRange,
246 {
247 combinate::wrapping::Grid2Wrapping::new(self)
248 }
249
250 fn collect(&self) -> backends::heap::ArrayGrid2<Self::Item>
254 where
255 Self: Grid2Get,
256 Self::XBound: Into<Range0To>,
257 Self::YBound: Into<Range0To>,
258 {
259 let x_len = self.x_bound().into().end;
260 let y_len = self.y_bound().into().end;
261 backends::heap::ArrayGrid2::new(
262 x_len, y_len,
263 |coord: Vector2<i32>| self.get(coord))
264 }
265}
266
267pub trait Grid2Len: Grid2<XBound=Range0To, YBound=Range0To> {
269 fn x_len(&self) -> i32 {
270 self.x_bound().end
271 }
272
273 fn y_len(&self) -> i32 {
274 self.y_bound().end
275 }
276}
277
278pub trait Grid2Get: Grid2 {
280 fn get<I>(&self, coord: I) -> Self::Item
281 where
282 I: Into<Vector2<i32>>;
283
284 fn try_get<I>(&self, coord: I) -> Option<Self::Item>
285 where
286 I: Into<Vector2<i32>>
287 {
288 let coord = coord.into();
289 if self.in_bounds(coord) {
290 Some(self.get(coord))
291 } else {
292 None
293 }
294 }
295}
296
297pub trait Grid2Set: Grid2 {
299 fn set<I>(&mut self, coord: I, elem: Self::Item)
300 where
301 I: Into<Vector2<i32>>;
302
303 fn try_set<I>(&mut self, coord: I, elem: Self::Item) -> Result<(), Self::Item>
304 where
305 I: Into<Vector2<i32>>
306 {
307 let coord = coord.into();
308 if self.in_bounds(coord) {
309 self.set(coord, elem);
310 Ok({})
311 } else {
312 Err(elem)
313 }
314 }
315}
316
317pub trait Grid2Ref: Grid2 {
319 fn idx<I>(&self, coord: I) -> &Self::Item
320 where
321 I: Into<Vector2<i32>>;
322
323 fn try_idx<I>(&self, coord: I) -> Option<&Self::Item>
324 where
325 I: Into<Vector2<i32>>
326 {
327 let coord = coord.into();
328 if self.in_bounds(coord) {
329 Some(self.idx(coord))
330 } else {
331 None
332 }
333 }
334}
335
336pub trait Grid2Mut: Grid2 {
338 fn midx<I>(&mut self, coord: I) -> &mut Self::Item
339 where
340 I: Into<Vector2<i32>>;
341
342 fn try_midx<I>(&mut self, coord: I) -> Option<&mut Self::Item>
343 where
344 I: Into<Vector2<i32>>
345 {
346 let coord = coord.into();
347 if self.in_bounds(coord) {
348 Some(self.midx(coord))
349 } else {
350 None
351 }
352 }
353}