1use core::fmt;
2use core::iter::{FusedIterator, Sum};
3use core::marker::PhantomData;
4use core::mem::MaybeUninit;
5use core::ops::{Add, Range};
6use core::ptr;
7
8use crate::new;
9use crate::{Column, Matrix, Row, Zero};
10
11pub struct IntoIter<T, const M: usize, const N: usize> {
32 matrix: Matrix<MaybeUninit<T>, M, N>,
33 alive: Range<usize>,
34}
35
36impl<T, const M: usize, const N: usize> fmt::Debug for IntoIter<T, M, N>
37where
38 T: fmt::Debug,
39{
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 f.debug_tuple("IntoIter").field(&self.as_slice()).finish()
42 }
43}
44
45impl<T, const M: usize, const N: usize> IntoIter<T, M, N> {
46 fn new(matrix: Matrix<T, M, N>) -> Self {
48 Self {
49 matrix: unsafe { new::transmute_unchecked(matrix) },
51 alive: 0..(M * N),
52 }
53 }
54
55 #[inline]
62 unsafe fn get_unchecked(&self, i: usize) -> T {
63 let ptr = unsafe { self.matrix.get_unchecked(i) }.as_ptr();
64 unsafe { ptr::read(ptr) }
65 }
66
67 #[inline]
69 fn as_slice(&self) -> &[T] {
70 let slice = &self.matrix.as_slice()[self.alive.clone()];
71 let ptr = slice as *const [MaybeUninit<T>] as *const [T];
72 unsafe { &*ptr }
74 }
75
76 #[inline]
78 fn as_mut_slice(&mut self) -> &mut [T] {
79 let slice = &mut self.matrix.as_mut_slice()[self.alive.clone()];
80 let ptr = slice as *mut [MaybeUninit<T>] as *mut [T];
81 unsafe { &mut *ptr }
83 }
84}
85
86impl<T, const M: usize, const N: usize> Iterator for IntoIter<T, M, N> {
87 type Item = T;
88
89 fn next(&mut self) -> Option<Self::Item> {
90 self.alive.next().map(|i| {
92 unsafe { self.get_unchecked(i) }
95 })
96 }
97
98 fn size_hint(&self) -> (usize, Option<usize>) {
99 let len = self.alive.len();
100 (len, Some(len))
101 }
102
103 fn count(self) -> usize {
104 self.alive.len()
105 }
106
107 fn last(mut self) -> Option<Self::Item> {
108 self.next_back()
109 }
110}
111
112impl<T, const M: usize, const N: usize> DoubleEndedIterator for IntoIter<T, M, N> {
113 fn next_back(&mut self) -> Option<Self::Item> {
114 self.alive.next_back().map(|i| {
116 unsafe { self.get_unchecked(i) }
119 })
120 }
121}
122
123impl<T, const M: usize, const N: usize> ExactSizeIterator for IntoIter<T, M, N> {
124 fn len(&self) -> usize {
125 self.alive.len()
126 }
127}
128
129impl<T, const M: usize, const N: usize> FusedIterator for IntoIter<T, M, N> {}
130
131impl<T, const M: usize, const N: usize> IntoIterator for Matrix<T, M, N> {
132 type Item = T;
133 type IntoIter = IntoIter<T, M, N>;
134
135 #[inline]
136 fn into_iter(self) -> Self::IntoIter {
137 IntoIter::new(self)
138 }
139}
140
141impl<T, const M: usize, const N: usize> Clone for IntoIter<T, M, N>
142where
143 T: Clone,
144{
145 fn clone(&self) -> Self {
146 let mut new = Self {
149 matrix: Matrix::uninit(),
150 alive: 0..0,
151 };
152 for (src, dst) in self.as_slice().iter().zip(new.matrix.as_mut_slice()) {
154 *dst = MaybeUninit::new(src.clone());
157 new.alive.end += 1;
158 }
159 new
160 }
161}
162
163impl<T, const M: usize, const N: usize> Drop for IntoIter<T, M, N> {
164 fn drop(&mut self) {
165 let slice = self.as_mut_slice();
166 unsafe { ptr::drop_in_place(slice) }
168 }
169}
170
171impl<T, const M: usize, const N: usize> Sum<Matrix<T, M, N>> for Matrix<T, M, N>
172where
173 Self: Add<Output = Self>,
174 T: Copy + Zero,
175{
176 fn sum<I>(iter: I) -> Self
177 where
178 I: Iterator<Item = Self>,
179 {
180 iter.fold(Matrix::zero(), Add::add)
181 }
182}
183
184pub struct IterRows<'a, T, const M: usize, const N: usize> {
190 matrix: &'a Matrix<T, M, N>,
191 alive: Range<usize>,
192}
193
194impl<'a, T, const M: usize, const N: usize> IterRows<'a, T, M, N> {
195 pub(crate) fn new(matrix: &'a Matrix<T, M, N>) -> Self {
196 Self {
197 matrix,
198 alive: 0..M,
199 }
200 }
201}
202
203impl<'a, T, const M: usize, const N: usize> Iterator for IterRows<'a, T, M, N> {
204 type Item = &'a Row<T, M, N>;
205
206 fn next(&mut self) -> Option<Self::Item> {
207 self.alive.next().map(|i| self.matrix.row(i))
208 }
209
210 fn size_hint(&self) -> (usize, Option<usize>) {
211 let len = self.alive.len();
212 (len, Some(len))
213 }
214
215 fn count(self) -> usize {
216 self.alive.len()
217 }
218
219 fn last(mut self) -> Option<Self::Item> {
220 self.next_back()
221 }
222}
223
224impl<T, const M: usize, const N: usize> DoubleEndedIterator for IterRows<'_, T, M, N> {
225 fn next_back(&mut self) -> Option<Self::Item> {
226 self.alive.next_back().map(|i| self.matrix.row(i))
227 }
228}
229
230impl<T, const M: usize, const N: usize> ExactSizeIterator for IterRows<'_, T, M, N> {
231 fn len(&self) -> usize {
232 self.alive.len()
233 }
234}
235
236impl<T, const M: usize, const N: usize> FusedIterator for IterRows<'_, T, M, N> {}
237
238pub struct IterColumns<'a, T, const M: usize, const N: usize> {
244 matrix: &'a Matrix<T, M, N>,
245 alive: Range<usize>,
246}
247
248impl<'a, T, const M: usize, const N: usize> IterColumns<'a, T, M, N> {
249 pub(crate) fn new(matrix: &'a Matrix<T, M, N>) -> Self {
250 Self {
251 matrix,
252 alive: 0..N,
253 }
254 }
255}
256
257impl<'a, T, const M: usize, const N: usize> Iterator for IterColumns<'a, T, M, N> {
258 type Item = &'a Column<T, M, N>;
259
260 fn next(&mut self) -> Option<Self::Item> {
261 self.alive.next().map(|i| self.matrix.column(i))
262 }
263
264 fn size_hint(&self) -> (usize, Option<usize>) {
265 let len = self.alive.len();
266 (len, Some(len))
267 }
268
269 fn count(self) -> usize {
270 self.alive.len()
271 }
272
273 fn last(mut self) -> Option<Self::Item> {
274 self.next_back()
275 }
276}
277
278impl<T, const M: usize, const N: usize> DoubleEndedIterator for IterColumns<'_, T, M, N> {
279 fn next_back(&mut self) -> Option<Self::Item> {
280 self.alive.next_back().map(|i| self.matrix.column(i))
281 }
282}
283
284impl<T, const M: usize, const N: usize> ExactSizeIterator for IterColumns<'_, T, M, N> {
285 fn len(&self) -> usize {
286 self.alive.len()
287 }
288}
289
290impl<T, const M: usize, const N: usize> FusedIterator for IterColumns<'_, T, M, N> {}
291
292pub struct IterRowsMut<'a, T, const M: usize, const N: usize> {
298 matrix: *mut Matrix<T, M, N>,
302 alive: Range<usize>,
303 marker: PhantomData<&'a mut Matrix<T, M, N>>,
304}
305
306impl<'a, T, const M: usize, const N: usize> IterRowsMut<'a, T, M, N> {
307 pub(crate) fn new(matrix: &'a mut Matrix<T, M, N>) -> Self {
308 Self {
309 matrix: matrix as *mut Matrix<T, M, N>,
310 alive: 0..M,
311 marker: PhantomData,
312 }
313 }
314}
315
316impl<'a, T, const M: usize, const N: usize> Iterator for IterRowsMut<'a, T, M, N> {
317 type Item = &'a mut Row<T, M, N>;
318
319 fn next(&mut self) -> Option<Self::Item> {
320 self.alive.next().map(|i| {
321 unsafe { (*self.matrix).row_mut(i) }
324 })
325 }
326
327 fn size_hint(&self) -> (usize, Option<usize>) {
328 let len = self.alive.len();
329 (len, Some(len))
330 }
331
332 fn count(self) -> usize {
333 self.alive.len()
334 }
335
336 fn last(mut self) -> Option<Self::Item> {
337 self.next_back()
338 }
339}
340
341impl<T, const M: usize, const N: usize> DoubleEndedIterator for IterRowsMut<'_, T, M, N> {
342 fn next_back(&mut self) -> Option<Self::Item> {
343 self.alive.next_back().map(|i| {
344 unsafe { (*self.matrix).row_mut(i) }
347 })
348 }
349}
350
351impl<T, const M: usize, const N: usize> ExactSizeIterator for IterRowsMut<'_, T, M, N> {
352 fn len(&self) -> usize {
353 self.alive.len()
354 }
355}
356
357impl<T, const M: usize, const N: usize> FusedIterator for IterRowsMut<'_, T, M, N> {}
358
359pub struct IterColumnsMut<'a, T, const M: usize, const N: usize> {
365 matrix: *mut Matrix<T, M, N>,
369 alive: Range<usize>,
370 marker: PhantomData<&'a mut Matrix<T, M, N>>,
371}
372
373impl<'a, T, const M: usize, const N: usize> IterColumnsMut<'a, T, M, N> {
374 pub(crate) fn new(matrix: &'a mut Matrix<T, M, N>) -> Self {
375 Self {
376 matrix: matrix as *mut Matrix<T, M, N>,
377 alive: 0..N,
378 marker: PhantomData,
379 }
380 }
381}
382
383impl<'a, T, const M: usize, const N: usize> Iterator for IterColumnsMut<'a, T, M, N> {
384 type Item = &'a mut Column<T, M, N>;
385
386 fn next(&mut self) -> Option<Self::Item> {
387 self.alive.next().map(|i| {
388 unsafe { (*self.matrix).column_mut(i) }
391 })
392 }
393
394 fn size_hint(&self) -> (usize, Option<usize>) {
395 let len = self.alive.len();
396 (len, Some(len))
397 }
398
399 fn count(self) -> usize {
400 self.alive.len()
401 }
402
403 fn last(mut self) -> Option<Self::Item> {
404 self.next_back()
405 }
406}
407
408impl<T, const M: usize, const N: usize> DoubleEndedIterator for IterColumnsMut<'_, T, M, N> {
409 fn next_back(&mut self) -> Option<Self::Item> {
410 self.alive.next_back().map(|i| {
411 unsafe { (*self.matrix).column_mut(i) }
414 })
415 }
416}
417
418impl<T, const M: usize, const N: usize> ExactSizeIterator for IterColumnsMut<'_, T, M, N> {
419 fn len(&self) -> usize {
420 self.alive.len()
421 }
422}
423
424impl<T, const M: usize, const N: usize> FusedIterator for IterColumnsMut<'_, T, M, N> {}