hexga_math/geometry/grid/
iter_mut.rs1use super::*;
2
3pub struct GridViewIterMut<'a, G, T, Idx, const N: usize>
4where
5 G: IGrid<T, Idx, N>,
6 Idx: Integer,
7 T: 'a,
8{
9 grid: &'a mut G,
10 rect: RectangleIter<Idx, N>,
11 phantom: std::marker::PhantomData<T>,
12}
13
14impl<'a, G, T, Idx, const N: usize> GridViewIterMut<'a, G, T, Idx, N>
15where
16 G: IGrid<T, Idx, N>,
17 Idx: Integer,
18 T: 'a,
19{
20 pub fn new(grid: &'a mut G) -> Self
21 {
22 let rect = grid.rect().iter_index();
23 Self {
24 grid,
25 rect: rect,
26 phantom: std::marker::PhantomData,
27 }
28 }
29
30 pub fn from_rect(grid: &'a mut G, rect: Rectangle<Idx, N>) -> Option<Self>
31 {
32 if !grid.rect().is_rect_inside(rect)
33 {
34 return None;
35 }
36 else
37 {
38 Some(unsafe { Self::from_rect_unchecked(grid, rect) })
39 }
40 }
41
42 pub unsafe fn from_rect_unchecked(grid: &'a mut G, rect: Rectangle<Idx, N>) -> Self
43 {
44 Self {
45 grid,
46 rect: rect.iter_index(),
47 phantom: std::marker::PhantomData,
48 }
49 }
50
51 pub fn from_rect_intersect(grid: &'a mut G, rect: Rectangle<Idx, N>) -> Self
52 {
53 let rect = grid.rect().intersect_or_empty(rect).iter_index();
54 Self {
55 grid,
56 rect,
57 phantom: std::marker::PhantomData,
58 }
59 }
60}
61
62impl<'a, G, T, Idx, const N: usize> Iterator for GridViewIterMut<'a, G, T, Idx, N>
63where
64 G: IGrid<T, Idx, N>,
65 Idx: Integer,
66{
67 type Item = (Vector<Idx, N>, &'a mut T);
68
69 fn next(&mut self) -> Option<Self::Item>
70 {
71 let idx = self.rect.next()?;
72 Some((idx, unsafe {
75 (&mut *(&mut *self.grid as *mut G)).get_unchecked_mut(idx)
76 }))
77 }
78
79 fn size_hint(&self) -> (usize, Option<usize>) { self.rect.size_hint() }
80}
81impl<'a, G, T, Idx, const N: usize> std::iter::FusedIterator for GridViewIterMut<'a, G, T, Idx, N>
82where
83 G: IGrid<T, Idx, N>,
84 Idx: Integer,
85 RectangleIter<Idx, N>: std::iter::FusedIterator,
86{
87}
88impl<'a, G, T, Idx, const N: usize> std::iter::ExactSizeIterator
89 for GridViewIterMut<'a, G, T, Idx, N>
90where
91 G: IGrid<T, Idx, N>,
92 Idx: Integer,
93 RectangleIter<Idx, N>: std::iter::ExactSizeIterator,
94{
95}
96
97impl<'a, G, T, Idx, const N: usize> MapIntern for GridViewMut<'a, G, T, Idx, N>
98where
99 G: IGrid<T, Idx, N>,
100 Idx: Integer,
101{
102 type Item = T;
103
104 fn map_intern<F>(mut self, mut f: F) -> Self
105 where
106 F: FnMut(Self::Item) -> Self::Item,
107 {
108 self.iter_mut().for_each(|(_, v)| {
109 unsafe {
110 let old = std::ptr::read(v);
112 let new = f(old);
113 std::ptr::write(v, new);
114 }
115 });
116 self
117 }
118}
119
120impl<'a, G, T, Idx, const N: usize> MapInternWith for GridViewMut<'a, G, T, Idx, N>
121where
122 G: IGrid<T, Idx, N>,
123 Idx: Integer,
124 T: Clone,
125{
126 fn map_with_intern<F>(mut self, mut other: Self, mut f: F) -> Self
127 where
128 F: FnMut(Self::Item, Self::Item) -> Self::Item,
129 {
130 assert_eq!(self.size(), other.size(), "size mismatch");
131 self.iter_mut()
132 .zip(other.iter_mut())
133 .for_each(|((_, a), (_, b))| {
134 unsafe {
135 let old = std::ptr::read(a);
137 let new = f(old, b.clone());
138 std::ptr::write(a, new);
139 }
140 });
141 self
142 }
143}