easy_ml/matrices/
iterators.rs

1/*!
2 * Iterators over parts of a Matrix
3 *
4 * - Over a row: Row[(Reference)](RowReferenceIterator)[(Mut)](RowReferenceMutIterator)[Iterator](RowIterator)
5 * - Over a column: Column[(Reference)](ColumnReferenceIterator)[(Mut)](ColumnReferenceMutIterator)[Iterator](ColumnIterator)
6 * - Over all data in row major order: RowMajor[(Reference)](RowMajorReferenceIterator)[(Mut)](RowMajorReferenceMutIterator)[(Owned)](RowMajorOwnedIterator)[Iterator](RowMajorIterator)
7 * - Over all data in column major order: ColumnMajor[(Reference)](ColumnMajorReferenceIterator)[(Mut)](ColumnMajorReferenceMutIterator)[(Owned)](ColumnMajorOwnedIterator)[Iterator](ColumnMajorIterator)
8 * - Over the main diagonal: Diagonal[(Reference)](DiagonalReferenceIterator)[(Mut)](DiagonalReferenceMutIterator)[Iterator](DiagonalIterator)
9 *
10 * # Examples
11 *
12 * Extending a matrix with new columns
13 * ```
14 * use easy_ml::matrices::Matrix;
15 *
16 * // we start with some matrix where the first and second columns correspond
17 * // to x and y points
18 * let mut matrix = Matrix::from(vec![
19 *     vec![ 3.0, 4.0 ],
20 *     vec![ 8.0, 1.0 ],
21 *     vec![ 2.0, 9.0 ]]);
22 * // insert a third column based on the formula x * y
23 * matrix.insert_column_with(2, matrix.column_iter(0)
24 *     // join together the x and y columns
25 *     .zip(matrix.column_iter(1))
26 *     // compute the values for the new column
27 *     .map(|(x, y)| x * y)
28 *     // Collect into a vector so we stop immutably borrowing from `matrix`.
29 *     // This is only neccessary when we use the data from a Matrix to modify itself,
30 *     // because the rust compiler enforces that we do not mutably and immutably borrow
31 *     // something at the same time. If we used data from a different Matrix to update
32 *     // `matrix` then we could stop at map and pass the iterator directly.
33 *     .collect::<Vec<f64>>()
34 *     // now that the Vec created owns the data for the new column and we have stopped
35 *     // borrowing immutably from `matrix` we turn the vec back into an iterator and
36 *     // mutably borrow `matrix` to add the new column
37 *     .drain(..));
38 * assert_eq!(matrix.get(0, 2), 3.0 * 4.0);
39 * assert_eq!(matrix.get(1, 2), 8.0 * 1.0);
40 * assert_eq!(matrix.get(2, 2), 2.0 * 9.0);
41 * ```
42 *
43 * # Matrix layout and iterator performance
44 *
45 * Internally the Matrix type uses a flattened array with [row major storage](https://en.wikipedia.org/wiki/Row-_and_column-major_order)
46 * of the data. Due to [CPU cache lines](https://stackoverflow.com/questions/3928995/how-do-cache-lines-work)
47 * this means row major access of elements is likely to be faster than column major indexing,
48 * once a matrix is large enough, so you should favor iterating through each row.
49 *
50 * ```
51 * use easy_ml::matrices::Matrix;
52 * let matrix = Matrix::from(vec![
53 *    vec![ 1, 2 ],
54 *    vec![ 3, 4 ]]);
55 * // storage of elements is [1, 2, 3, 4]
56 *
57 * // row major access
58 * for row in 0..2 {
59 *     for column in 0..2 {
60 *         println!("{}", matrix.get(row, column));
61 *     }
62 * } // -> 1 2 3 4
63 * matrix.row_major_iter().for_each(|e| println!("{}", e)); // -> 1 2 3 4
64 * matrix.row_major_iter().with_index().for_each(|e| println!("{:?}", e)); // -> ((0, 0), 1) ((0, 1), 2), ((1, 0), 3), ((1, 1), 4)
65 *
66 * // column major access
67 * for column in 0..2 {
68 *     for row in 0..2 {
69 *         println!("{}", matrix.get(row, column));
70 *     }
71 * } // -> 1 3 2 4
72 * matrix.column_major_iter().for_each(|e| println!("{}", e)); // -> 1 3 2 4
73 * matrix.column_major_iter().with_index().for_each(|e| println!("{:?}", e)); // // -> ((0, 0), 1), ((1, 0), 3), ((0, 1), 2), ((1, 1), 4)
74 * ```
75 *
76 * Iterators are also able to elide array indexing bounds checks which may improve performance over
77 * explicit calls to get or get_reference in a loop, however you can use unsafe getters to elide
78 * bounds checks in loops as well so you are not forced to use iterators even if the checks are
79 * a performance concern.
80 */
81
82use std::iter::{ExactSizeIterator, FusedIterator};
83use std::marker::PhantomData;
84use std::ops::Range;
85
86use crate::matrices::views::{MatrixMut, MatrixRef, NoInteriorMutability};
87use crate::matrices::{Column, Matrix, Row};
88
89trait MatrixRefExtension<T>: MatrixRef<T> {
90    /**
91     * Helper for asserting starting indexes are in range.
92     */
93    fn index_is_valid(&self, row: Row, column: Column) -> bool {
94        row < self.view_rows() && column < self.view_columns()
95    }
96}
97
98impl<R, T> MatrixRefExtension<T> for R where R: MatrixRef<T> {}
99
100/**
101 * A wrapper around another iterator that iterates through each element in the iterator and
102 * includes the index used to access the element.
103 *
104 * This is like a 2D version of [`enumerate`](std::iter::Iterator::enumerate).
105 */
106#[derive(Debug)]
107pub struct WithIndex<I> {
108    pub(crate) iterator: I,
109}
110
111impl<I> WithIndex<I> {
112    /**
113     * Consumes the WithIndex, yielding the iterator it was created from.
114     */
115    pub fn source(self) -> I {
116        self.iterator
117    }
118}
119
120/**
121 * An iterator over a column in a matrix.
122 *
123 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
124 * ```ignore
125 * [
126 *   1, 2
127 *   3, 4
128 * ]
129 * ```
130 * Depending on the column iterator you want to obtain,
131 * can either iterate through 1, 3 or 2, 4.
132 */
133#[derive(Debug)]
134pub struct ColumnIterator<'a, T: Clone, S: MatrixRef<T> = Matrix<T>> {
135    matrix: &'a S,
136    column: Column,
137    range: Range<Row>,
138    _type: PhantomData<&'a T>,
139}
140
141impl<'a, T: Clone> ColumnIterator<'a, T> {
142    /**
143     * Constructs a column iterator over this matrix.
144     *
145     * # Panics
146     *
147     * Panics if the column does not exist in this matrix.
148     */
149    #[track_caller]
150    pub fn new(matrix: &Matrix<T>, column: Column) -> ColumnIterator<'_, T> {
151        ColumnIterator::from(matrix, column)
152    }
153}
154
155impl<'a, T: Clone, S: MatrixRef<T>> ColumnIterator<'a, T, S> {
156    /**
157     * Constructs a column iterator over this source.
158     *
159     * # Panics
160     *
161     * Panics if the column does not exist in this source.
162     */
163    #[track_caller]
164    pub fn from(source: &S, column: Column) -> ColumnIterator<'_, T, S> {
165        assert!(
166            source.index_is_valid(0, column),
167            "Expected ({},{}) to be in range",
168            0,
169            column
170        );
171        ColumnIterator {
172            matrix: source,
173            column,
174            range: 0..source.view_rows(),
175            _type: PhantomData,
176        }
177    }
178}
179
180impl<'a, T: Clone, S: MatrixRef<T>> Iterator for ColumnIterator<'a, T, S> {
181    type Item = T;
182
183    fn next(&mut self) -> Option<Self::Item> {
184        match self.range.next() {
185            None => None,
186            Some(row) => unsafe {
187                // Safety: We initialised the range to 0..matrix.view_rows(), and
188                // checked we can read from this column at creation, hence if
189                // the view_rows have not changed this read is in bounds and if
190                // they are able to be changed, then the MatrixRef implementation is
191                // required to bounds check for us.
192                Some(
193                    self.matrix
194                        .get_reference_unchecked(row, self.column)
195                        .clone(),
196                )
197            },
198        }
199    }
200
201    fn size_hint(&self) -> (usize, Option<usize>) {
202        self.range.size_hint()
203    }
204}
205impl<'a, T: Clone, S: MatrixRef<T>> FusedIterator for ColumnIterator<'a, T, S> {}
206impl<'a, T: Clone, S: MatrixRef<T>> ExactSizeIterator for ColumnIterator<'a, T, S> {}
207
208/**
209 * An iterator over a row in a matrix.
210 *
211 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
212 * ```ignore
213 * [
214 *   1, 2
215 *   3, 4
216 * ]
217 * ```
218 * Depending on the row iterator you want to obtain,
219 * can either iterate through 1, 2 or 3, 4.
220 */
221#[derive(Debug)]
222pub struct RowIterator<'a, T: Clone, S: MatrixRef<T> = Matrix<T>> {
223    matrix: &'a S,
224    row: Row,
225    range: Range<Column>,
226    _type: PhantomData<&'a T>,
227}
228
229impl<'a, T: Clone> RowIterator<'a, T> {
230    /**
231     * Constructs a row iterator over this matrix.
232     *
233     * # Panics
234     *
235     * Panics if the row does not exist in this matrix.
236     */
237    #[track_caller]
238    pub fn new(matrix: &Matrix<T>, row: Row) -> RowIterator<'_, T> {
239        RowIterator::from(matrix, row)
240    }
241}
242
243impl<'a, T: Clone, S: MatrixRef<T>> RowIterator<'a, T, S> {
244    /**
245     * Constructs a row iterator over this source.
246     *
247     * # Panics
248     *
249     * Panics if the row does not exist in this source.
250     */
251    #[track_caller]
252    pub fn from(source: &S, row: Row) -> RowIterator<'_, T, S> {
253        assert!(
254            source.index_is_valid(row, 0),
255            "Expected ({},{}) to be in range",
256            row,
257            0
258        );
259        RowIterator {
260            matrix: source,
261            row,
262            range: 0..source.view_columns(),
263            _type: PhantomData,
264        }
265    }
266}
267
268impl<'a, T: Clone, S: MatrixRef<T>> Iterator for RowIterator<'a, T, S> {
269    type Item = T;
270
271    fn next(&mut self) -> Option<Self::Item> {
272        match self.range.next() {
273            None => None,
274            Some(column) => unsafe {
275                // Safety: We initialised the range to 0..matrix.view_columns(), and
276                // checked we can read from this row at creation, hence if
277                // the view_columns have not changed this read is in bounds and if
278                // they are able to be changed, then the MatrixRef implementation is
279                // required to bounds check for us.
280                Some(
281                    self.matrix
282                        .get_reference_unchecked(self.row, column)
283                        .clone(),
284                )
285            },
286        }
287    }
288
289    fn size_hint(&self) -> (usize, Option<usize>) {
290        self.range.size_hint()
291    }
292}
293impl<'a, T: Clone, S: MatrixRef<T>> FusedIterator for RowIterator<'a, T, S> {}
294impl<'a, T: Clone, S: MatrixRef<T>> ExactSizeIterator for RowIterator<'a, T, S> {}
295
296// Common column major iterator logic
297fn column_major_iter(
298    finished: &mut bool,
299    rows: Row,
300    columns: Column,
301    row_counter: &mut Row,
302    column_counter: &mut Column,
303) -> Option<(Row, Column)> {
304    if *finished {
305        return None;
306    }
307
308    let value = Some((*row_counter, *column_counter));
309
310    if *row_counter == rows - 1 && *column_counter == columns - 1 {
311        // reached end of matrix for next iteration
312        *finished = true;
313    }
314
315    if *row_counter == rows - 1 {
316        // reached end of a column, need to reset to first element in next column
317        *row_counter = 0;
318        *column_counter += 1;
319    } else {
320        // keep incrementing through this column
321        *row_counter += 1;
322    }
323
324    value
325}
326
327// Common column major iterator size hint logic
328fn column_major_size_hint(
329    rows: Row,
330    columns: Column,
331    row_counter: Row,
332    column_counter: Column,
333) -> (usize, Option<usize>) {
334    let remaining_columns = columns - column_counter;
335    match remaining_columns {
336        0 => (0, Some(0)),
337        1 => {
338            // we're on the last column, so return how many items are left for us to
339            // go through with the row counter
340            let remaining_rows = rows - row_counter;
341            (remaining_rows, Some(remaining_rows))
342        }
343        x => {
344            // we still have at least one full column left in addition to what's left
345            // for this column's row counter
346            let remaining_rows = rows - row_counter;
347            // each full column takes as many iterations as the matrix has rows
348            let remaining_full_columns = (x - 1) * rows;
349            let remaining = remaining_rows + remaining_full_columns;
350            (remaining, Some(remaining))
351        }
352    }
353}
354
355/**
356 * A column major iterator over all values in a matrix.
357 *
358 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
359 * ```ignore
360 * [
361 *   1, 2
362 *   3, 4
363 * ]
364 * ```
365 * The elements will be iterated through as 1, 3, 2, 4
366 */
367#[derive(Debug)]
368pub struct ColumnMajorIterator<'a, T: Clone, S: MatrixRef<T> = Matrix<T>> {
369    matrix: &'a S,
370    column_counter: Column,
371    columns: Column,
372    row_counter: Row,
373    rows: Row,
374    finished: bool,
375    _type: PhantomData<&'a T>,
376}
377
378impl<'a, T: Clone> ColumnMajorIterator<'a, T> {
379    /**
380     * Constructs a column major iterator over this matrix.
381     */
382    pub fn new(matrix: &Matrix<T>) -> ColumnMajorIterator<'_, T> {
383        ColumnMajorIterator::from(matrix)
384    }
385}
386
387impl<'a, T: Clone, S: MatrixRef<T>> ColumnMajorIterator<'a, T, S> {
388    /**
389     * Constructs a column major iterator over this source.
390     */
391    pub fn from(source: &S) -> ColumnMajorIterator<'_, T, S> {
392        ColumnMajorIterator {
393            matrix: source,
394            column_counter: 0,
395            columns: source.view_columns(),
396            row_counter: 0,
397            rows: source.view_rows(),
398            finished: !source.index_is_valid(0, 0),
399            _type: PhantomData,
400        }
401    }
402
403    /**
404     * Constructs an iterator which also yields the row and column index of each element in
405     * this iterator.
406     */
407    pub fn with_index(self) -> WithIndex<Self> {
408        WithIndex { iterator: self }
409    }
410}
411
412impl<'a, T: Clone, S: MatrixRef<T>> From<ColumnMajorIterator<'a, T, S>>
413    for WithIndex<ColumnMajorIterator<'a, T, S>>
414{
415    fn from(iterator: ColumnMajorIterator<'a, T, S>) -> Self {
416        iterator.with_index()
417    }
418}
419
420impl<'a, T: Clone, S: MatrixRef<T>> Iterator for ColumnMajorIterator<'a, T, S> {
421    type Item = T;
422
423    fn next(&mut self) -> Option<Self::Item> {
424        column_major_iter(
425            &mut self.finished,
426            self.rows,
427            self.columns,
428            &mut self.row_counter,
429            &mut self.column_counter,
430        )
431        .map(|(row, column)| unsafe {
432            // Safety: We checked on creation that 0,0 is in range, and after getting
433            // our next value we check if we hit the end of the matrix and will avoid
434            // calling this on our next loop if we finished. Hence if the view size has
435            // not changed this read is in bounds and if they are able to be changed,
436            // then the MatrixRef implementation is required to bounds check for us.
437            self.matrix.get_reference_unchecked(row, column).clone()
438        })
439    }
440
441    fn size_hint(&self) -> (usize, Option<usize>) {
442        column_major_size_hint(
443            self.rows,
444            self.columns,
445            self.row_counter,
446            self.column_counter,
447        )
448    }
449}
450impl<'a, T: Clone, S: MatrixRef<T>> FusedIterator for ColumnMajorIterator<'a, T, S> {}
451impl<'a, T: Clone, S: MatrixRef<T>> ExactSizeIterator for ColumnMajorIterator<'a, T, S> {}
452
453impl<'a, T: Clone, S: MatrixRef<T>> Iterator for WithIndex<ColumnMajorIterator<'a, T, S>> {
454    type Item = ((Row, Column), T);
455
456    fn next(&mut self) -> Option<Self::Item> {
457        let (row, column) = (self.iterator.row_counter, self.iterator.column_counter);
458        self.iterator.next().map(|x| ((row, column), x))
459    }
460
461    fn size_hint(&self) -> (usize, Option<usize>) {
462        self.iterator.size_hint()
463    }
464}
465impl<'a, T: Clone, S: MatrixRef<T>> FusedIterator for WithIndex<ColumnMajorIterator<'a, T, S>> {}
466/**
467 * Note: On earlier versions of Easy ML (<=1.9.0), the size hint given for this impl erroneously
468 * did not return an exact size
469 */
470impl<'a, T: Clone, S: MatrixRef<T>> ExactSizeIterator for WithIndex<ColumnMajorIterator<'a, T, S>> {}
471
472// Common row major iterator logic
473fn row_major_iter(
474    finished: &mut bool,
475    rows: Row,
476    columns: Column,
477    row_counter: &mut Row,
478    column_counter: &mut Column,
479) -> Option<(Row, Column)> {
480    if *finished {
481        return None;
482    }
483
484    let value = Some((*row_counter, *column_counter));
485
486    if *column_counter == columns - 1 && *row_counter == rows - 1 {
487        // reached end of matrix for next iteration
488        *finished = true;
489    }
490
491    if *column_counter == columns - 1 {
492        // reached end of a row, need to reset to first element in next row
493        *column_counter = 0;
494        *row_counter += 1;
495    } else {
496        // keep incrementing through this row
497        *column_counter += 1;
498    }
499
500    value
501}
502
503// Common row major iterator size hint logic
504fn row_major_size_hint(
505    rows: Row,
506    columns: Column,
507    row_counter: Row,
508    column_counter: Column,
509) -> (usize, Option<usize>) {
510    let remaining_rows = rows - row_counter;
511    match remaining_rows {
512        0 => (0, Some(0)),
513        1 => {
514            // we're on the last row, so return how many items are left for us to
515            // go through with the column counter
516            let remaining_columns = columns - column_counter;
517            (remaining_columns, Some(remaining_columns))
518        }
519        x => {
520            // we still have at least one full row left in addition to what's left
521            // for this row's column counter
522            let remaining_columns = columns - column_counter;
523            // each full row takes as many iterations as the matrix has columns
524            let remaining_full_rows = (x - 1) * columns;
525            let remaining = remaining_columns + remaining_full_rows;
526            (remaining, Some(remaining))
527        }
528    }
529}
530
531/**
532 * A row major iterator over all values in a matrix.
533 *
534 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
535 * ```ignore
536 * [
537 *   1, 2
538 *   3, 4
539 * ]
540 * ```
541 * The elements will be iterated through as 1, 2, 3, 4
542 */
543#[derive(Debug)]
544pub struct RowMajorIterator<'a, T: Clone, S: MatrixRef<T> = Matrix<T>> {
545    matrix: &'a S,
546    column_counter: Column,
547    columns: Column,
548    row_counter: Row,
549    rows: Row,
550    finished: bool,
551    _type: PhantomData<&'a T>,
552}
553
554impl<'a, T: Clone> RowMajorIterator<'a, T> {
555    /**
556     * Constructs a row major iterator over this matrix.
557     */
558    pub fn new(matrix: &Matrix<T>) -> RowMajorIterator<'_, T> {
559        RowMajorIterator::from(matrix)
560    }
561}
562
563impl<'a, T: Clone, S: MatrixRef<T>> RowMajorIterator<'a, T, S> {
564    /**
565     * Constructs a row major iterator over this source.
566     */
567    pub fn from(source: &S) -> RowMajorIterator<'_, T, S> {
568        RowMajorIterator {
569            matrix: source,
570            column_counter: 0,
571            columns: source.view_columns(),
572            row_counter: 0,
573            rows: source.view_rows(),
574            finished: !source.index_is_valid(0, 0),
575            _type: PhantomData,
576        }
577    }
578
579    /**
580     * Constructs an iterator which also yields the row and column index of each element in
581     * this iterator.
582     */
583    pub fn with_index(self) -> WithIndex<Self> {
584        WithIndex { iterator: self }
585    }
586}
587
588impl<'a, T: Clone, S: MatrixRef<T>> From<RowMajorIterator<'a, T, S>>
589    for WithIndex<RowMajorIterator<'a, T, S>>
590{
591    fn from(iterator: RowMajorIterator<'a, T, S>) -> Self {
592        iterator.with_index()
593    }
594}
595
596impl<'a, T: Clone, S: MatrixRef<T>> Iterator for RowMajorIterator<'a, T, S> {
597    type Item = T;
598
599    fn next(&mut self) -> Option<Self::Item> {
600        row_major_iter(
601            &mut self.finished,
602            self.rows,
603            self.columns,
604            &mut self.row_counter,
605            &mut self.column_counter,
606        )
607        .map(|(row, column)| unsafe {
608            // Safety: We checked on creation that 0,0 is in range, and after getting
609            // our next value we check if we hit the end of the matrix and will avoid
610            // calling this on our next loop if we finished. Hence if the view size has
611            // not changed this read is in bounds and if they are able to be changed,
612            // then the MatrixRef implementation is required to bounds check for us.
613            self.matrix.get_reference_unchecked(row, column).clone()
614        })
615    }
616
617    fn size_hint(&self) -> (usize, Option<usize>) {
618        row_major_size_hint(
619            self.rows,
620            self.columns,
621            self.row_counter,
622            self.column_counter,
623        )
624    }
625}
626impl<'a, T: Clone, S: MatrixRef<T>> FusedIterator for RowMajorIterator<'a, T, S> {}
627impl<'a, T: Clone, S: MatrixRef<T>> ExactSizeIterator for RowMajorIterator<'a, T, S> {}
628
629impl<'a, T: Clone, S: MatrixRef<T>> Iterator for WithIndex<RowMajorIterator<'a, T, S>> {
630    type Item = ((Row, Column), T);
631
632    fn next(&mut self) -> Option<Self::Item> {
633        let (row, column) = (self.iterator.row_counter, self.iterator.column_counter);
634        self.iterator.next().map(|x| ((row, column), x))
635    }
636
637    fn size_hint(&self) -> (usize, Option<usize>) {
638        self.iterator.size_hint()
639    }
640}
641impl<'a, T: Clone, S: MatrixRef<T>> FusedIterator for WithIndex<RowMajorIterator<'a, T, S>> {}
642/**
643 * Note: On earlier versions of Easy ML (<=1.9.0), the size hint given for this impl erroneously
644 * did not return an exact size
645 */
646impl<'a, T: Clone, S: MatrixRef<T>> ExactSizeIterator for WithIndex<RowMajorIterator<'a, T, S>> {}
647
648/**
649 * An iterator over references to a column in a matrix.
650 *
651 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
652 * ```ignore
653 * [
654 *   1, 2
655 *   3, 4
656 * ]
657 * ```
658 * Depending on the row iterator you want to obtain,
659 * can either iterate through &1, &3 or &2, &4.
660 */
661#[derive(Debug)]
662pub struct ColumnReferenceIterator<'a, T, S: MatrixRef<T> = Matrix<T>> {
663    matrix: &'a S,
664    column: Column,
665    range: Range<Row>,
666    _type: PhantomData<&'a T>,
667}
668
669impl<'a, T> ColumnReferenceIterator<'a, T> {
670    /**
671     * Constructs a column iterator over this matrix.
672     *
673     * # Panics
674     *
675     * Panics if the column does not exist in this matrix.
676     */
677    #[track_caller]
678    pub fn new(matrix: &Matrix<T>, column: Column) -> ColumnReferenceIterator<'_, T> {
679        ColumnReferenceIterator::from(matrix, column)
680    }
681}
682
683impl<'a, T, S: MatrixRef<T>> ColumnReferenceIterator<'a, T, S> {
684    /**
685     * Constructs a column iterator over this source.
686     *
687     * # Panics
688     *
689     * Panics if the column does not exist in this source.
690     */
691    #[track_caller]
692    pub fn from(source: &S, column: Column) -> ColumnReferenceIterator<'_, T, S> {
693        assert!(
694            source.index_is_valid(0, column),
695            "Expected ({},{}) to be in range",
696            0,
697            column
698        );
699        ColumnReferenceIterator {
700            matrix: source,
701            column,
702            range: 0..source.view_rows(),
703            _type: PhantomData,
704        }
705    }
706}
707
708impl<'a, T, S: MatrixRef<T>> Iterator for ColumnReferenceIterator<'a, T, S> {
709    type Item = &'a T;
710
711    fn next(&mut self) -> Option<Self::Item> {
712        match self.range.next() {
713            None => None,
714            Some(row) => unsafe {
715                // Safety: We initialised the range to 0..matrix.view_rows(), and
716                // checked we can read from this column at creation, hence if
717                // the view_rows have not changed this read is in bounds and if
718                // they are able to be changed, then the MatrixRef implementation is
719                // required to bounds check for us.
720                Some(self.matrix.get_reference_unchecked(row, self.column))
721            },
722        }
723    }
724
725    fn size_hint(&self) -> (usize, Option<usize>) {
726        self.range.size_hint()
727    }
728}
729impl<'a, T, S: MatrixRef<T>> FusedIterator for ColumnReferenceIterator<'a, T, S> {}
730impl<'a, T, S: MatrixRef<T>> ExactSizeIterator for ColumnReferenceIterator<'a, T, S> {}
731
732/**
733 * An iterator over references to a row in a matrix.
734 *
735 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
736 * ```ignore
737 * [
738 *   1, 2
739 *   3, 4
740 * ]
741 * ```
742 * Depending on the row iterator you want to obtain,
743 * can either iterate through &1, &2 or &3, &4.
744 */
745#[derive(Debug)]
746pub struct RowReferenceIterator<'a, T, S: MatrixRef<T> = Matrix<T>> {
747    matrix: &'a S,
748    row: Row,
749    range: Range<Column>,
750    _type: PhantomData<&'a T>,
751}
752
753impl<'a, T> RowReferenceIterator<'a, T> {
754    /**
755     * Constructs a row iterator over this matrix.
756     *
757     * # Panics
758     *
759     * Panics if the row does not exist in this matrix.
760     */
761    #[track_caller]
762    pub fn new(matrix: &Matrix<T>, row: Row) -> RowReferenceIterator<'_, T> {
763        RowReferenceIterator::from(matrix, row)
764    }
765}
766
767impl<'a, T, S: MatrixRef<T>> RowReferenceIterator<'a, T, S> {
768    /**
769     * Constructs a row iterator over this source.
770     *
771     * # Panics
772     *
773     * Panics if the row does not exist in this source.
774     */
775    #[track_caller]
776    pub fn from(source: &S, row: Row) -> RowReferenceIterator<'_, T, S> {
777        assert!(
778            source.index_is_valid(row, 0),
779            "Expected ({},{}) to be in range",
780            row,
781            0
782        );
783        RowReferenceIterator {
784            matrix: source,
785            row,
786            range: 0..source.view_columns(),
787            _type: PhantomData,
788        }
789    }
790}
791
792impl<'a, T, S: MatrixRef<T>> Iterator for RowReferenceIterator<'a, T, S> {
793    type Item = &'a T;
794
795    fn next(&mut self) -> Option<Self::Item> {
796        match self.range.next() {
797            None => None,
798            Some(column) => unsafe {
799                // Safety: We initialised the range to 0..matrix.view_columns(), and
800                // checked we can read from this row at creation, hence if
801                // the view_columns have not changed this read is in bounds and if
802                // they are able to be changed, then the MatrixRef implementation is
803                // required to bounds check for us.
804                Some(self.matrix.get_reference_unchecked(self.row, column))
805            },
806        }
807    }
808
809    fn size_hint(&self) -> (usize, Option<usize>) {
810        self.range.size_hint()
811    }
812}
813impl<'a, T, S: MatrixRef<T>> FusedIterator for RowReferenceIterator<'a, T, S> {}
814impl<'a, T, S: MatrixRef<T>> ExactSizeIterator for RowReferenceIterator<'a, T, S> {}
815
816/**
817 * A column major iterator over references to all values in a matrix.
818 *
819 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
820 * ```ignore
821 * [
822 *   1, 2
823 *   3, 4
824 * ]
825 * ```
826 * The elements will be iterated through as &1, &3, &2, &4
827 */
828#[derive(Debug)]
829pub struct ColumnMajorReferenceIterator<'a, T, S: MatrixRef<T> = Matrix<T>> {
830    matrix: &'a S,
831    column_counter: Column,
832    columns: Column,
833    row_counter: Row,
834    rows: Row,
835    finished: bool,
836    _type: PhantomData<&'a T>,
837}
838
839impl<'a, T> ColumnMajorReferenceIterator<'a, T> {
840    /**
841     * Constructs a column major iterator over this matrix.
842     */
843    pub fn new(matrix: &Matrix<T>) -> ColumnMajorReferenceIterator<'_, T> {
844        ColumnMajorReferenceIterator::from(matrix)
845    }
846}
847
848impl<'a, T, S: MatrixRef<T>> ColumnMajorReferenceIterator<'a, T, S> {
849    /**
850     * Constructs a column major iterator over this source.
851     */
852    pub fn from(source: &S) -> ColumnMajorReferenceIterator<'_, T, S> {
853        ColumnMajorReferenceIterator {
854            matrix: source,
855            column_counter: 0,
856            columns: source.view_columns(),
857            row_counter: 0,
858            rows: source.view_rows(),
859            finished: !source.index_is_valid(0, 0),
860            _type: PhantomData,
861        }
862    }
863
864    /**
865     * Constructs an iterator which also yields the row and column index of each element in
866     * this iterator.
867     */
868    pub fn with_index(self) -> WithIndex<Self> {
869        WithIndex { iterator: self }
870    }
871}
872
873impl<'a, T, S: MatrixRef<T>> From<ColumnMajorReferenceIterator<'a, T, S>>
874    for WithIndex<ColumnMajorReferenceIterator<'a, T, S>>
875{
876    fn from(iterator: ColumnMajorReferenceIterator<'a, T, S>) -> Self {
877        iterator.with_index()
878    }
879}
880
881impl<'a, T, S: MatrixRef<T>> Iterator for ColumnMajorReferenceIterator<'a, T, S> {
882    type Item = &'a T;
883
884    fn next(&mut self) -> Option<Self::Item> {
885        column_major_iter(
886            &mut self.finished,
887            self.rows,
888            self.columns,
889            &mut self.row_counter,
890            &mut self.column_counter,
891        )
892        .map(|(row, column)| unsafe {
893            // Safety: We checked on creation that 0,0 is in range, and after getting
894            // our next value we check if we hit the end of the matrix and will avoid
895            // calling this on our next loop if we finished. Hence if the view size has
896            // not changed this read is in bounds and if they are able to be changed,
897            // then the MatrixRef implementation is required to bounds check for us.
898            self.matrix.get_reference_unchecked(row, column)
899        })
900    }
901
902    fn size_hint(&self) -> (usize, Option<usize>) {
903        column_major_size_hint(
904            self.rows,
905            self.columns,
906            self.row_counter,
907            self.column_counter,
908        )
909    }
910}
911
912impl<'a, T, S: MatrixRef<T>> FusedIterator for ColumnMajorReferenceIterator<'a, T, S> {}
913impl<'a, T, S: MatrixRef<T>> ExactSizeIterator for ColumnMajorReferenceIterator<'a, T, S> {}
914
915impl<'a, T, S: MatrixRef<T>> Iterator for WithIndex<ColumnMajorReferenceIterator<'a, T, S>> {
916    type Item = ((Row, Column), &'a T);
917
918    fn next(&mut self) -> Option<Self::Item> {
919        let (row, column) = (self.iterator.row_counter, self.iterator.column_counter);
920        self.iterator.next().map(|x| ((row, column), x))
921    }
922
923    fn size_hint(&self) -> (usize, Option<usize>) {
924        self.iterator.size_hint()
925    }
926}
927impl<'a, T, S: MatrixRef<T>> FusedIterator for WithIndex<ColumnMajorReferenceIterator<'a, T, S>> {}
928/**
929 * Note: On earlier versions of Easy ML (<=1.9.0), the size hint given for this impl erroneously
930 * did not return an exact size
931 */
932#[rustfmt::skip]
933impl<'a, T, S: MatrixRef<T>> ExactSizeIterator for WithIndex<ColumnMajorReferenceIterator<'a, T, S>> {}
934
935/**
936 * A row major iterator over references to all values in a matrix.
937 *
938 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
939 * ```ignore
940 * [
941 *   1, 2
942 *   3, 4
943 * ]
944 * ```
945 * The elements will be iterated through as &1, &2, &3, &4
946 */
947#[derive(Debug)]
948pub struct RowMajorReferenceIterator<'a, T, S: MatrixRef<T> = Matrix<T>> {
949    matrix: &'a S,
950    column_counter: Column,
951    columns: Column,
952    row_counter: Row,
953    rows: Row,
954    finished: bool,
955    _type: PhantomData<&'a T>,
956}
957
958impl<'a, T> RowMajorReferenceIterator<'a, T> {
959    /**
960     * Constructs a column major iterator over this matrix.
961     */
962    pub fn new(matrix: &Matrix<T>) -> RowMajorReferenceIterator<'_, T> {
963        RowMajorReferenceIterator::from(matrix)
964    }
965}
966
967impl<'a, T, S: MatrixRef<T>> RowMajorReferenceIterator<'a, T, S> {
968    /**
969     * Constructs a column major iterator over this source.
970     */
971    pub fn from(source: &S) -> RowMajorReferenceIterator<'_, T, S> {
972        RowMajorReferenceIterator {
973            matrix: source,
974            column_counter: 0,
975            columns: source.view_columns(),
976            row_counter: 0,
977            rows: source.view_rows(),
978            finished: !source.index_is_valid(0, 0),
979            _type: PhantomData,
980        }
981    }
982
983    /**
984     * Constructs an iterator which also yields the row and column index of each element in
985     * this iterator.
986     */
987    pub fn with_index(self) -> WithIndex<Self> {
988        WithIndex { iterator: self }
989    }
990}
991
992impl<'a, T, S: MatrixRef<T>> From<RowMajorReferenceIterator<'a, T, S>>
993    for WithIndex<RowMajorReferenceIterator<'a, T, S>>
994{
995    fn from(iterator: RowMajorReferenceIterator<'a, T, S>) -> Self {
996        iterator.with_index()
997    }
998}
999
1000impl<'a, T, S: MatrixRef<T>> Iterator for RowMajorReferenceIterator<'a, T, S> {
1001    type Item = &'a T;
1002
1003    fn next(&mut self) -> Option<Self::Item> {
1004        row_major_iter(
1005            &mut self.finished,
1006            self.rows,
1007            self.columns,
1008            &mut self.row_counter,
1009            &mut self.column_counter,
1010        )
1011        .map(|(row, column)| unsafe {
1012            // Safety: We checked on creation that 0,0 is in range, and after getting
1013            // our next value we check if we hit the end of the matrix and will avoid
1014            // calling this on our next loop if we finished. Hence if the view size has
1015            // not changed this read is in bounds and if they are able to be changed,
1016            // then the MatrixRef implementation is required to bounds check for us.
1017            self.matrix.get_reference_unchecked(row, column)
1018        })
1019    }
1020
1021    fn size_hint(&self) -> (usize, Option<usize>) {
1022        row_major_size_hint(
1023            self.rows,
1024            self.columns,
1025            self.row_counter,
1026            self.column_counter,
1027        )
1028    }
1029}
1030impl<'a, T, S: MatrixRef<T>> FusedIterator for RowMajorReferenceIterator<'a, T, S> {}
1031impl<'a, T, S: MatrixRef<T>> ExactSizeIterator for RowMajorReferenceIterator<'a, T, S> {}
1032
1033impl<'a, T, S: MatrixRef<T>> Iterator for WithIndex<RowMajorReferenceIterator<'a, T, S>> {
1034    type Item = ((Row, Column), &'a T);
1035
1036    fn next(&mut self) -> Option<Self::Item> {
1037        let (row, column) = (self.iterator.row_counter, self.iterator.column_counter);
1038        self.iterator.next().map(|x| ((row, column), x))
1039    }
1040
1041    fn size_hint(&self) -> (usize, Option<usize>) {
1042        self.iterator.size_hint()
1043    }
1044}
1045impl<'a, T, S: MatrixRef<T>> FusedIterator for WithIndex<RowMajorReferenceIterator<'a, T, S>> {}
1046/**
1047 * Note: On earlier versions of Easy ML (<=1.9.0), the size hint given for this impl erroneously
1048 * did not return an exact size
1049 */
1050impl<'a, T, S: MatrixRef<T>> ExactSizeIterator for WithIndex<RowMajorReferenceIterator<'a, T, S>> {}
1051
1052/**
1053 * An iterator over the main diagonal in a matrix.
1054 *
1055 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
1056 * ```ignore
1057 * [
1058 *   1, 2
1059 *   3, 4
1060 * ]
1061 * ```
1062 * The elements will be iterated through as 1, 4
1063 *
1064 * If the matrix is not square this will stop at whichever row/colum is shorter.
1065 */
1066#[derive(Debug)]
1067pub struct DiagonalIterator<'a, T: Clone, S: MatrixRef<T> = Matrix<T>> {
1068    matrix: &'a S,
1069    range: Range<usize>,
1070    _type: PhantomData<&'a T>,
1071}
1072
1073impl<'a, T: Clone> DiagonalIterator<'a, T> {
1074    /**
1075     * Constructs a diagonal iterator over this matrix.
1076     */
1077    pub fn new(matrix: &Matrix<T>) -> DiagonalIterator<'_, T> {
1078        DiagonalIterator::from(matrix)
1079    }
1080}
1081
1082impl<'a, T: Clone, S: MatrixRef<T>> DiagonalIterator<'a, T, S> {
1083    /**
1084     * Constructs a diagonal iterator over this source.
1085     */
1086    pub fn from(source: &S) -> DiagonalIterator<'_, T, S> {
1087        DiagonalIterator {
1088            matrix: source,
1089            range: 0..std::cmp::min(source.view_rows(), source.view_columns()),
1090            _type: PhantomData,
1091        }
1092    }
1093}
1094
1095impl<'a, T: Clone, S: MatrixRef<T>> Iterator for DiagonalIterator<'a, T, S> {
1096    type Item = T;
1097
1098    fn next(&mut self) -> Option<Self::Item> {
1099        match self.range.next() {
1100            None => None,
1101            Some(i) => unsafe {
1102                // Safety: We initialised the range to 0..min(rows/columns), hence if the
1103                // view size has not changed this read is in bounds and if they are able to
1104                // be changed, then the MatrixRef implementation is required to bounds
1105                // check for us.
1106                Some(self.matrix.get_reference_unchecked(i, i).clone())
1107            },
1108        }
1109    }
1110
1111    fn size_hint(&self) -> (usize, Option<usize>) {
1112        self.range.size_hint()
1113    }
1114}
1115impl<'a, T: Clone, S: MatrixRef<T>> FusedIterator for DiagonalIterator<'a, T, S> {}
1116impl<'a, T: Clone, S: MatrixRef<T>> ExactSizeIterator for DiagonalIterator<'a, T, S> {}
1117
1118/**
1119 * An iterator over references to the main diagonal in a matrix.
1120 *
1121 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
1122 * ```ignore
1123 * [
1124 *   1, 2
1125 *   3, 4
1126 * ]
1127 * ```
1128 * The elements will be iterated through as &1, &4
1129 *
1130 * If the matrix is not square this will stop at whichever row/colum is shorter.
1131 */
1132#[derive(Debug)]
1133pub struct DiagonalReferenceIterator<'a, T, S: MatrixRef<T> = Matrix<T>> {
1134    matrix: &'a S,
1135    range: Range<usize>,
1136    _type: PhantomData<&'a T>,
1137}
1138
1139impl<'a, T> DiagonalReferenceIterator<'a, T> {
1140    /**
1141     * Constructs a diagonal iterator over this matrix.
1142     */
1143    pub fn new(matrix: &Matrix<T>) -> DiagonalReferenceIterator<'_, T> {
1144        DiagonalReferenceIterator::from(matrix)
1145    }
1146}
1147
1148impl<'a, T, S: MatrixRef<T>> DiagonalReferenceIterator<'a, T, S> {
1149    /**
1150     * Constructs a diagonal iterator over this source.
1151     */
1152    pub fn from(source: &S) -> DiagonalReferenceIterator<'_, T, S> {
1153        DiagonalReferenceIterator {
1154            matrix: source,
1155            range: 0..std::cmp::min(source.view_rows(), source.view_columns()),
1156            _type: PhantomData,
1157        }
1158    }
1159}
1160
1161impl<'a, T, S: MatrixRef<T>> Iterator for DiagonalReferenceIterator<'a, T, S> {
1162    type Item = &'a T;
1163
1164    fn next(&mut self) -> Option<Self::Item> {
1165        match self.range.next() {
1166            None => None,
1167            Some(i) => unsafe {
1168                // Safety: We initialised the range to 0..min(rows/columns), hence if the
1169                // view size has not changed this read is in bounds and if they are able to
1170                // be changed, then the MatrixRef implementation is required to bounds
1171                // check for us.
1172                Some(self.matrix.get_reference_unchecked(i, i))
1173            },
1174        }
1175    }
1176
1177    fn size_hint(&self) -> (usize, Option<usize>) {
1178        self.range.size_hint()
1179    }
1180}
1181impl<'a, T, S: MatrixRef<T>> FusedIterator for DiagonalReferenceIterator<'a, T, S> {}
1182impl<'a, T, S: MatrixRef<T>> ExactSizeIterator for DiagonalReferenceIterator<'a, T, S> {}
1183
1184/**
1185 * A column major iterator over mutable references to all values in a matrix.
1186 *
1187 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
1188 * ```ignore
1189 * [
1190 *   1, 2
1191 *   3, 4
1192 * ]
1193 * ```
1194 * The elements will be iterated through as &mut 1, &mut 3, &mut 2, &mut 4
1195 */
1196#[derive(Debug)]
1197#[rustfmt::skip]
1198pub struct ColumnMajorReferenceMutIterator<'a, T, S: MatrixMut<T> + NoInteriorMutability = Matrix<T>> {
1199    matrix: &'a mut S,
1200    column_counter: Column,
1201    columns: Column,
1202    row_counter: Row,
1203    rows: Row,
1204    finished: bool,
1205    _type: PhantomData<&'a mut T>,
1206}
1207
1208impl<'a, T> ColumnMajorReferenceMutIterator<'a, T> {
1209    /**
1210     * Constructs a column major iterator over this matrix.
1211     */
1212    pub fn new(matrix: &mut Matrix<T>) -> ColumnMajorReferenceMutIterator<'_, T> {
1213        ColumnMajorReferenceMutIterator::from(matrix)
1214    }
1215}
1216
1217impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> ColumnMajorReferenceMutIterator<'a, T, S> {
1218    /**
1219     * Constructs a column major iterator over this source.
1220     */
1221    pub fn from(source: &mut S) -> ColumnMajorReferenceMutIterator<'_, T, S> {
1222        ColumnMajorReferenceMutIterator {
1223            column_counter: 0,
1224            columns: source.view_columns(),
1225            row_counter: 0,
1226            rows: source.view_rows(),
1227            finished: !source.index_is_valid(0, 0),
1228            matrix: source,
1229            _type: PhantomData,
1230        }
1231    }
1232
1233    /**
1234     * Constructs an iterator which also yields the row and column index of each element in
1235     * this iterator.
1236     */
1237    pub fn with_index(self) -> WithIndex<Self> {
1238        WithIndex { iterator: self }
1239    }
1240}
1241
1242impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> From<ColumnMajorReferenceMutIterator<'a, T, S>>
1243    for WithIndex<ColumnMajorReferenceMutIterator<'a, T, S>>
1244{
1245    fn from(iterator: ColumnMajorReferenceMutIterator<'a, T, S>) -> Self {
1246        iterator.with_index()
1247    }
1248}
1249
1250impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> Iterator
1251    for ColumnMajorReferenceMutIterator<'a, T, S>
1252{
1253    type Item = &'a mut T;
1254
1255    fn next(&mut self) -> Option<Self::Item> {
1256        column_major_iter(
1257            &mut self.finished,
1258            self.rows,
1259            self.columns,
1260            &mut self.row_counter,
1261            &mut self.column_counter,
1262        )
1263        .map(|(row, column)| unsafe {
1264            // Safety: We checked on creation that 0,0 is in range, and after getting
1265            // our next value we check if we hit the end of the matrix and will avoid
1266            // calling this on our next loop if we finished. Since the view size may not
1267            // change due to NoInteriorMutability and our exclusive reference this read
1268            // is in bounds.
1269            // Safety: We are not allowed to give out overlapping mutable references,
1270            // but since we will always increment the counter on every call to next()
1271            // and stop when we reach the end no references will overlap*.
1272            // The compiler doesn't know this, so transmute the lifetime for it.
1273            // *We also require the source matrix to be NoInteriorMutability to additionally
1274            // make illegal any edge cases where some extremely exotic matrix rotates its data
1275            // inside the buffer around though a shared reference while we were iterating that
1276            // could otherwise make our cursor read the same data twice.
1277            std::mem::transmute::<&mut T, &mut T>(
1278                self.matrix.get_reference_unchecked_mut(row, column),
1279            )
1280        })
1281    }
1282
1283    fn size_hint(&self) -> (usize, Option<usize>) {
1284        column_major_size_hint(
1285            self.rows,
1286            self.columns,
1287            self.row_counter,
1288            self.column_counter,
1289        )
1290    }
1291}
1292#[rustfmt::skip]
1293impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> FusedIterator for ColumnMajorReferenceMutIterator<'a, T, S> {}
1294#[rustfmt::skip]
1295impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> ExactSizeIterator for ColumnMajorReferenceMutIterator<'a, T, S> {}
1296
1297impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> Iterator
1298    for WithIndex<ColumnMajorReferenceMutIterator<'a, T, S>>
1299{
1300    type Item = ((Row, Column), &'a mut T);
1301
1302    fn next(&mut self) -> Option<Self::Item> {
1303        let (row, column) = (self.iterator.row_counter, self.iterator.column_counter);
1304        self.iterator.next().map(|x| ((row, column), x))
1305    }
1306
1307    fn size_hint(&self) -> (usize, Option<usize>) {
1308        self.iterator.size_hint()
1309    }
1310}
1311#[rustfmt::skip]
1312impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> FusedIterator for WithIndex<ColumnMajorReferenceMutIterator<'a, T, S>> {}
1313/**
1314 * Note: On earlier versions of Easy ML (<=1.9.0), the size hint given for this impl erroneously
1315 * did not return an exact size
1316 */
1317#[rustfmt::skip]
1318impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> ExactSizeIterator for WithIndex<ColumnMajorReferenceMutIterator<'a, T, S>> {}
1319
1320/**
1321 * A row major iterator over mutable references to all values in a matrix.
1322 *
1323 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
1324 * ```ignore
1325 * [
1326 *   1, 2
1327 *   3, 4
1328 * ]
1329 * ```
1330 * The elements will be iterated through as &mut 1, &mut 2, &mut 3, &mut 4
1331 */
1332#[derive(Debug)]
1333pub struct RowMajorReferenceMutIterator<'a, T, S: MatrixMut<T> + NoInteriorMutability = Matrix<T>> {
1334    matrix: &'a mut S,
1335    column_counter: Column,
1336    columns: Column,
1337    row_counter: Row,
1338    rows: Row,
1339    finished: bool,
1340    _type: PhantomData<&'a mut T>,
1341}
1342
1343impl<'a, T> RowMajorReferenceMutIterator<'a, T> {
1344    /**
1345     * Constructs a row major iterator over this matrix.
1346     */
1347    pub fn new(matrix: &mut Matrix<T>) -> RowMajorReferenceMutIterator<'_, T> {
1348        RowMajorReferenceMutIterator::from(matrix)
1349    }
1350}
1351
1352impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> RowMajorReferenceMutIterator<'a, T, S> {
1353    /**
1354     * Constructs a row major iterator over this source.
1355     */
1356    pub fn from(source: &mut S) -> RowMajorReferenceMutIterator<'_, T, S> {
1357        RowMajorReferenceMutIterator {
1358            column_counter: 0,
1359            columns: source.view_columns(),
1360            row_counter: 0,
1361            rows: source.view_rows(),
1362            finished: !source.index_is_valid(0, 0),
1363            matrix: source,
1364            _type: PhantomData,
1365        }
1366    }
1367
1368    /**
1369     * Constructs an iterator which also yields the row and column index of each element in
1370     * this iterator.
1371     */
1372    pub fn with_index(self) -> WithIndex<Self> {
1373        WithIndex { iterator: self }
1374    }
1375}
1376
1377impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> From<RowMajorReferenceMutIterator<'a, T, S>>
1378    for WithIndex<RowMajorReferenceMutIterator<'a, T, S>>
1379{
1380    fn from(iterator: RowMajorReferenceMutIterator<'a, T, S>) -> Self {
1381        iterator.with_index()
1382    }
1383}
1384
1385impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> Iterator
1386    for RowMajorReferenceMutIterator<'a, T, S>
1387{
1388    type Item = &'a mut T;
1389
1390    fn next(&mut self) -> Option<Self::Item> {
1391        row_major_iter(
1392            &mut self.finished,
1393            self.rows,
1394            self.columns,
1395            &mut self.row_counter,
1396            &mut self.column_counter,
1397        )
1398        .map(|(row, column)| unsafe {
1399            // Safety: We checked on creation that 0,0 is in range, and after getting
1400            // our next value we check if we hit the end of the matrix and will avoid
1401            // calling this on our next loop if we finished. Since the view size may not
1402            // change due to NoInteriorMutability and our exclusive reference this read
1403            // is in bounds.
1404            // then the MatrixRef implementation is required to bounds check for us.
1405            // Safety: We are not allowed to give out overlapping mutable references,
1406            // but since we will always increment the counter on every call to next()
1407            // and stop when we reach the end no references will overlap*.
1408            // The compiler doesn't know this, so transmute the lifetime for it.
1409            // *We also require the source matrix to be NoInteriorMutability to additionally
1410            // make illegal any edge cases where some extremely exotic matrix rotates its data
1411            // inside the buffer around through a shared reference while we were iterating that
1412            // could otherwise make our cursor read the same data twice.
1413            std::mem::transmute::<&mut T, &mut T>(
1414                self.matrix.get_reference_unchecked_mut(row, column),
1415            )
1416        })
1417    }
1418
1419    fn size_hint(&self) -> (usize, Option<usize>) {
1420        row_major_size_hint(
1421            self.rows,
1422            self.columns,
1423            self.row_counter,
1424            self.column_counter,
1425        )
1426    }
1427}
1428#[rustfmt::skip]
1429impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> FusedIterator for RowMajorReferenceMutIterator<'a, T, S> {}
1430#[rustfmt::skip]
1431impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> ExactSizeIterator for RowMajorReferenceMutIterator<'a, T, S> {}
1432
1433impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> Iterator
1434    for WithIndex<RowMajorReferenceMutIterator<'a, T, S>>
1435{
1436    type Item = ((Row, Column), &'a mut T);
1437
1438    fn next(&mut self) -> Option<Self::Item> {
1439        let (row, column) = (self.iterator.row_counter, self.iterator.column_counter);
1440        self.iterator.next().map(|x| ((row, column), x))
1441    }
1442
1443    fn size_hint(&self) -> (usize, Option<usize>) {
1444        self.iterator.size_hint()
1445    }
1446}
1447#[rustfmt::skip]
1448impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> FusedIterator for WithIndex<RowMajorReferenceMutIterator<'a, T, S>> {}
1449/**
1450 * Note: On earlier versions of Easy ML (<=1.9.0), the size hint given for this impl erroneously
1451 * did not return an exact size
1452 */
1453#[rustfmt::skip]
1454impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> ExactSizeIterator for WithIndex<RowMajorReferenceMutIterator<'a, T, S>> {}
1455
1456/**
1457 * A column major iterator over all values in a matrix.
1458 *
1459 * This iterator does not clone the values, it returns the actual values stored in the matrix.
1460 * There is no such method to return `T` by value from a [MatrixRef]/[MatrixMut], to do
1461 * this it [replaces](std::mem::replace) the values with dummy values. Hence it can only be
1462 * created for types that implement [Default] or [ZeroOne](crate::numeric::ZeroOne)
1463 * from [Numeric](crate::numeric) which provide a means to create dummy values.
1464 *
1465 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
1466 * ```ignore
1467 * [
1468 *   1, 2
1469 *   3, 4
1470 * ]
1471 * ```
1472 * The elements will be iterated through as 1, 3, 2, 4
1473 *
1474 * ```
1475 * use easy_ml::matrices::Matrix;
1476 *
1477 * #[derive(Debug, Default, Eq, PartialEq)]
1478 * struct NoClone(i32);
1479 *
1480 * let matrix = Matrix::from(vec![
1481 *     vec![ NoClone(1), NoClone(2) ],
1482 *     vec![ NoClone(3), NoClone(4) ]
1483 * ]);
1484 * let values = matrix.column_major_owned_iter(); // will use T::default() for dummy values
1485 * assert_eq!(vec![ NoClone(1), NoClone(3), NoClone(2), NoClone(4) ], values.collect::<Vec<NoClone>>());
1486 * ```
1487 */
1488#[derive(Debug)]
1489#[rustfmt::skip]
1490pub struct ColumnMajorOwnedIterator<T, S: MatrixMut<T> + NoInteriorMutability = Matrix<T>> {
1491    matrix: S,
1492    column_counter: Column,
1493    columns: Column,
1494    row_counter: Row,
1495    rows: Row,
1496    finished: bool,
1497    producer: fn() -> T,
1498}
1499
1500impl<T> ColumnMajorOwnedIterator<T> {
1501    /**
1502     * Constructs a column major iterator over this matrix.
1503     */
1504    pub fn new(matrix: Matrix<T>) -> ColumnMajorOwnedIterator<T>
1505    where
1506        T: Default,
1507    {
1508        ColumnMajorOwnedIterator::from(matrix)
1509    }
1510}
1511
1512impl<T, S: MatrixMut<T> + NoInteriorMutability> ColumnMajorOwnedIterator<T, S> {
1513    /**
1514     * Constructs a column major iterator over this source.
1515     */
1516    pub fn from(source: S) -> ColumnMajorOwnedIterator<T, S>
1517    where
1518        T: Default,
1519    {
1520        ColumnMajorOwnedIterator {
1521            column_counter: 0,
1522            columns: source.view_columns(),
1523            row_counter: 0,
1524            rows: source.view_rows(),
1525            finished: !source.index_is_valid(0, 0),
1526            matrix: source,
1527            producer: || T::default(),
1528        }
1529    }
1530
1531    /**
1532     * Constructs a column major iterator over this source.
1533     */
1534    pub fn from_numeric(source: S) -> ColumnMajorOwnedIterator<T, S>
1535    where
1536        T: crate::numeric::ZeroOne,
1537    {
1538        ColumnMajorOwnedIterator {
1539            column_counter: 0,
1540            columns: source.view_columns(),
1541            row_counter: 0,
1542            rows: source.view_rows(),
1543            finished: !source.index_is_valid(0, 0),
1544            matrix: source,
1545            producer: || T::zero(),
1546        }
1547    }
1548
1549    /**
1550     * Constructs an iterator which also yields the row and column index of each element in
1551     * this iterator.
1552     */
1553    pub fn with_index(self) -> WithIndex<Self> {
1554        WithIndex { iterator: self }
1555    }
1556}
1557
1558impl<T, S: MatrixMut<T> + NoInteriorMutability> From<ColumnMajorOwnedIterator<T, S>>
1559    for WithIndex<ColumnMajorOwnedIterator<T, S>>
1560{
1561    fn from(iterator: ColumnMajorOwnedIterator<T, S>) -> Self {
1562        iterator.with_index()
1563    }
1564}
1565
1566impl<T, S: MatrixMut<T> + NoInteriorMutability> Iterator for ColumnMajorOwnedIterator<T, S> {
1567    type Item = T;
1568
1569    fn next(&mut self) -> Option<Self::Item> {
1570        column_major_iter(
1571            &mut self.finished,
1572            self.rows,
1573            self.columns,
1574            &mut self.row_counter,
1575            &mut self.column_counter,
1576        )
1577        .map(|(row, column)| unsafe {
1578            // Safety: We checked on creation that 0,0 is in range, and after getting
1579            // our next value we check if we hit the end of the matrix and will avoid
1580            // calling this on our next loop if we finished. Since the view size may not
1581            // change due to NoInteriorMutability and our exclusive reference this read
1582            // is in bounds.
1583            // *We also require the source matrix to be NoInteriorMutability to additionally
1584            // make illegal any edge cases where some extremely exotic matrix rotates its data
1585            // inside the buffer around though a shared reference while we were iterating that
1586            // could otherwise make our cursor read the same data twice.
1587            let producer = self.producer;
1588            let dummy = producer();
1589            std::mem::replace(self.matrix.get_reference_unchecked_mut(row, column), dummy)
1590        })
1591    }
1592
1593    fn size_hint(&self) -> (usize, Option<usize>) {
1594        column_major_size_hint(
1595            self.rows,
1596            self.columns,
1597            self.row_counter,
1598            self.column_counter,
1599        )
1600    }
1601}
1602#[rustfmt::skip]
1603impl<T, S: MatrixMut<T> + NoInteriorMutability> FusedIterator for ColumnMajorOwnedIterator<T, S> {}
1604#[rustfmt::skip]
1605impl<T, S: MatrixMut<T> + NoInteriorMutability> ExactSizeIterator for ColumnMajorOwnedIterator<T, S> {}
1606
1607impl<T, S: MatrixMut<T> + NoInteriorMutability> Iterator
1608    for WithIndex<ColumnMajorOwnedIterator<T, S>>
1609{
1610    type Item = ((Row, Column), T);
1611
1612    fn next(&mut self) -> Option<Self::Item> {
1613        let (row, column) = (self.iterator.row_counter, self.iterator.column_counter);
1614        self.iterator.next().map(|x| ((row, column), x))
1615    }
1616
1617    fn size_hint(&self) -> (usize, Option<usize>) {
1618        self.iterator.size_hint()
1619    }
1620}
1621#[rustfmt::skip]
1622impl<T, S: MatrixMut<T> + NoInteriorMutability> FusedIterator for WithIndex<ColumnMajorOwnedIterator<T, S>> {}
1623#[rustfmt::skip]
1624impl<T, S: MatrixMut<T> + NoInteriorMutability> ExactSizeIterator for WithIndex<ColumnMajorOwnedIterator<T, S>> {}
1625
1626/**
1627 * A row major iterator over all values in a matrix.
1628 *
1629 * This iterator does not clone the values, it returns the actual values stored in the matrix.
1630 * There is no such method to return `T` by value from a [MatrixRef]/[MatrixMut], to do
1631 * this it [replaces](std::mem::replace) the values with dummy values. Hence it can only be
1632 * created for types that implement [Default] or [ZeroOne](crate::numeric::ZeroOne)
1633 * from [Numeric](crate::numeric) which provide a means to create dummy values.
1634 *
1635 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
1636 * ```ignore
1637 * [
1638 *   1, 2
1639 *   3, 4
1640 * ]
1641 * ```
1642 * The elements will be iterated through as 1, 2, 3, 4
1643 *
1644 * ```
1645 * use easy_ml::matrices::Matrix;
1646 *
1647 * #[derive(Debug, Default, Eq, PartialEq)]
1648 * struct NoClone(i32);
1649 *
1650 * let matrix = Matrix::from(vec![
1651 *     vec![ NoClone(1), NoClone(2) ],
1652 *     vec![ NoClone(3), NoClone(4) ]
1653 * ]);
1654 * let values = matrix.row_major_owned_iter(); // will use T::default() for dummy values
1655 * assert_eq!(vec![ NoClone(1), NoClone(2), NoClone(3), NoClone(4) ], values.collect::<Vec<NoClone>>());
1656 * ```
1657 */
1658#[derive(Debug)]
1659pub struct RowMajorOwnedIterator<T, S: MatrixMut<T> + NoInteriorMutability = Matrix<T>> {
1660    matrix: S,
1661    column_counter: Column,
1662    columns: Column,
1663    row_counter: Row,
1664    rows: Row,
1665    finished: bool,
1666    producer: fn() -> T,
1667}
1668
1669impl<T> RowMajorOwnedIterator<T> {
1670    /**
1671     * Constructs a row major iterator over this matrix.
1672     */
1673    pub fn new(matrix: Matrix<T>) -> RowMajorOwnedIterator<T>
1674    where
1675        T: Default,
1676    {
1677        RowMajorOwnedIterator::from(matrix)
1678    }
1679}
1680
1681impl<T, S: MatrixMut<T> + NoInteriorMutability> RowMajorOwnedIterator<T, S> {
1682    /**
1683     * Constructs a row major iterator over this source.
1684     */
1685    pub fn from(source: S) -> RowMajorOwnedIterator<T, S>
1686    where
1687        T: Default,
1688    {
1689        RowMajorOwnedIterator {
1690            column_counter: 0,
1691            columns: source.view_columns(),
1692            row_counter: 0,
1693            rows: source.view_rows(),
1694            finished: !source.index_is_valid(0, 0),
1695            matrix: source,
1696            producer: || T::default(),
1697        }
1698    }
1699
1700    /**
1701     * Constructs a row major iterator over this source.
1702     */
1703    pub fn from_numeric(source: S) -> RowMajorOwnedIterator<T, S>
1704    where
1705        T: crate::numeric::ZeroOne,
1706    {
1707        RowMajorOwnedIterator {
1708            column_counter: 0,
1709            columns: source.view_columns(),
1710            row_counter: 0,
1711            rows: source.view_rows(),
1712            finished: !source.index_is_valid(0, 0),
1713            matrix: source,
1714            producer: || T::zero(),
1715        }
1716    }
1717
1718    /**
1719     * Constructs an iterator which also yields the row and column index of each element in
1720     * this iterator.
1721     */
1722    pub fn with_index(self) -> WithIndex<Self> {
1723        WithIndex { iterator: self }
1724    }
1725}
1726
1727impl<T, S: MatrixMut<T> + NoInteriorMutability> From<RowMajorOwnedIterator<T, S>>
1728    for WithIndex<RowMajorOwnedIterator<T, S>>
1729{
1730    fn from(iterator: RowMajorOwnedIterator<T, S>) -> Self {
1731        iterator.with_index()
1732    }
1733}
1734
1735impl<T, S: MatrixMut<T> + NoInteriorMutability> Iterator for RowMajorOwnedIterator<T, S> {
1736    type Item = T;
1737
1738    fn next(&mut self) -> Option<Self::Item> {
1739        row_major_iter(
1740            &mut self.finished,
1741            self.rows,
1742            self.columns,
1743            &mut self.row_counter,
1744            &mut self.column_counter,
1745        )
1746        .map(|(row, column)| unsafe {
1747            // Safety: We checked on creation that 0,0 is in range, and after getting
1748            // our next value we check if we hit the end of the matrix and will avoid
1749            // calling this on our next loop if we finished. Since the view size may not
1750            // change due to NoInteriorMutability and our exclusive reference this read
1751            // is in bounds.
1752            // *We also require the source matrix to be NoInteriorMutability to additionally
1753            // make illegal any edge cases where some extremely exotic matrix rotates its data
1754            // inside the buffer around through a shared reference while we were iterating that
1755            // could otherwise make our cursor read the same data twice.
1756            let producer = self.producer;
1757            let dummy = producer();
1758            std::mem::replace(self.matrix.get_reference_unchecked_mut(row, column), dummy)
1759        })
1760    }
1761
1762    fn size_hint(&self) -> (usize, Option<usize>) {
1763        row_major_size_hint(
1764            self.rows,
1765            self.columns,
1766            self.row_counter,
1767            self.column_counter,
1768        )
1769    }
1770}
1771#[rustfmt::skip]
1772impl<T, S: MatrixMut<T> + NoInteriorMutability> FusedIterator for RowMajorOwnedIterator<T, S> {}
1773#[rustfmt::skip]
1774impl<T, S: MatrixMut<T> + NoInteriorMutability> ExactSizeIterator for RowMajorOwnedIterator<T, S> {}
1775
1776impl<T, S: MatrixMut<T> + NoInteriorMutability> Iterator
1777    for WithIndex<RowMajorOwnedIterator<T, S>>
1778{
1779    type Item = ((Row, Column), T);
1780
1781    fn next(&mut self) -> Option<Self::Item> {
1782        let (row, column) = (self.iterator.row_counter, self.iterator.column_counter);
1783        self.iterator.next().map(|x| ((row, column), x))
1784    }
1785
1786    fn size_hint(&self) -> (usize, Option<usize>) {
1787        self.iterator.size_hint()
1788    }
1789}
1790#[rustfmt::skip]
1791impl<T, S: MatrixMut<T> + NoInteriorMutability> FusedIterator for WithIndex<RowMajorOwnedIterator<T, S>> {}
1792#[rustfmt::skip]
1793impl<T, S: MatrixMut<T> + NoInteriorMutability> ExactSizeIterator for WithIndex<RowMajorOwnedIterator<T, S>> {}
1794
1795/**
1796 * An iterator over mutable references to the main diagonal in a matrix.
1797 *
1798 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
1799 * ```ignore
1800 * [
1801 *   1, 2
1802 *   3, 4
1803 * ]
1804 * ```
1805 * The elements will be iterated through as &mut 1, &mut 4
1806 *
1807 * If the matrix is not square this will stop at whichever row/colum is shorter.
1808 */
1809#[derive(Debug)]
1810pub struct DiagonalReferenceMutIterator<'a, T, S: MatrixMut<T> + NoInteriorMutability = Matrix<T>> {
1811    matrix: &'a mut S,
1812    range: Range<usize>,
1813    _type: PhantomData<&'a mut T>,
1814}
1815
1816impl<'a, T> DiagonalReferenceMutIterator<'a, T> {
1817    /**
1818     * Constructs a diagonal iterator over this matrix.
1819     */
1820    pub fn new(matrix: &mut Matrix<T>) -> DiagonalReferenceMutIterator<'_, T> {
1821        DiagonalReferenceMutIterator::from(matrix)
1822    }
1823}
1824
1825impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> DiagonalReferenceMutIterator<'a, T, S> {
1826    /**
1827     * Constructs a diagonal iterator over this source.
1828     */
1829    pub fn from(source: &mut S) -> DiagonalReferenceMutIterator<'_, T, S> {
1830        DiagonalReferenceMutIterator {
1831            range: 0..std::cmp::min(source.view_rows(), source.view_columns()),
1832            matrix: source,
1833            _type: PhantomData,
1834        }
1835    }
1836}
1837
1838impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> Iterator
1839    for DiagonalReferenceMutIterator<'a, T, S>
1840{
1841    type Item = &'a mut T;
1842
1843    fn next(&mut self) -> Option<Self::Item> {
1844        match self.range.next() {
1845            None => None,
1846            Some(i) => unsafe {
1847                // Safety: We initialised the range to 0..min(rows/columns), hence this read is
1848                // in bounds because the source is NoInteriorMutability and we hold an exclusive
1849                // reference to it, so the valid bounds cannot change in size.
1850                // Safety: We are not allowed to give out overlapping mutable references,
1851                // but since we will always increment the counter on every call to next()
1852                // and stop when we reach the end no references will overlap*.
1853                // The compiler doesn't know this, so transmute the lifetime for it.
1854                // *We also require the source matrix to be NoInteriorMutability to additionally
1855                // make illegal any edge cases where some extremely exotic matrix rotates its data
1856                // inside the buffer around through a shared reference while we were iterating that
1857                // could otherwise make our cursor read the same data twice.
1858                Some(std::mem::transmute::<&mut T, &mut T>(
1859                    self.matrix.get_reference_unchecked_mut(i, i),
1860                ))
1861            },
1862        }
1863    }
1864
1865    fn size_hint(&self) -> (usize, Option<usize>) {
1866        self.range.size_hint()
1867    }
1868}
1869#[rustfmt::skip]
1870impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> FusedIterator for DiagonalReferenceMutIterator<'a, T, S> {}
1871#[rustfmt::skip]
1872impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> ExactSizeIterator for DiagonalReferenceMutIterator<'a, T, S> {}
1873
1874/**
1875 * An iterator over mutable references to a column in a matrix.
1876 *
1877 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
1878 * ```ignore
1879 * [
1880 *   1, 2
1881 *   3, 4
1882 * ]
1883 * ```
1884 * Depending on the row iterator you want to obtain,
1885 * can either iterate through &mut 1, &mut 3 or &mut 2, &mut 4.
1886 */
1887#[derive(Debug)]
1888pub struct ColumnReferenceMutIterator<'a, T, S: MatrixMut<T> + NoInteriorMutability = Matrix<T>> {
1889    matrix: &'a mut S,
1890    column: Column,
1891    range: Range<Row>,
1892    _type: PhantomData<&'a mut T>,
1893}
1894
1895impl<'a, T> ColumnReferenceMutIterator<'a, T> {
1896    /**
1897     * Constructs a column iterator over this matrix.
1898     *
1899     * # Panics
1900     *
1901     * Panics if the column does not exist in this matrix.
1902     */
1903    #[track_caller]
1904    pub fn new(matrix: &mut Matrix<T>, column: Column) -> ColumnReferenceMutIterator<'_, T> {
1905        ColumnReferenceMutIterator::from(matrix, column)
1906    }
1907}
1908
1909impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> ColumnReferenceMutIterator<'a, T, S> {
1910    /**
1911     * Constructs a column iterator over this source.
1912     *
1913     * # Panics
1914     *
1915     * Panics if the column does not exist in this source.
1916     */
1917    #[track_caller]
1918    pub fn from(source: &mut S, column: Column) -> ColumnReferenceMutIterator<'_, T, S> {
1919        assert!(
1920            source.index_is_valid(0, column),
1921            "Expected ({},{}) to be in range",
1922            0,
1923            column
1924        );
1925        ColumnReferenceMutIterator {
1926            range: 0..source.view_rows(),
1927            matrix: source,
1928            column,
1929            _type: PhantomData,
1930        }
1931    }
1932}
1933
1934impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> Iterator
1935    for ColumnReferenceMutIterator<'a, T, S>
1936{
1937    type Item = &'a mut T;
1938
1939    fn next(&mut self) -> Option<Self::Item> {
1940        match self.range.next() {
1941            None => None,
1942            Some(row) => unsafe {
1943                // Safety: We initialised the range to 0..matrix.view_rows(), and
1944                // checked we can read from this column at creation, hence this read is
1945                // in bounds because the source is NoInteriorMutability and we hold an exclusive
1946                // reference to it, so the valid bounds cannot change in size.
1947                // Safety: We are not allowed to give out overlapping mutable references,
1948                // but since we will always increment the counter on every call to next()
1949                // and stop when we reach the end no references will overlap*.
1950                // The compiler doesn't know this, so transmute the lifetime for it.
1951                // *We also require the source matrix to be NoInteriorMutability to additionally
1952                // make illegal any edge cases where some extremely exotic matrix rotates its data
1953                // inside the buffer around through a shared reference while we were iterating that
1954                // could otherwise make our cursor read the same data twice.
1955                Some(std::mem::transmute::<&mut T, &mut T>(
1956                    self.matrix.get_reference_unchecked_mut(row, self.column),
1957                ))
1958            },
1959        }
1960    }
1961
1962    fn size_hint(&self) -> (usize, Option<usize>) {
1963        self.range.size_hint()
1964    }
1965}
1966#[rustfmt::skip]
1967impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> FusedIterator for ColumnReferenceMutIterator<'a, T, S> {}
1968#[rustfmt::skip]
1969impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> ExactSizeIterator for ColumnReferenceMutIterator<'a, T, S> {}
1970
1971/**
1972 * An iterator over mutable references to a row in a matrix.
1973 *
1974 * For a 2x2 matrix such as `[ 1, 2; 3, 4]`: ie
1975 * ```ignore
1976 * [
1977 *   1, 2
1978 *   3, 4
1979 * ]
1980 * ```
1981 * Depending on the row iterator you want to obtain,
1982 * can either iterate through &mut 1, &mut 2 or &mut 3, &mut 4.
1983 */
1984#[derive(Debug)]
1985pub struct RowReferenceMutIterator<'a, T, S: MatrixMut<T> + NoInteriorMutability = Matrix<T>> {
1986    matrix: &'a mut S,
1987    row: Row,
1988    range: Range<Column>,
1989    _type: PhantomData<&'a mut T>,
1990}
1991
1992impl<'a, T> RowReferenceMutIterator<'a, T> {
1993    /**
1994     * Constructs a row iterator over this matrix.
1995     *
1996     * # Panics
1997     *
1998     * Panics if the row does not exist in this matrix.
1999     */
2000    #[track_caller]
2001    pub fn new(matrix: &mut Matrix<T>, row: Row) -> RowReferenceMutIterator<'_, T> {
2002        RowReferenceMutIterator::from(matrix, row)
2003    }
2004}
2005
2006impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> RowReferenceMutIterator<'a, T, S> {
2007    /**
2008     * Constructs a row iterator over this source.
2009     *
2010     * # Panics
2011     *
2012     * Panics if the row does not exist in this source.
2013     */
2014    #[track_caller]
2015    pub fn from(source: &mut S, row: Row) -> RowReferenceMutIterator<'_, T, S> {
2016        assert!(
2017            source.index_is_valid(row, 0),
2018            "Expected ({},{}) to be in range",
2019            row,
2020            0
2021        );
2022        RowReferenceMutIterator {
2023            range: 0..source.view_columns(),
2024            matrix: source,
2025            row,
2026            _type: PhantomData,
2027        }
2028    }
2029}
2030
2031impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> Iterator for RowReferenceMutIterator<'a, T, S> {
2032    type Item = &'a mut T;
2033
2034    fn next(&mut self) -> Option<Self::Item> {
2035        match self.range.next() {
2036            None => None,
2037            Some(column) => unsafe {
2038                // Safety: We initialised the range to 0..matrix.view_columns(), and
2039                // checked we can read from this row at creation, hence this read is
2040                // in bounds because the source is NoInteriorMutability and we hold an exclusive
2041                // reference to it, so the valid bounds cannot change in size.
2042                // Safety: We are not allowed to give out overlapping mutable references,
2043                // but since we will always increment the counter on every call to next()
2044                // and stop when we reach the end no references will overlap*.
2045                // The compiler doesn't know this, so transmute the lifetime for it.
2046                // *We also require the source matrix to be NoInteriorMutability to additionally
2047                // make illegal any edge cases where some extremely exotic matrix rotates its data
2048                // inside the buffer around through a shared reference while we were iterating that
2049                // could otherwise make our cursor read the same data twice.
2050                Some(std::mem::transmute::<&mut T, &mut T>(
2051                    self.matrix.get_reference_unchecked_mut(self.row, column),
2052                ))
2053            },
2054        }
2055    }
2056
2057    fn size_hint(&self) -> (usize, Option<usize>) {
2058        self.range.size_hint()
2059    }
2060}
2061#[rustfmt::skip]
2062impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> FusedIterator for RowReferenceMutIterator<'a, T, S> {}
2063#[rustfmt::skip]
2064impl<'a, T, S: MatrixMut<T> + NoInteriorMutability> ExactSizeIterator for RowReferenceMutIterator<'a, T, S> {}