cell_map/iterators/
mod.rs

1//! Provides iterators over [`CellMap`]s.
2//!
3//! Iterators are constructed using the `iter` family of functions on [`CellMap`], such as
4//! [`CellMap::iter()`] and [`CellMap::window_iter_mut()`]. Which function you use determines
5//! which [`Slicer`] the iterator uses, in other words what order and shape the iterated items will
6//! be produced in.
7//!
8//! Once constructed both [`CellMapIter`] and [`CellMapIterMut`] provide functions to modify the
9//! which layers are produced, and whether or not the items also produce their indexes. These can
10//! be used like iterator combinators.
11//!
12//! # Examples
13//!
14//! Iterate over a 3x3 window of items in the `Height` layer, while also returning the indices
15//! of the central cell of the window:
16//!
17//! ```
18//! # use cell_map::{CellMap, CellMapParams, Layer, Bounds};
19//! # use nalgebra::Vector2;
20//! # #[derive(Layer, Clone, Debug)]
21//! # enum MyLayer {
22//! #     Height,
23//! #     Gradient,
24//! #     Roughness
25//! # }
26//! #
27//! # // Creates a new 5x5 map where each cell is 1.0 units wide, which is centred on (0, 0), with
28//! # // all elements initialised to 1.0.
29//! # let mut map = CellMap::<MyLayer, f64>::new_from_elem(
30//! #     CellMapParams {
31//! #         cell_size: Vector2::new(1.0, 1.0),
32//! #         cell_bounds: Bounds::new((0, 5), (0, 5)).unwrap(),
33//! #         ..Default::default()
34//! #     },
35//! #     1.0,
36//! # );
37//! for ((layer, index), height) in map.window_iter(Vector2::new(1, 1)).unwrap().indexed() {
38//!     println!("[{:?}, {}, {}] = {}", layer, index.x, index.y, height);
39//! }
40//! ```
41//!
42//! [`CellMap`]: crate::CellMap
43
44// ------------------------------------------------------------------------------------------------
45// MODULES
46// ------------------------------------------------------------------------------------------------
47
48pub mod indexed;
49pub mod layerers;
50pub mod positioned;
51pub mod slicers;
52#[cfg(test)]
53mod tests;
54
55// ------------------------------------------------------------------------------------------------
56// IMPORTS
57// ------------------------------------------------------------------------------------------------
58
59use layerers::*;
60use nalgebra::{Point2, Vector2};
61use slicers::*;
62
63use crate::{CellMap, Error, Layer};
64
65use self::{indexed::Indexed, positioned::Positioned};
66
67// ------------------------------------------------------------------------------------------------
68// STRUCTS
69// ------------------------------------------------------------------------------------------------
70
71/// A non-mutable iterator over a [`CellMap`], see [`Slicer`] and [`layerers`] for more
72/// information.
73#[derive(Debug, Clone, Copy)]
74pub struct CellMapIter<'m, L, T, R, S>
75where
76    L: Layer,
77    R: Layerer<L>,
78    S: Slicer<'m, L, T>,
79{
80    map: &'m CellMap<L, T>,
81    layerer: R,
82    slicer: S,
83}
84
85/// A mutable iterator over a [`CellMap`], see [`Slicer`] and [`layerers`] for more information.
86#[derive(Debug)]
87pub struct CellMapIterMut<'m, L, T, R, S>
88where
89    L: Layer,
90    R: Layerer<L>,
91    S: Slicer<'m, L, T>,
92{
93    map: &'m mut CellMap<L, T>,
94    layerer: R,
95    slicer: S,
96}
97
98// ------------------------------------------------------------------------------------------------
99// IMPLS
100// ------------------------------------------------------------------------------------------------
101
102impl<'m, L, T, R, S> CellMapIter<'m, L, T, R, S>
103where
104    L: Layer,
105    S: Slicer<'m, L, T>,
106    R: Layerer<L>,
107{
108    pub(crate) fn new_cells(map: &'m CellMap<L, T>) -> CellMapIter<'m, L, T, Many<L>, Cells> {
109        CellMapIter {
110            map,
111            layerer: Many {
112                layers: L::all().into(),
113            },
114            slicer: Cells::from_map(map),
115        }
116    }
117
118    pub(crate) fn new_windows(
119        map: &'m CellMap<L, T>,
120        semi_width: Vector2<usize>,
121    ) -> Result<CellMapIter<'m, L, T, Many<L>, Windows>, Error> {
122        Ok(CellMapIter {
123            map,
124            layerer: Many {
125                layers: L::all().into(),
126            },
127            slicer: Windows::from_map(map, semi_width)?,
128        })
129    }
130
131    pub(crate) fn new_line(
132        map: &'m CellMap<L, T>,
133        start_position: Point2<f64>,
134        end_position: Point2<f64>,
135    ) -> Result<CellMapIter<'m, L, T, Many<L>, Line>, Error> {
136        Ok(CellMapIter {
137            map,
138            layerer: Many {
139                layers: L::all().into(),
140            },
141            slicer: Line::from_map::<L, T>(map.metadata, start_position, end_position)?,
142        })
143    }
144
145    /// Converts this iterator to use a [`Single`] layerer, produing data from only one layer.
146    pub fn layer(self, layer: L) -> CellMapIter<'m, L, T, Single<L>, S> {
147        CellMapIter {
148            map: self.map,
149            layerer: Single { layer },
150            slicer: self.slicer,
151        }
152    }
153
154    /// Converts this iterator to use a [`Many`] layerer, produing data from many layers.
155    pub fn layers(self, layers: &[L]) -> CellMapIter<'m, L, T, Many<L>, S> {
156        CellMapIter {
157            map: self.map,
158            layerer: Many {
159                layers: layers.to_vec().into(),
160            },
161            slicer: self.slicer,
162        }
163    }
164
165    /// Converts this iterator to also produce the index of the iterated item as well as its value.
166    pub fn indexed(self) -> CellMapIter<'m, L, T, R, Indexed<'m, L, T, S>> {
167        let current_layer = self.layerer.current().unwrap();
168        CellMapIter {
169            map: self.map,
170            layerer: self.layerer,
171            slicer: Indexed::new(self.slicer, current_layer),
172        }
173    }
174
175    /// Converts this iterator to also produce the position of the iterated item as well as its
176    /// value.
177    pub fn positioned(self) -> CellMapIter<'m, L, T, R, Positioned<'m, L, T, S>> {
178        let current_layer = self.layerer.current().unwrap();
179        CellMapIter {
180            map: self.map,
181            layerer: self.layerer,
182            slicer: Positioned::new(self.slicer, current_layer, self.map.metadata),
183        }
184    }
185}
186
187impl<'m, L, T, R, S> CellMapIterMut<'m, L, T, R, S>
188where
189    L: Layer,
190    R: Layerer<L>,
191    S: Slicer<'m, L, T>,
192{
193    pub(crate) fn new_cells(
194        map: &'m mut CellMap<L, T>,
195    ) -> CellMapIterMut<'m, L, T, Many<L>, Cells> {
196        let slicer = Cells::from_map(map);
197
198        CellMapIterMut {
199            map,
200            layerer: Many {
201                layers: L::all().into(),
202            },
203            slicer,
204        }
205    }
206
207    pub(crate) fn new_windows(
208        map: &'m mut CellMap<L, T>,
209        semi_width: Vector2<usize>,
210    ) -> Result<CellMapIterMut<'m, L, T, Many<L>, Windows>, Error> {
211        let slicer = Windows::from_map(map, semi_width)?;
212
213        Ok(CellMapIterMut {
214            map,
215            layerer: Many {
216                layers: L::all().into(),
217            },
218            slicer,
219        })
220    }
221
222    pub(crate) fn new_line(
223        map: &'m mut CellMap<L, T>,
224        start_position: Point2<f64>,
225        end_position: Point2<f64>,
226    ) -> Result<CellMapIterMut<'m, L, T, Many<L>, Line>, Error> {
227        let metadata = map.metadata;
228        Ok(CellMapIterMut {
229            map,
230            layerer: Many {
231                layers: L::all().into(),
232            },
233            slicer: Line::from_map::<L, T>(metadata, start_position, end_position)?,
234        })
235    }
236
237    /// Converts this iterator to use a [`Single`] layerer, produing data from only one layer.
238    pub fn layer(self, layer: L) -> CellMapIterMut<'m, L, T, Single<L>, S> {
239        CellMapIterMut {
240            map: self.map,
241            layerer: Single { layer },
242            slicer: self.slicer,
243        }
244    }
245
246    /// Converts this iterator to use a [`Many`] layerer, produing data from many layers.
247    pub fn layers(self, layers: &[L]) -> CellMapIterMut<'m, L, T, Many<L>, S> {
248        CellMapIterMut {
249            map: self.map,
250            layerer: Many {
251                layers: layers.to_vec().into(),
252            },
253            slicer: self.slicer,
254        }
255    }
256
257    /// Converts this iterator to use a [`Map`] layerer, which maps data from one layer to another.
258    pub fn map_layers(self, from: L, to: L) -> CellMapIterMut<'m, L, T, Map<L>, S> {
259        CellMapIterMut {
260            map: self.map,
261            layerer: Map { from, to },
262            slicer: self.slicer,
263        }
264    }
265
266    /// Converts this iterator to also produce the index of the iterated item as well as its value.
267    pub fn indexed(self) -> CellMapIterMut<'m, L, T, R, Indexed<'m, L, T, S>> {
268        let current_layer = self.layerer.current().unwrap();
269        CellMapIterMut {
270            map: self.map,
271            layerer: self.layerer,
272            slicer: Indexed::new(self.slicer, current_layer),
273        }
274    }
275
276    /// Converts this iterator to also produce the position of the iterated item as well as its
277    /// value.
278    pub fn positioned(self) -> CellMapIterMut<'m, L, T, R, Positioned<'m, L, T, S>> {
279        let current_layer = self.layerer.current().unwrap();
280        let map_meta = self.map.metadata;
281        CellMapIterMut {
282            map: self.map,
283            layerer: self.layerer,
284            slicer: Positioned::new(self.slicer, current_layer, map_meta),
285        }
286    }
287}
288
289// ------------------------------------------------------------------------------------------------
290// ITERATORS
291// ------------------------------------------------------------------------------------------------
292
293impl<'m, L, T, S> Iterator for CellMapIter<'m, L, T, Single<L>, S>
294where
295    L: Layer,
296    S: Slicer<'m, L, T>,
297{
298    type Item = S::Output;
299
300    fn next(&mut self) -> Option<Self::Item> {
301        let item = self
302            .slicer
303            .slice(&self.map.data[self.layerer.layer.to_index()]);
304
305        self.slicer.advance();
306
307        item
308    }
309}
310
311impl<'m, L, T, S> Iterator for CellMapIterMut<'m, L, T, Single<L>, S>
312where
313    L: Layer,
314    S: Slicer<'m, L, T>,
315{
316    type Item = S::OutputMut;
317
318    fn next(&mut self) -> Option<Self::Item> {
319        // Note: use of unsafe
320        //
321        // We must guarantee that we don't hand out multiple mutable references to the data stored
322        // in the map, which we can do since each call to this function will drop the previously
323        // returned reference first.
324        let item = unsafe {
325            let layer_ptr = self
326                .map
327                .data
328                .as_mut_ptr()
329                .add(self.layerer.layer.to_index());
330            self.slicer.slice_mut(&mut *layer_ptr)
331        };
332
333        self.slicer.advance();
334
335        item
336    }
337}
338
339impl<'m, L, T, S> Iterator for CellMapIter<'m, L, T, Many<L>, S>
340where
341    L: Layer,
342    S: Slicer<'m, L, T>,
343{
344    type Item = S::Output;
345
346    fn next(&mut self) -> Option<Self::Item> {
347        let item = self
348            .slicer
349            .slice(&self.map.data[self.layerer.layers.front()?.to_index()]);
350
351        self.slicer.advance();
352
353        if self.slicer.index().is_none() {
354            self.layerer.layers.pop_front();
355            self.slicer.reset(self.layerer.current());
356        }
357
358        item
359    }
360}
361
362impl<'m, L, T, S> Iterator for CellMapIterMut<'m, L, T, Many<L>, S>
363where
364    L: Layer,
365    S: Slicer<'m, L, T>,
366{
367    type Item = S::OutputMut;
368
369    fn next(&mut self) -> Option<Self::Item> {
370        // Note: use of unsafe
371        //
372        // We must guarantee that we don't hand out multiple mutable references to the data stored
373        // in the map, which we can do since each call to this function will drop the previously
374        // returned reference first.
375        let item = unsafe {
376            let layer_ptr = self
377                .map
378                .data
379                .as_mut_ptr()
380                .add(self.layerer.layers.front()?.to_index());
381            self.slicer.slice_mut(&mut *layer_ptr)
382        };
383
384        self.slicer.advance();
385
386        if self.slicer.index().is_none() {
387            self.layerer.layers.pop_front();
388            self.slicer.reset(self.layerer.current());
389        }
390
391        item
392    }
393}
394
395impl<'m, L, T, S> Iterator for CellMapIterMut<'m, L, T, Map<L>, S>
396where
397    L: Layer,
398    S: Slicer<'m, L, T>,
399{
400    type Item = (S::Output, S::OutputMut);
401
402    fn next(&mut self) -> Option<Self::Item> {
403        // Note: use of unsafe
404        //
405        // We must guarantee that we don't hand out multiple mutable references to the data stored
406        // in the map, which we can do since each call to this function will drop the previously
407        // returned reference first.
408        let (from, to) = unsafe {
409            let from_ptr = self.map.data.as_ptr().add(self.layerer.from.to_index());
410            let from = self.slicer.slice(&*from_ptr);
411            let to_ptr = self.map.data.as_mut_ptr().add(self.layerer.to.to_index());
412            let to = self.slicer.slice_mut(&mut *to_ptr);
413
414            (from, to)
415        };
416
417        self.slicer.advance();
418
419        match (from, to) {
420            (Some(f), Some(t)) => Some((f, t)),
421            (_, _) => None,
422        }
423    }
424}