hexga_math/geometry/grid/
view_mut.rs

1use crate::*;
2
3use crate::*;
4
5
6pub trait IGridViewMut<G, T, Idx, const N : usize> :
7      IGridView<G,T,Idx,N>
8    + GetMut<Vector<Idx,N>,Output = T> + GetManyMut<Vector<Idx,N>,Output=T>
9    + IndexMut<Vector<Idx,N>, Output = T>
10    where
11    G : IGrid<T, Idx, N>,
12    Idx : Integer
13{
14    type WithLifetimeMut<'a> : IGridViewMut<G,T,Idx,N> where Self: 'a;
15    fn view_mut<'a,'b>(&'a mut self) -> Self::WithLifetimeMut<'b> where 'a : 'b;
16
17    fn iter_mut(&mut self) -> GridViewIterMut<'_, G, T, Idx, N>;
18    fn for_each_mut<F>(&mut self, f : F) where F : FnMut((Vector<Idx,N>,&mut T));
19
20    fn fill_fn<F>(&mut self, mut f : F) where F : FnMut(Vector::<Idx,N>) -> T
21    {
22        self.for_each_mut(|(idx,v)| { *v = f(idx); })
23    }
24    //fn fill_fn_par<F>(&mut self, f : F) -> Self where F : Fn(Vector::<Idx,N>) -> T + Sync, T : Send, Idx : Sync;
25
26    fn fill_uniform(&mut self, value : T) where T: Clone { self.for_each_mut(|(_,v)| { *v = value.clone(); }); }
27
28    fn update_from_or_panic<O,G2>(&mut self, other : &O)
29            where
30        O : IGridView<G2,T,Idx,N>,
31        G2 : IGrid<T,Idx,N>,
32        T : Clone,
33        { self.update_from(other).unwrap() }
34
35    fn update_from<O,G2>(&mut self, other : &O) -> Result<(), ()>
36        where
37        O : IGridView<G2,T,Idx,N>,
38        G2 : IGrid<T,Idx,N>,
39        T : Clone,
40    {
41        if self.size() != other.size() { return Err(()); }
42
43        for idx in self.size().iter_index()
44        {
45            self[idx] = other[idx].clone();
46        }
47
48        Ok(())
49    }
50
51    #[doc(hidden)]
52    unsafe fn grid_mut_unchecked(&mut self) -> &mut G;
53}
54
55
56
57/// A mutable view to a N-dimensional grid.
58///
59/// Can only shrink / be cropped.
60pub struct GridViewMut<'a, G, T, Idx, const N : usize>
61    where
62    G : IGrid<T, Idx, N>,
63    Idx : Integer
64{
65    grid : &'a mut G,
66    rect : Rectangle<Idx,N>,
67    phantom : std::marker::PhantomData<T>,
68}
69
70impl<'c, G, T, Idx, const N : usize> IGridView<G,T,Idx,N> for GridViewMut<'c, G, T, Idx, N>
71    where
72    G : IGrid<T, Idx, N>,
73    Idx : Integer
74{
75    type WithLifetime<'a> = GridView<'a, G, T, Idx, N> where Self: 'a;
76    fn view<'a,'b>(&'a self) -> Self::WithLifetime<'b> where 'a : 'b { unsafe { GridView::from_rect_unchecked(self.grid_unchecked(), self.rect()) } }
77
78    unsafe fn grid_unchecked(&self) -> &G { self.grid }
79    unsafe fn subview_from_translated_rect_unchecked<'a, 'b>(&'a self, rect: Rectangle<Idx, N>) -> Self::WithLifetime<'b> where 'a: 'b
80    { unsafe { GridView::from_rect_unchecked(self.grid_unchecked(), rect) } }
81}
82
83/*
84impl<'c, G, T, Idx, const N : usize> IGridViewNonOwned<G, T, Idx, N> for GridViewMut<'c, G, T, Idx, N> where
85    G : IGrid<T, Idx, N>,
86    Idx : Integer {}
87*/
88
89impl<'c, G, T, Idx, const N : usize> IGridViewMut<G,T,Idx,N> for GridViewMut<'c, G, T, Idx, N>
90    where
91    G : IGrid<T, Idx, N>,
92    Idx : Integer
93{
94    type WithLifetimeMut<'a> = GridViewMut<'a, G, T, Idx, N> where Self: 'a;
95    fn view_mut<'a,'b>(&'a mut self) -> Self::WithLifetimeMut<'b> where 'a : 'b { unsafe { let r = self.rect(); GridViewMut::from_rect_unchecked(self.grid_mut_unchecked(), r) } }
96
97
98    fn iter_mut(&mut self) -> GridViewIterMut<'_, G, T, Idx, N> { GridViewIterMut::from_rect(self.grid, self.rect()).unwrap() }
99    fn for_each_mut<F>(&mut self, f : F) where F : FnMut((Vector<Idx,N>,&mut T)) { self.iter_mut().for_each(f); }
100
101    #[doc(hidden)]
102    unsafe fn grid_mut_unchecked(&mut self) -> &mut G { self.grid }
103}
104
105
106impl<'a, G, T, Idx, const N : usize> Debug for GridViewMut<'a, G, T, Idx, N>
107    where
108    G : IGrid<T, Idx, N>,
109    Idx : Integer,
110    T : Debug
111{
112    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result
113    {
114        f.debug_struct("GridViewMut").field("grid", &self.iter().map(|(_,v)| v).to_vec()).field("rect", &self.rect).finish()
115    }
116}
117
118impl<'a, G, T, Idx, const N : usize> PartialEq for GridViewMut<'a, G, T, Idx, N>
119    where
120    G : IGrid<T, Idx, N>,
121    Idx : Integer,
122    T : PartialEq
123{
124    fn eq(&self, other: &Self) -> bool
125    {
126        self.rect == other.rect && self.iter().eq(other.iter())
127    }
128}
129
130impl<'a, G, T, Idx, const N : usize> Eq for GridViewMut<'a, G, T, Idx, N>
131    where
132    G : IGrid<T, Idx, N>,
133    Idx : Integer,
134    T : Eq
135{}
136
137impl<'a, G, T, Idx, const N : usize> Hash for GridViewMut<'a, G, T, Idx, N>
138    where
139    G : IGrid<T, Idx, N>,
140    Idx : Integer,
141    T : Hash
142{
143    fn hash<H: Hasher>(&self, state: &mut H) {
144        self.rect.hash(state);
145        for (_, v) in self.iter()
146        {
147            v.hash(state);
148        }
149    }
150}
151
152impl<'a, G, T, Idx, const N : usize> PartialOrd for GridViewMut<'a, G, T, Idx, N>
153    where
154    G : IGrid<T, Idx, N>,
155    Idx : Integer,
156    T : PartialOrd
157{
158    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
159        if self.rect == other.rect {
160            self.iter().partial_cmp(other.iter())
161        }else
162        {
163            self.rect.partial_cmp(&other.rect)
164        }
165    }
166}
167
168impl<'a, G, T, Idx, const N : usize> Ord for GridViewMut<'a, G, T, Idx, N>
169    where
170    G : IGrid<T, Idx, N>,
171    Idx : Integer,
172    T : Ord
173{
174    fn cmp(&self, other: &Self) -> Ordering {
175        if self.rect == other.rect {
176            self.iter().cmp(other.iter())
177        }else
178        {
179            self.rect.cmp(&other.rect)
180        }
181    }
182}
183
184
185impl<'a, G, T, Idx, const N : usize> IRectangle<Idx,N> for GridViewMut<'a, G, T, Idx, N>
186    where
187    G : IGrid<T, Idx, N>,
188    Idx : Integer
189{
190    /// The view is relative to itself, so the position is zero
191    #[inline(always)]
192    fn pos(&self) -> Vector<Idx,N> { zero() }
193    #[inline(always)]
194    fn size(&self) -> Vector<Idx,N> { self.rect.size }
195    #[inline(always)]
196    fn rect(&self) -> Rectangle<Idx, N> { self.rect }
197}
198
199impl<'a, P, G, T, Idx, const N : usize> Get<P> for GridViewMut<'a, G, T, Idx, N>
200    where
201    G : IGrid<T, Idx, N>,
202    Idx : Integer,
203    P : Into<Vector<Idx,N>>,
204{
205    type Output = <G as Get<Vector<Idx,N>>>::Output;
206
207    #[inline(always)]
208    fn try_get(&self, index : P) -> Result<&Self::Output, ()> { self.grid.try_get(index.into() + self.rect.pos) }
209    #[inline(always)]
210    fn get(&self, index : P) -> Option<&Self::Output> { self.grid.get(index.into() + self.rect.pos) }
211    #[inline(always)]
212    #[track_caller]
213    unsafe fn get_unchecked(&self, index : P) -> &Self::Output { unsafe { self.grid.get_unchecked(index.into() + self.rect.pos) } }
214}
215
216impl<'a, P, G, T, Idx, const N : usize> Index<P> for GridViewMut<'a, G, T, Idx, N>
217    where
218    G : IGrid<T, Idx, N>,
219    Idx : Integer,
220    P : Into<Vector<Idx,N>>,
221{
222    type Output = <Self as Get<Vector<Idx,N>>>::Output;
223
224    #[track_caller]
225    fn index(&self, index: P) -> &Self::Output { self.get_or_panic(index) }
226}
227
228
229impl<'a, P, G, T, Idx, const N : usize> GetMut<P> for GridViewMut<'a, G, T, Idx, N>
230    where
231    G : IGrid<T, Idx, N>,
232    Idx : Integer,
233    P : Into<Vector<Idx,N>>,
234{
235    #[inline(always)]
236    fn try_get_mut(&mut self, index : P) -> Result<&mut Self::Output, ()> { self.grid.try_get_mut(index.into() + self.rect.pos) }
237    #[inline(always)]
238    fn get_mut(&mut self, index : P) -> Option<&mut Self::Output> { self.grid.get_mut(index.into() + self.rect.pos) }
239    #[inline(always)]
240    #[track_caller]
241    unsafe fn get_unchecked_mut(&mut self, index : P) -> &mut Self::Output { unsafe { self.grid.get_unchecked_mut(index.into() + self.rect.pos) } }
242}
243
244impl<'a, P, G, T, Idx, const N : usize> IndexMut<P> for GridViewMut<'a, G, T, Idx, N>
245    where
246    G : IGrid<T, Idx, N>,
247    Idx : Integer,
248    P : Into<Vector<Idx,N>>,
249{
250    #[inline(always)]
251    #[track_caller]
252    fn index_mut(&mut self, index: P) -> &mut Self::Output { self.get_mut_or_panic(index) }
253}
254
255impl<'a, P, G, T, Idx, const N : usize> GetManyMut<P> for GridViewMut<'a, G, T, Idx, N>
256    where
257    G : IGrid<T, Idx, N>,
258    Idx : Integer,
259    P : Into<Vector<Idx,N>>,
260{
261    fn try_get_many_mut<const N2: usize>(&mut self, indices: [P; N2]) -> Result<[&mut Self::Output;N2], ()> { self.grid.try_get_many_mut(indices.map(|idx| idx.into() + self.rect.pos)) }
262    #[inline(always)]
263    fn get_many_mut<const N2: usize>(&mut self, indices: [P; N2]) -> Option<[&mut Self::Output;N2]> { self.grid.try_get_many_mut(indices.map(|idx| idx.into() + self.rect.pos)).ok() }
264    #[inline(always)]
265    #[track_caller]
266    unsafe fn get_many_unchecked_mut<const N2: usize>(&mut self, indices: [P; N2]) -> [&mut Self::Output;N2] { self.grid.get_many_mut(indices.map(|idx| idx.into() + self.rect.pos)).expect("invalid index") }
267}
268
269
270impl<'a, G, T, Idx, const N : usize> GridViewMut<'a, G, T, Idx, N>
271    where
272    G : IGrid<T, Idx, N>,
273    Idx : Integer
274{
275    pub fn new(grid : &'a mut G) -> Self { unsafe { Self::from_rect_unchecked(grid, grid.rect()) } }
276
277    pub fn from_rect(grid : &'a mut G, rect : Rectangle<Idx,N>) -> Option<Self>
278    {
279        if !grid.rect().is_rect_inside(rect) {
280            return None;
281        }else
282        {
283            Some(unsafe { Self::from_rect_unchecked(grid, rect) })
284        }
285    }
286    pub unsafe fn from_rect_unchecked(grid : &'a mut G, rect : Rectangle<Idx,N>) -> Self { Self { grid, rect, phantom: PhantomData }}
287
288    pub fn from_rect_intersect(grid : &'a mut G, rect : Rectangle<Idx,N>) -> Self
289    {
290        unsafe { Self::from_rect_unchecked(grid, grid.rect().intersect_or_empty(rect)) }
291    }
292}
293
294
295impl<'a, G, T, Idx, const N : usize> Crop<Idx,N> for GridViewMut<'a, G, T, Idx, N>
296    where
297    G : IGrid<T, Idx, N>,
298    Idx : Integer
299{
300    fn crop(self, subrect : Rectangle<Idx, N>) -> Option<Self>
301    {
302        self.rect.crop(subrect).map(|r| unsafe { Self::from_rect_unchecked(self.grid, r) })
303    }
304}
305
306
307
308
309
310// I'm not sure about the `T : CastIntoComposite<Dest> + Copy` semantic for the moment, `&'a T : CastIntoComposite<Dest>` make more sens
311impl<'a, 'b, G, T, Idx, const N : usize, Dest> CastIntoComposite<Dest> for GridViewMut<'a,G, T, Idx, N>
312    where Idx : Integer, G : IGrid<T, Idx, N>, T : CastIntoComposite<Dest> + Copy
313{
314    type Output = G::WithType<T::Output>;
315    fn cast_into_composite(self) -> Self::Output {
316        self.transform(|v| v.cast_into_composite())
317    }
318}
319impl<'a, G, T, Idx, const N : usize, Dest> CastRangeIntoComposite<Dest> for GridViewMut<'a,G, T, Idx, N>
320    where Idx : Integer, G : IGrid<T, Idx, N>, T : CastRangeIntoComposite<Dest> + Copy
321{
322    type Output = G::WithType<T::Output>;
323    fn cast_range_into_composite(self) -> Self::Output {
324        self.transform(|v| v.cast_range_into_composite())
325    }
326}
327impl<'a, G, T, Idx, const N : usize> ToUnsigned for GridViewMut<'a,G, T, Idx, N>
328    where Idx : Integer, G : IGrid<T, Idx, N>, T : ToUnsigned + Copy
329{
330    type Output = G::WithType<T::Output>;
331
332    fn to_unsigned(self) -> Self::Output {
333        self.transform(|v| v.to_unsigned())
334    }
335}
336impl<'a, G, T, Idx, const N : usize> ToSigned for GridViewMut<'a,G, T, Idx, N>
337    where Idx : Integer, G : IGrid<T, Idx, N>, T : ToSigned + Copy
338{
339    type Output = G::WithType<T::Output>;
340
341    fn to_signed(self) -> Self::Output {
342        self.transform(|v| v.to_signed())
343    }
344}
345impl<'a, G, T, Idx, const N : usize> Abs for GridViewMut<'a,G, T, Idx, N>
346    where Idx : Integer, G : IGrid<T, Idx, N>, T : Abs + Copy
347{
348    type Output = G::WithType<T::Output>;
349    fn abs(self) -> Self::Output {
350        self.transform(|v| v.abs())
351    }
352}