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_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
57pub 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
83impl<'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 #[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
310impl<'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}