1use ::core::{
69 fmt::Debug,
70 iter::{ FusedIterator, FromIterator },
71 marker::PhantomData,
72
73};
74
75
76use alloc::vec::Vec;
77use alloc::vec::IntoIter;
78use alloc::boxed::Box;
79
80use crate::{MatrixExt, MatrixMutExt};
81
82macro_rules! iter {
83 (
84 $(#[doc = $doc:expr] $name:ident { $($mut:ident)? } { $ptr:ident } $matrixTrait:ident $getfn:ident $($start:ident)?),* ;
85 $get_bounds:expr ;
86 $incrfn:item ;
87 $lenimpl:item ;
88 $nextbackimpl:item
89 ) => {
90 $(
91 #[doc = $doc]
92 #[derive(Hash, Debug, Copy, Clone)]
94 pub struct $name<'a, M: $matrixTrait + 'a>
95 {
96 m: *$ptr M,
97 i: usize,
98 irev: usize,
99 _marker: PhantomData<&'a M>,
100 }
101
102 impl<'a, M: $matrixTrait> $name<'a, M>
103 where M::Element: 'a
104 {
105 pub(crate) fn new(m: &'a $($mut)? M $(, $start: usize)? ) -> Self {
106 let get_start = $get_bounds;
107 let (i, irev) = get_start(m $(, $start)?);
108 Self { m, i, irev, _marker: PhantomData }
109 }
110
111 #[inline(always)]
112 fn use_matrix(&$($mut)? self) -> &'a $($mut)? M {
113 unsafe { (&$($mut)? *self.m) }
114 }
115
116 #[inline(always)]
117 fn matrix(&self) -> &'a M {
118 unsafe { (&*self.m) }
119 }
120
121 #[inline(always)]
122 fn get_nth(&$($mut)? self, i: usize) -> Option<&'a $($mut)? M::Element> {
123 self.use_matrix().$getfn(i)
124 }
125
126 #[inline(always)]
127 $incrfn
128
129 }
130
131 impl<'a, M: $matrixTrait> Iterator for $name<'a, M>
132 where M::Element: 'a
133 {
134 type Item = &'a $($mut)? M::Element;
135 fn next(&mut self) -> Option<Self::Item> {
136 if self.i > self.irev {
137 return None
138 }
139 let i = self.i;
140 self.i = self.increment(i);
141
142 self.get_nth(i)
144 }
145 }
146
147 impl<'a, M: $matrixTrait> FusedIterator for $name<'a, M> {}
148
149 impl<'a, M: $matrixTrait> ExactSizeIterator for $name<'a, M> {
150 $lenimpl
151 }
152
153 impl<'a, M: $matrixTrait> DoubleEndedIterator for $name<'a, M> {
154 $nextbackimpl
155 }
156
157 impl<'a, 'b, M, M2> PartialEq<$name<'b, M2>> for $name<'a, M>
158 where
159 M: $matrixTrait,
160 M2: $matrixTrait,
161 M::Element: PartialEq<M2::Element>
162 {
163 fn eq(&self, other: & $name<'b, M2>) -> bool {
164 let len = self.len();
165 if len != other.len() {
166 return false
167 }
168 for i in 0..len {
169 if self[i] != other[i] {
170 return false
171 }
172 }
173 true
174 }
175 }
176
177 impl<'a, M: $matrixTrait> Eq for $name<'a, M>
178 where
179 M::Element: PartialEq
180 {}
181
182
183 impl<'a, M: $matrixTrait, T, F> FromIterator<$name<'a, M>> for Box<[F]>
185 where
186 F: ::core::ops::Deref<Target = [T]>,
187 F: FromIterator<<$name<'a, M> as Iterator>::Item>,
188 M::Element: 'a
189 {
190 fn from_iter<IntoI>(iter: IntoI) -> Self
191 where
192 IntoI: IntoIterator<Item = $name<'a, M>>
193 {
194 iter.into_iter().map(|c| c.collect::<F>()).collect()
195 }
196 }
197
198 impl<'a, M: $matrixTrait, T, F> FromIterator<$name<'a, M>> for Vec<F>
199 where
200 F: ::core::ops::Deref<Target = [T]>,
201 F: FromIterator<<$name<'a, M> as Iterator>::Item>,
202 M::Element: 'a
203 {
204 fn from_iter<IntoI>(iter: IntoI) -> Self
205 where
206 IntoI: IntoIterator<Item = $name<'a, M>>
207 {
208 iter.into_iter().map(|c| c.collect::<F>()).collect()
209 }
210 }
211
212 impl<'a, M: $matrixTrait> ::core::ops::Index<usize> for $name<'a, M>
213 where
214 M::Element: 'a
215 {
216 type Output = M::Element;
217
218 fn index(&self, idx: usize) -> &Self::Output {
221 let mut i = self.i;
222 for _ in 0..idx {
223 i = self.increment(i);
224 }
225 self.matrix().get_nth(i).unwrap()
226 }
227 }
228
229 $(
230 impl<'a, M: $matrixTrait> ::core::ops::IndexMut<usize> for $name<'a, M>
231 where
232 M::Element: 'a
233 {
234 fn index_mut(&$mut self, idx: usize) -> &mut Self::Output {
237 let mut i = self.i;
238 for _ in 0..idx {
239 i = self.increment(i);
240 }
241 self.get_nth(i).unwrap()
242 }
243 }
244 )?
245
246 unsafe impl<'a, M: $matrixTrait> Send for $name<'a, M>
247 where M: Send, M::Element: Send {}
248
249 unsafe impl<'a, M: $matrixTrait> Sync for $name<'a, M>
250 where M: Sync, M::Element: Sync {}
251 )*
252 }
253}
254
255iter!{
256 #[doc =
257 "An iterator over the elements of the matrix.\n\n\
258 This struct is created by the [`iter`](MatrixExt::iter) method on [`MatrixExt`]."]
259 Iter {} { const } MatrixExt get_nth,
260 #[doc =
261 "An iterator over the elements of the matrix (mutable).\n\n\
262 This struct is created by the [`iter_mut`](MatrixMutExt::iter_mut) method on [`MatrixMutExt`]."]
263 IterMut { mut } { mut } MatrixMutExt get_nth_mut;
264 |m: &M| (0, m.size().saturating_sub(1)) ;
265 fn increment(&self, i: usize) -> usize {
266 i + 1
267 } ;
268 fn len(&self) -> usize { self.matrix().size() } ;
269 fn next_back(&mut self) -> Option<Self::Item> {
270 if self.i > self.irev {
271 return None
272 }
273 let j = self.irev;
274 self.irev -= 1;
275
276 self.get_nth(j)
278 }
279}
280
281iter!{
282 #[doc =
283 "An iterator over a matrix row.\n\n\
284 This struct is created by the [`row`](MatrixExt::row) method on [`MatrixExt`]."]
285 Row {} { const } MatrixExt get_nth irow,
286 #[doc =
287 "An iterator over a mutable matrix row.\n\n\
288 This struct is created by the [`row_mut`](MatrixMutExt::row_mut) method on [`MatrixMutExt`]."]
289 RowMut { mut } { mut } MatrixMutExt get_nth_mut irow;
290 |m: &M, row| {
291 let rlen = m.row_len();
292 let i = row * rlen;
293 (i, i + rlen - 1)
294 } ;
295 fn increment(&self, i: usize) -> usize {
296 i + 1
297 } ;
298 fn len(&self) -> usize { self.matrix().row_len() } ;
299 fn next_back(&mut self) -> Option<Self::Item> {
300 if self.i > self.irev {
301 return None
302 }
303 let j = self.irev;
304 self.irev -= 1;
305
306 self.get_nth(j)
308 }
309}
310
311macro_rules! dimensional_iterator {
312 ( $w:ident,
313 $ptr:ident,
314 { $($mut:ident)? },
315 $matrixTrait:ident,
316 $outElem:ty,
317 $callfn:ident,
318 $lenfn:ident
319 ) => {
320
321 #[derive(Debug)]
322 pub struct $w<'a, M>
323 where M: $matrixTrait,
324 M::Element: 'a {
325 n: usize,
326 m: *$ptr M,
327 _marker: PhantomData<&'a M>
328 }
329
330 impl<'a, M> Iterator for $w<'a, M>
331 where
332 M: $matrixTrait,
333 M::Element: 'a
334 {
335 type Item = $outElem;
336
337 fn next(&mut self) -> Option<Self::Item> {
338 let next = unsafe { (&$($mut)? *self.m).$callfn(self.n) };
339
340 self.n += 1;
341
342 next
344 }
345 }
346
347 impl<'a, M> DoubleEndedIterator for $w<'a, M>
348 where M: $matrixTrait,
349 {
350 fn next_back(&mut self) -> Option<Self::Item> {
351 let next = unsafe {
352 let m = (&$($mut)? *self.m);
353 let end = m.$lenfn();
354 m.$callfn(end - self.n - 1)
355 };
356
357 self.n += 1;
358
359 next
361 }
362
363 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
364 let next = unsafe {
365 let m = (&$($mut)? *self.m);
366 let end = m.$lenfn();
367 m.$callfn(end - self.n + n - 1)
368 };
369
370 self.n += 1;
371
372 next
374 }
375 }
376
377 impl<'a, M> FusedIterator for $w<'a, M>
378 where M: $matrixTrait
379 { }
380
381 impl<'a, M> ExactSizeIterator for $w<'a, M>
382 where M: $matrixTrait {
383 fn len(&self) -> usize {
384 let m = unsafe { &$($mut)? *self.m };
385 m.$lenfn()
386 }
387 }
388
389 impl<'a, 'b, M> From<&'b $($mut)? M> for $w<'a, M>
390 where
391 'b: 'a,
392 M: $matrixTrait
393 {
394 fn from(source: &'b $($mut)? M) -> Self {
395 Self {
396 n: 0,
397 m: source,
398 _marker: PhantomData
399 }
400 }
401 }
402
403 unsafe impl<'a, M: $matrixTrait> Send for $w<'a, M>
433 where M: Send, M::Element: Send {}
434
435 unsafe impl<'a, M: $matrixTrait> Sync for $w<'a, M>
436 where M: Sync, M::Element: Sync {}
437 };
438}
439
440iter!{
441 #[doc =
442 "An iterator over a matrix column.\n\n\
443 This struct is created by the [`col`](MatrixExt::col) method on [`MatrixExt`]."]
444 Column {} { const } MatrixExt get_nth icol,
445 #[doc =
446 "An iterator over a mutable matrix column.\n\n\
447 This struct is created by the [`col_mut`](MatrixMutExt::col_mut) method on [`MatrixMutExt`]."]
448 ColumnMut { mut } { mut} MatrixMutExt get_nth_mut icol;
449 |m: &M, col| {
450 let (rows, cols) = m.shape();
451 (col, (rows * cols) - cols.saturating_sub(col))
452 } ;
453 fn increment(&self, i: usize) -> usize {
454 i + self.matrix().row_len()
455 } ;
456 fn len(&self) -> usize { self.matrix().col_len() } ;
457 fn next_back(&mut self) -> Option<Self::Item> {
458 if self.i > self.irev {
459 return None
460 }
461 let j = self.irev;
462 self.irev -= self.use_matrix().row_len();
463
464 self.get_nth(j)
466 }
467}
468
469iter!{
470 #[doc =
471 "An iterator over a matrix diagonal.\n\n\
472 This struct is created by the [`diag`](MatrixExt::diag) method on [`MatrixExt`]."]
473 Diag {} { const } MatrixExt get_nth n,
474 #[doc =
475 "An iterator over a mutable matrix diagonal.\n\n\
476 This struct is created by the [`diag_mut`](MatrixMutExt::diag_mut) method on [`MatrixMutExt`]."]
477 DiagMut { mut } { mut } MatrixMutExt get_nth_mut n;
478 |m: &M, mut n| {
479 let (rows, cols) = match m.shape() {
480 (_, 0) | (0, _) => return (0, 1),
481 (rows, cols) => (rows, cols)
482 } ;
483 let diag_len = m.diag_len(n);
484 let main_diag = rows - 1;
485 if n < main_diag {
486 n = main_diag - n;
487 (
488 n * cols,
489 n + cols * (diag_len + 1),
490 )
491 } else {
492 n = n - main_diag;
493 (
494 n,
495 n + cols * (diag_len + 1),
496 )
497 }
498 } ;
499 fn increment(&self, i: usize) -> usize {
500 let m = self.matrix();
501 let (mut i, mut j) = m.subscripts_from(i);
502 i += 1;
503 j += 1;
504
505 if m.check(i, j) {
506 m.index_from((i, j))
507 }
508 else {
509 self.irev + 1
512 }
513 };
514 fn len(&self) -> usize { self.matrix().diag_len(self.i) };
515 fn next_back(&mut self) -> Option<Self::Item> {
516 if self.i > self.irev {
517 return None
518 }
519 let j = self.irev;
520 self.irev -= self.use_matrix().row_len() + 1;
521
522 self.get_nth(j)
524 }
525}
526
527
528dimensional_iterator!{
529 Rows, const, { }, MatrixExt,
530 Row<'a, M>,
531 row, num_rows
532}
533
534dimensional_iterator!{
535 RowsMut, mut, { mut }, MatrixMutExt,
536 RowMut<'a, M>,
537 row_mut, num_rows
538}
539
540dimensional_iterator!{
541 Columns, const, {}, MatrixExt,
542 Column<'a, M>,
543 col, num_cols
544}
545
546dimensional_iterator!{
547 ColumnsMut, mut, { mut }, MatrixMutExt,
548 ColumnMut<'a, M>,
549 col_mut, num_cols
550}
551
552dimensional_iterator!{
553 Diags, const, { }, MatrixExt,
554 Diag<'a, M>,
555 diag, num_diags
556}
557
558dimensional_iterator!{
559 DiagsMut, mut, { mut }, MatrixMutExt,
560 DiagMut<'a, M>,
561 diag_mut, num_diags
562}
563
564
565pub struct Enumerator<I> {
568 iter: I,
569 jmp: usize,
570 i: usize,
571 j: usize,
572}
573impl<I> Enumerator<I> {
574 pub(crate) fn new(iter: I, jmp: usize) -> Self {
575 Self {
576 iter,
577 jmp,
578 i: 0,
579 j: 0,
580 }
581 }
582}
583impl<I> Iterator for Enumerator<I>
584where
585 I: Iterator,
586{
587 type Item = (usize, usize, <I as Iterator>::Item);
588 fn next(&mut self) -> Option<Self::Item> {
589 let next = (self.i, self.j, self.iter.next()?);
590
591 self.j += 1;
592
593 if self.j == self.jmp {
594 self.j = 0;
595 self.i += 1;
596 }
597
598 Some(next)
599 }
600}
601impl<I> ExactSizeIterator for Enumerator<I>
602where
603 I: ExactSizeIterator
604{
605 fn len(&self) -> usize { self.iter.len() }
606}
607impl<I: FusedIterator> FusedIterator for Enumerator<I> {}
608
609
610#[derive(Default, Clone, Debug)]
611pub struct IntoAxes<T> {
612 axes: IntoIter<Vec<T>>,
613}
614impl<T> IntoAxes<T>
615{
616 pub fn from_as_rows<M: MatrixExt + IntoIterator>(src: M) -> Self
617 where <M as IntoIterator>::Item: IntoIterator<Item = T>
618 {
619 let mut v = Vec::with_capacity(src.num_rows());
620 for row in src {
621 v.push(row.into_iter().collect());
622 }
623
624 Self { axes: v.into_iter() }
625 }
626
627 pub fn from_as_cols<M: MatrixExt + IntoIterator>(src: M) -> Self
628 where <M as IntoIterator>::Item: IntoIterator<Item = T>
629 {
630 let (num_rows, num_cols) = src.shape();
631 let mut v = Vec::with_capacity(num_cols);
632 for _ in 0..num_cols {
633 v.push(Vec::with_capacity(num_rows));
634 }
635 for row in src {
636 for (i, elem) in row.into_iter().enumerate() {
637 v[i].push(elem)
638 }
639 }
640 Self { axes: v.into_iter() }
641 }
642
643 pub fn from_as_diags<M: MatrixExt + IntoIterator>(src: M) -> Self
644 where <M as IntoIterator>::Item: IntoIterator<Item = T>
645 {
646 if src.is_empty () {
647 return Self {
648 axes: Vec::new().into_iter()
649 }
650 }
651
652 let num_diags = src.num_diags();
654 let i_main_diag = src.num_rows() - 1;
655
656 let mut v = Vec::with_capacity(num_diags);
657 for i in 0..num_diags {
658 v.push(Vec::with_capacity(src.diag_len(i)));
659 }
660
661 let mut into_iter = src.into_iter();
663
664 let first_row = into_iter.next().expect("Not empty so first row must exist");
665
666 for (i, elem) in first_row.into_iter().enumerate() {
668 v[i_main_diag + i].push(elem);
669 }
670
671 for (i, row) in into_iter.enumerate() {
673 let mut row = row.into_iter();
674
675 v[i_main_diag - i - 1].push(row.next().expect("If new row then must contain at least one element"));
678
679 for (j, elem) in row.enumerate() {
680 v[i_main_diag + j].push(elem);
681 }
682 }
683 Self { axes: v.into_iter() }
684 }
685}
686
687impl<T> Iterator for IntoAxes<T> {
688 type Item = Vec<T>;
689 fn next(&mut self) -> Option<Self::Item> {
690 self.axes.next()
691 }
692}
693
694impl<T> DoubleEndedIterator for IntoAxes<T> {
695 fn next_back(&mut self) -> Option<Self::Item> {
696 self.axes.next_back()
697 }
698}
699
700impl<T> ExactSizeIterator for IntoAxes<T> {
701 fn len(&self) -> usize { self.axes.len() }
702}
703
704impl<T> FusedIterator for IntoAxes<T> {}