1use std::fmt::{Formatter, Debug};
2use std::ops::{Deref, Range};
3use std::marker::PhantomData;
4use std::ptr::{addr_of_mut, NonNull};
5
6#[cfg(feature = "ndarray")]
7use ndarray::{ArrayBase, DataMut, Ix2};
8
9use crate::seq::{VectorView, VectorViewMut, SwappableVectorViewMut};
10
11pub unsafe trait AsPointerToSlice<T> {
30
31    unsafe fn get_pointer(self_: NonNull<Self>) -> NonNull<T>;
48}
49
50unsafe impl<T> AsPointerToSlice<T> for Vec<T> {
51
52    unsafe fn get_pointer(self_: NonNull<Self>) -> NonNull<T> {
53        unsafe {
57            NonNull::new((*self_.as_ptr()).as_mut_ptr()).unwrap()
58        }
59    }
60}
61
62#[repr(transparent)]
69#[derive(Clone, Copy, PartialEq, Eq)]
70pub struct DerefArray<T, const SIZE: usize> {
71    pub data: [T; SIZE]
73}
74
75impl<T: std::fmt::Debug, const SIZE: usize> std::fmt::Debug for DerefArray<T, SIZE> {
76
77    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78        self.data.fmt(f)
79    }
80}
81
82impl<T, const SIZE: usize> From<[T; SIZE]> for DerefArray<T, SIZE> {
83
84    fn from(value: [T; SIZE]) -> Self {
85        Self { data: value }
86    }
87}
88
89impl<'a, T, const SIZE: usize> From<&'a [T; SIZE]> for &'a DerefArray<T, SIZE> {
90
91    fn from(value: &'a [T; SIZE]) -> Self {
92        unsafe { std::mem::transmute(value) }
93    }
94}
95
96impl<'a, T, const SIZE: usize> From<&'a mut [T; SIZE]> for &'a mut DerefArray<T, SIZE> {
97
98    fn from(value: &'a mut [T; SIZE]) -> Self {
99        unsafe { std::mem::transmute(value) }
100    }
101}
102
103impl<T, const SIZE: usize> Deref for DerefArray<T, SIZE> {
104
105    type Target = [T];
106
107    fn deref(&self) -> &Self::Target {
108        &self.data[..]
109    }
110}
111
112unsafe impl<T, const SIZE: usize> AsPointerToSlice<T> for DerefArray<T, SIZE> {
113
114    unsafe fn get_pointer(self_: NonNull<Self>) -> NonNull<T> {
115        unsafe { 
116            let self_ptr = self_.as_ptr();
117            let data_ptr = addr_of_mut!((*self_ptr).data);
118            NonNull::new((*data_ptr).as_mut_ptr()).unwrap()
119        }
120    }
121}
122
123#[repr(transparent)]
129pub struct AsFirstElement<T>(T);
130
131unsafe impl<'a, T> AsPointerToSlice<T> for AsFirstElement<T> {
132
133    unsafe fn get_pointer(self_: NonNull<Self>) -> NonNull<T> {
134        unsafe { std::mem::transmute(self_) }
135    }
136}
137
138#[stability::unstable(feature = "enable")]
170pub struct SubmatrixRaw<V, T>
171    where V: AsPointerToSlice<T>
172{
173    entry: PhantomData<*mut T>,
174    rows: NonNull<V>,
175    row_count: usize,
176    row_step: isize,
177    col_start: usize,
178    col_count: usize
179}
180
181unsafe impl<V, T> Send for SubmatrixRaw<V, T> 
188    where V: AsPointerToSlice<T> + Sync, T: Sync
189{}
190
191unsafe impl<V, T> Sync for SubmatrixRaw<V, T> 
192    where V: AsPointerToSlice<T> + Sync, T: Sync
193{}
194
195impl<V, T> Clone for SubmatrixRaw<V, T> 
196    where V: AsPointerToSlice<T>
197{
198    fn clone(&self) -> Self {
199        *self
200    }
201}
202
203impl<V, T> Copy for SubmatrixRaw<V, T> 
204    where V: AsPointerToSlice<T>
205{}
206
207impl<V, T> SubmatrixRaw<V, T> 
208    where V: AsPointerToSlice<T>
209{
210    #[stability::unstable(feature = "enable")]
224    pub unsafe fn new(rows: NonNull<V>, row_count: usize, row_step: isize, cols_start: usize, col_count: usize) -> Self {
225        Self {
226            entry: PhantomData,
227            row_count: row_count,
228            row_step: row_step,
229            rows: rows,
230            col_start: cols_start,
231            col_count
232        }
233    }
234
235    #[stability::unstable(feature = "enable")]
236    pub fn restrict_rows(mut self, rows: Range<usize>) -> Self {
237        assert!(rows.start <= rows.end);
238        assert!(rows.end <= self.row_count);
239        unsafe {
245            self.row_count = rows.end - rows.start;
246            self.rows = self.rows.offset(rows.start as isize * self.row_step);
247        }
248        self
249    }
250
251    #[stability::unstable(feature = "enable")]
252    pub fn restrict_cols(mut self, cols: Range<usize>) -> Self {
253        assert!(cols.end <= self.col_count);
254        self.col_count = cols.end - cols.start;
255        self.col_start += cols.start;
256        self
257    }
258
259    #[stability::unstable(feature = "enable")]
264    pub fn row_at(&self, row: usize) -> NonNull<[T]> {
265        assert!(row < self.row_count);
266        let row_ref = unsafe {
269            V::get_pointer(self.rows.offset(row as isize * self.row_step))
270        };
271        unsafe {
273            NonNull::slice_from_raw_parts(row_ref.offset(self.col_start as isize), self.col_count)
274        }
275    }
276
277    #[stability::unstable(feature = "enable")]
282    pub fn entry_at(&self, row: usize, col: usize) -> NonNull<T> {
283        assert!(row < self.row_count, "Row index {} out of range 0..{}", row, self.row_count);
284        assert!(col < self.col_count, "Col index {} out of range 0..{}", col, self.col_count);
285        let row_ref = unsafe {
288            V::get_pointer(self.rows.offset(row as isize * self.row_step))
289        };
290        unsafe {
292            row_ref.offset(self.col_start as isize + col as isize)
293        }
294    }
295}
296
297pub struct Column<'a, V, T>
301    where V: AsPointerToSlice<T>
302{
303    entry: PhantomData<&'a T>,
304    raw_data: SubmatrixRaw<V, T>
305}
306
307impl<'a, V, T> Column<'a, V, T>
308    where V: AsPointerToSlice<T>
309{
310    unsafe fn new(raw_data: SubmatrixRaw<V, T>) -> Self {
322        assert!(raw_data.col_count == 1);
323        Self {
324            entry: PhantomData,
325            raw_data: raw_data
326        }
327    }
328}
329
330impl<'a, V, T: Debug> Debug for Column<'a, V, T>
331    where V: AsPointerToSlice<T>
332{
333    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
334        let mut output = f.debug_list();
335        for x in self.as_iter() {
336            _ = output.entry(x);
337        }
338        output.finish()
339    }
340}
341
342impl<'a, V, T> Clone for Column<'a, V, T>
343    where V: AsPointerToSlice<T>
344{
345    fn clone(&self) -> Self {
346        *self
347    }
348}
349
350impl<'a, V, T> Copy for Column<'a, V, T>
351    where V: AsPointerToSlice<T>
352{}
353
354impl<'a, V, T> VectorView<T> for Column<'a, V, T>
355    where V: AsPointerToSlice<T>
356{
357    fn len(&self) -> usize {
358        self.raw_data.row_count
359    }
360
361    fn at(&self, i: usize) -> &T {
362        unsafe {
364            self.raw_data.entry_at(i, 0).as_ref()
365        }
366    }
367}
368
369pub struct ColumnMut<'a, V, T>
376    where V: AsPointerToSlice<T>
377{
378    entry: PhantomData<&'a mut T>,
379    raw_data: SubmatrixRaw<V, T>
380}
381
382impl<'a, V, T: Debug> Debug for ColumnMut<'a, V, T>
383    where V: AsPointerToSlice<T>
384{
385    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
386        self.as_const().fmt(f)
387    }
388}
389
390impl<'a, V, T> ColumnMut<'a, V, T>
391    where V: AsPointerToSlice<T>
392{
393    unsafe fn new(raw_data: SubmatrixRaw<V, T>) -> Self {
406        assert!(raw_data.col_count == 1);
407        Self {
408            entry: PhantomData,
409            raw_data: raw_data
410        }
411    }
412    
413    pub fn reborrow<'b>(&'b mut self) -> ColumnMut<'b, V, T> {
419        ColumnMut {
420            entry: PhantomData,
421            raw_data: self.raw_data
422        }
423    }
424
425    pub fn two_entries<'b>(&'b mut self, i: usize, j: usize) -> (&'b mut T, &'b mut T) {
433        assert!(i != j);
434        unsafe {
436            (self.raw_data.entry_at(i, 0).as_mut(), self.raw_data.entry_at(j, 0).as_mut())
437        }
438    }
439    
440    pub fn as_const<'b>(&'b self) -> Column<'b, V, T> {
444        Column {
445            entry: PhantomData,
446            raw_data: self.raw_data
447        }
448    }
449}
450
451unsafe impl<'a, V, T> Send for ColumnMut<'a, V, T>
452    where V: AsPointerToSlice<T> + Sync, T: Send
453{}
454
455impl<'a, V, T> VectorView<T> for ColumnMut<'a, V, T>
456    where V: AsPointerToSlice<T>
457{
458    fn len(&self) -> usize {
459        self.raw_data.row_count
460    }
461
462    fn at(&self, i: usize) -> &T {
463        unsafe {
465            self.raw_data.entry_at(i, 0).as_ref()
466        }
467    }
468}
469
470pub struct ColumnMutIter<'a, V, T> 
475    where V: AsPointerToSlice<T>
476{
477    column_mut: ColumnMut<'a, V, T>
478}
479
480impl<'a, V, T> Iterator for ColumnMutIter<'a, V, T>
481    where V: AsPointerToSlice<T>
482{
483    type Item = &'a mut T;
484
485    fn next(&mut self) -> Option<Self::Item> {
486        if self.column_mut.raw_data.row_count > 0 {
487            let mut result = self.column_mut.raw_data.entry_at(0, 0);
488            self.column_mut.raw_data = self.column_mut.raw_data.restrict_rows(1..self.column_mut.raw_data.row_count);
489            unsafe {
491                Some(result.as_mut())
492            }
493        } else {
494            None
495        }
496    }
497}
498
499impl<'a, V, T> IntoIterator for ColumnMut<'a, V, T>
500    where V: AsPointerToSlice<T>
501{
502    type Item = &'a mut T;
503    type IntoIter = ColumnMutIter<'a, V, T>;
504
505    fn into_iter(self) -> ColumnMutIter<'a, V, T> {
506        ColumnMutIter { column_mut: self }
507    }
508}
509
510impl<'a, V, T> VectorViewMut<T> for ColumnMut<'a, V, T>
511    where V: AsPointerToSlice<T>
512{
513    fn at_mut<'b>(&'b mut self, i: usize) -> &'b mut T {
514        unsafe {
516            self.raw_data.entry_at(i, 0).as_mut()
517        }
518    }
519}
520
521impl<'a, V, T> SwappableVectorViewMut<T> for ColumnMut<'a, V, T>
522    where V: AsPointerToSlice<T>
523{
524    fn swap(&mut self, i: usize, j: usize) {
525        if i != j {
526            unsafe {
530                std::mem::swap(self.raw_data.entry_at(i, 0).as_mut(), self.raw_data.entry_at(j, 0).as_mut());
531            }
532        }
533    }
534}
535
536pub struct Submatrix<'a, V, T>
548    where V: 'a + AsPointerToSlice<T>
549{
550    entry: PhantomData<&'a T>,
551    raw_data: SubmatrixRaw<V, T>
552}
553
554impl<'a, V, T> Submatrix<'a, V, T>
555    where V: 'a + AsPointerToSlice<T>
556{
557    pub fn submatrix(self, rows: Range<usize>, cols: Range<usize>) -> Self {
562        self.restrict_rows(rows).restrict_cols(cols)
563    }
564
565    pub fn restrict_rows(self, rows: Range<usize>) -> Self {
569        Self {
570            entry: PhantomData,
571            raw_data: self.raw_data.restrict_rows(rows)
572        }
573    }
574
575    pub fn into_at(self, i: usize, j: usize) -> &'a T {
583        &self.into_row_at(i)[j]
584    }
585    
586    pub fn at<'b>(&'b self, i: usize, j: usize) -> &'b T {
590        &self.row_at(i)[j]
591    }
592
593    pub fn restrict_cols(self, cols: Range<usize>) -> Self {
597        Self {
598            entry: PhantomData,
599            raw_data: self.raw_data.restrict_cols(cols)
600        }
601    }
602
603    pub fn row_iter(self) -> impl 'a + Clone + ExactSizeIterator<Item = &'a [T]> {
607        (0..self.raw_data.row_count).map(move |i| 
608        unsafe {
610            self.raw_data.row_at(i).as_ref()
611        })
612    }
613
614    pub fn col_iter(self) -> impl 'a + Clone + ExactSizeIterator<Item = Column<'a, V, T>> {
618        (0..self.raw_data.col_count).map(move |j| {
619            debug_assert!(j < self.raw_data.col_count);
620            let mut result_raw = self.raw_data;
621            result_raw.col_start += j;
622            result_raw.col_count = 1;
623            unsafe {
625                return Column::new(result_raw);
626            }
627        })
628    }
629
630    pub fn into_row_at(self, i: usize) -> &'a [T] {
638        unsafe {
640            self.raw_data.row_at(i).as_ref()
641        }
642    }
643
644    pub fn row_at<'b>(&'b self, i: usize) -> &'b [T] {
648        unsafe {
650            self.raw_data.row_at(i).as_ref()
651        }
652    }
653
654    pub fn into_col_at(self, j: usize) -> Column<'a, V, T> {
662        assert!(j < self.raw_data.col_count);
663        let mut result_raw = self.raw_data;
664        result_raw.col_start += j;
665        result_raw.col_count = 1;
666        unsafe {
668            return Column::new(result_raw);
669        }
670    }
671
672    pub fn col_at<'b>(&'b self, j: usize) -> Column<'b, V, T> {
676        assert!(j < self.raw_data.col_count);
677        let mut result_raw = self.raw_data;
678        result_raw.col_start += j;
679        result_raw.col_count = 1;
680        unsafe {
682            return Column::new(result_raw);
683        }
684    }
685
686    pub fn col_count(&self) -> usize {
690        self.raw_data.col_count
691    }
692
693    pub fn row_count(&self) -> usize {
697        self.raw_data.row_count
698    }
699}
700
701impl<'a, V, T: Debug> Debug for Submatrix<'a, V, T>
702    where V: 'a + AsPointerToSlice<T>
703{
704    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
705        let mut output = f.debug_list();
706        for row in self.row_iter() {
707            _ = output.entry(&row);
708        }
709        output.finish()
710    }
711}
712
713impl<'a, V, T> Clone for Submatrix<'a, V, T>
714    where V: 'a + AsPointerToSlice<T>
715{
716    fn clone(&self) -> Self {
717        *self
718    }
719}
720
721impl<'a, V, T> Copy for Submatrix<'a, V, T>
722    where V: 'a + AsPointerToSlice<T>
723{}
724
725pub struct SubmatrixMut<'a, V, T>
735    where V: 'a + AsPointerToSlice<T>
736{
737    entry: PhantomData<&'a mut T>,
738    raw_data: SubmatrixRaw<V, T>
739}
740
741impl<'a, V, T> SubmatrixMut<'a, V, T>
742    where V: 'a + AsPointerToSlice<T>
743{
744    pub fn submatrix(self, rows: Range<usize>, cols: Range<usize>) -> Self {
749        self.restrict_rows(rows).restrict_cols(cols)
750    }
751
752    pub fn restrict_rows(self, rows: Range<usize>) -> Self {
756        Self {
757            entry: PhantomData,
758            raw_data: self.raw_data.restrict_rows(rows)
759        }
760    }
761
762    pub fn restrict_cols(self, cols: Range<usize>) -> Self {
766        Self {
767            entry: PhantomData,
768            raw_data: self.raw_data.restrict_cols(cols)
769        }
770    }
771
772    pub fn split_rows(self, fst_rows: Range<usize>, snd_rows: Range<usize>) -> (Self, Self) {
778        assert!(fst_rows.end <= snd_rows.start || snd_rows.end <= fst_rows.start);
779        (
780            Self {
781                entry: PhantomData,
782                raw_data: self.raw_data.restrict_rows(fst_rows)
783            },
784            Self {
785                entry: PhantomData,
786                raw_data: self.raw_data.restrict_rows(snd_rows)
787            },
788        )
789    }
790
791    pub fn split_cols(self, fst_cols: Range<usize>, snd_cols: Range<usize>) -> (Self, Self) {
797        assert!(fst_cols.end <= snd_cols.start || snd_cols.end <= fst_cols.start);
798        (
799            Self {
800                entry: PhantomData,
801                raw_data: self.raw_data.restrict_cols(fst_cols)
802            },
803            Self {
804                entry: PhantomData,
805                raw_data: self.raw_data.restrict_cols(snd_cols)
806            },
807        )
808    }
809
810    pub fn row_iter(self) -> impl 'a + ExactSizeIterator<Item = &'a mut [T]> {
814        (0..self.raw_data.row_count).map(move |i| 
815        unsafe {
817            self.raw_data.row_at(i).as_mut()
818        })
819    }
820
821    pub fn col_iter(self) -> impl 'a + ExactSizeIterator<Item = ColumnMut<'a, V, T>> {
825        (0..self.raw_data.col_count).map(move |j| {
826            let mut result_raw = self.raw_data;
827            result_raw.col_start += j;
828            result_raw.col_count = 1;
829            unsafe {
831                return ColumnMut::new(result_raw);
832            }
833        })
834    }
835
836    pub fn into_at_mut(self, i: usize, j: usize) -> &'a mut T {
844        &mut self.into_row_mut_at(i)[j]
845    }
846
847    pub fn at_mut<'b>(&'b mut self, i: usize, j: usize) -> &'b mut T {
851        &mut self.row_mut_at(i)[j]
852    }
853
854    pub fn at<'b>(&'b self, i: usize, j: usize) -> &'b T {
858        self.as_const().into_at(i, j)
859    }
860
861    pub fn row_at<'b>(&'b self, i: usize) -> &'b [T] {
865        self.as_const().into_row_at(i)
866    }
867
868    pub fn into_row_mut_at(self, i: usize) -> &'a mut [T] {
876        unsafe {
878            self.raw_data.row_at(i).as_mut()
879        }
880    }
881
882    pub fn row_mut_at<'b>(&'b mut self, i: usize) -> &'b mut [T] {
886        self.reborrow().into_row_mut_at(i)
887    }
888
889    pub fn col_at<'b>(&'b self, j: usize) -> Column<'b, V, T> {
893        self.as_const().into_col_at(j)
894    }
895
896    pub fn col_mut_at<'b>(&'b mut self, j: usize) -> ColumnMut<'b, V, T> {
900        assert!(j < self.raw_data.col_count);
901        let mut result_raw = self.raw_data;
902        result_raw.col_start += j;
903        result_raw.col_count = 1;
904        unsafe {
906            return ColumnMut::new(result_raw);
907        }
908    }
909
910    pub fn reborrow<'b>(&'b mut self) -> SubmatrixMut<'b, V, T> {
916        SubmatrixMut {
917            entry: PhantomData,
918            raw_data: self.raw_data
919        }
920    }
921
922    pub fn as_const<'b>(&'b self) -> Submatrix<'b, V, T> {
926        Submatrix {
927            entry: PhantomData,
928            raw_data: self.raw_data
929        }
930    }
931
932    pub fn col_count(&self) -> usize {
936        self.raw_data.col_count
937    }
938
939    pub fn row_count(&self) -> usize {
943        self.raw_data.row_count
944    }
945}
946
947impl<'a, V, T: Debug> Debug for SubmatrixMut<'a, V, T>
948    where V: 'a + AsPointerToSlice<T>
949{
950    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
951        self.as_const().fmt(f)
952    }
953}
954
955impl<'a, T> SubmatrixMut<'a, AsFirstElement<T>, T> {
956
957    pub fn from_1d(data: &'a mut [T], row_count: usize, col_count: usize) -> Self {
963        assert_eq!(row_count * col_count, data.len());
964        unsafe {
965            Self {
966                entry: PhantomData,
967                raw_data: SubmatrixRaw::new(std::mem::transmute(NonNull::new(data.as_mut_ptr()).unwrap_unchecked()), row_count, col_count as isize, 0, col_count)
968            }
969        }
970    }
971
972    #[doc(cfg(feature = "ndarray"))]
973    #[cfg(feature = "ndarray")]
974    pub fn from_ndarray<S>(data: &'a mut ArrayBase<S, Ix2>) -> Self
975        where S: DataMut<Elem = T>
976    {
977        assert!(data.is_standard_layout());
978        let (nrows, ncols) = (data.nrows(), data.ncols());
979        return Self::new(data.as_slice_mut().unwrap(), nrows, ncols);
980    }
981}
982
983impl<'a, V: AsPointerToSlice<T> + Deref<Target = [T]>, T> SubmatrixMut<'a, V, T> {
984
985    pub fn from_2d(data: &'a mut [V]) -> Self {
990        assert!(data.len() > 0);
991        let row_count = data.len();
992        let col_count = data[0].len();
993        for row in data.iter() {
994            assert_eq!(col_count, row.len());
995        }
996        unsafe {
997            Self {
998                entry: PhantomData,
999                raw_data: SubmatrixRaw::new(NonNull::new(data.as_mut_ptr() as *mut _).unwrap_unchecked(), row_count, 1, 0, col_count)
1000            }
1001        }
1002    }
1003}
1004
1005impl<'a, T> Submatrix<'a, AsFirstElement<T>, T> {
1006
1007    pub fn from_1d(data: &'a [T], row_count: usize, col_count: usize) -> Self {
1013        assert_eq!(row_count * col_count, data.len());
1014        unsafe {
1015            Self {
1016                entry: PhantomData,
1017                raw_data: SubmatrixRaw::new(std::mem::transmute(NonNull::new(data.as_ptr() as *mut T).unwrap_unchecked()), row_count, col_count as isize, 0, col_count)
1018            }
1019        }
1020    }
1021
1022    #[doc(cfg(feature = "ndarray"))]
1023    #[cfg(feature = "ndarray")]
1024    pub fn from_ndarray<S>(data: &'a ArrayBase<S, Ix2>) -> Self
1025        where S: DataMut<Elem = T>
1026    {
1027        let (nrows, ncols) = (data.nrows(), data.ncols());
1028        return Self::new(data.as_slice().unwrap(), nrows, ncols);
1029    }
1030}
1031
1032impl<'a, V: AsPointerToSlice<T> + Deref<Target = [T]>, T> Submatrix<'a, V, T> {
1033
1034    pub fn from_2d(data: &'a [V]) -> Self {
1039        assert!(data.len() > 0);
1040        let row_count = data.len();
1041        let col_count = data[0].len();
1042        for row in data.iter() {
1043            assert_eq!(col_count, row.len());
1044        }
1045        unsafe {
1046            Self {
1047                entry: PhantomData,
1048                raw_data: SubmatrixRaw::new(NonNull::new(data.as_ptr() as *mut _).unwrap_unchecked(), row_count, 1, 0, col_count)
1049            }
1050        }
1051    }
1052}
1053
1054#[cfg(test)]
1055fn assert_submatrix_eq<V: AsPointerToSlice<T>, T: PartialEq + Debug, const N: usize, const M: usize>(expected: [[T; M]; N], actual: &mut SubmatrixMut<V, T>) {
1056    assert_eq!(N, actual.row_count());
1057    assert_eq!(M, actual.col_count());
1058    for i in 0..N {
1059        for j in 0..M {
1060            assert_eq!(&expected[i][j], actual.at(i, j));
1061            assert_eq!(&expected[i][j], actual.as_const().at(i, j));
1062        }
1063    }
1064}
1065
1066#[cfg(test)]
1067fn with_testmatrix_vec<F>(f: F)
1068    where F: FnOnce(SubmatrixMut<Vec<i64>, i64>)
1069{
1070    let mut data = vec![
1071        vec![1, 2, 3, 4, 5],
1072        vec![6, 7, 8, 9, 10],
1073        vec![11, 12, 13, 14, 15]
1074    ];
1075    let matrix = SubmatrixMut::<Vec<_>, _>::from_2d(&mut data[..]);
1076    f(matrix)
1077}
1078
1079#[cfg(test)]
1080fn with_testmatrix_array<F>(f: F)
1081    where F: FnOnce(SubmatrixMut<DerefArray<i64, 5>, i64>)
1082{
1083    let mut data = vec![
1084        DerefArray::from([1, 2, 3, 4, 5]),
1085        DerefArray::from([6, 7, 8, 9, 10]),
1086        DerefArray::from([11, 12, 13, 14, 15])
1087    ];
1088    let matrix = SubmatrixMut::<DerefArray<_, 5>, _>::from_2d(&mut data[..]);
1089    f(matrix)
1090}
1091
1092#[cfg(test)]
1093fn with_testmatrix_linmem<F>(f: F)
1094    where F: FnOnce(SubmatrixMut<AsFirstElement<i64>, i64>)
1095{
1096    let mut data = vec![
1097        1, 2, 3, 4, 5,
1098        6, 7, 8, 9, 10,
1099        11, 12, 13, 14, 15
1100    ];
1101    let matrix = SubmatrixMut::<AsFirstElement<_>, _>::from_1d(&mut data[..], 3, 5);
1102    f(matrix)
1103}
1104
1105#[cfg(feature = "ndarray")]
1106#[cfg(test)]
1107fn with_testmatrix_ndarray<F>(f: F)
1108    where F: FnOnce(SubmatrixMut<AsFirstElement<i64>, i64>)
1109{
1110    use ndarray::array;
1111
1112    let mut data = array![
1113        [1, 2, 3, 4, 5],
1114        [6, 7, 8, 9, 10],
1115        [11, 12, 13, 14, 15]
1116    ];
1117    let matrix = SubmatrixMut::<AsFirstElement<_>, _>::from_ndarray(&mut data);
1118    f(matrix)
1119}
1120
1121#[cfg(not(feature = "ndarray"))]
1122#[cfg(test)]
1123fn with_testmatrix_ndarray<F>(_: F)
1124    where F: FnOnce(SubmatrixMut<AsFirstElement<i64>, i64>)
1125{
1126    }
1128
1129#[cfg(test)]
1130fn test_submatrix<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1131    assert_submatrix_eq([
1132        [1, 2, 3, 4, 5],
1133        [6, 7, 8, 9, 10],
1134        [11, 12, 13, 14, 15]
1135    ], &mut matrix);
1136    assert_submatrix_eq([[2, 3], [7, 8]], &mut matrix.reborrow().submatrix(0..2, 1..3));
1137    assert_submatrix_eq([[8, 9, 10]], &mut matrix.reborrow().submatrix(1..2, 2..5));
1138    assert_submatrix_eq([[8, 9, 10], [13, 14, 15]], &mut matrix.reborrow().submatrix(1..3, 2..5));
1139
1140    let (mut left, mut right) = matrix.split_cols(0..3, 3..5);
1141    assert_submatrix_eq([[1, 2, 3], [6, 7, 8], [11, 12, 13]], &mut left);
1142    assert_submatrix_eq([[4, 5], [9, 10], [14, 15]], &mut right);
1143}
1144
1145#[test]
1146fn test_submatrix_wrapper() {
1147    with_testmatrix_vec(test_submatrix);
1148    with_testmatrix_array(test_submatrix);
1149    with_testmatrix_linmem(test_submatrix);
1150    with_testmatrix_ndarray(test_submatrix);
1151}
1152
1153#[cfg(test)]
1154fn test_submatrix_mutate<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1155    assert_submatrix_eq([
1156        [1, 2, 3, 4, 5],
1157        [6, 7, 8, 9, 10],
1158        [11, 12, 13, 14, 15]
1159    ], &mut matrix);
1160    let (mut left, mut right) = matrix.split_cols(0..3, 3..5);
1161    assert_submatrix_eq([[1, 2, 3], [6, 7, 8], [11, 12, 13]], &mut left);
1162    assert_submatrix_eq([[4, 5], [9, 10], [14, 15]], &mut right);
1163    *left.at_mut(1, 1) += 1;
1164    *right.at_mut(0, 0) += 1;
1165    *right.at_mut(2, 1) += 1;
1166    assert_submatrix_eq([[1, 2, 3], [6, 8, 8], [11, 12, 13]], &mut left);
1167    assert_submatrix_eq([[5, 5], [9, 10], [14, 16]], &mut right);
1168
1169    let (mut top, mut bottom) = left.split_rows(0..1, 1..3);
1170    assert_submatrix_eq([[1, 2, 3]], &mut top);
1171    assert_submatrix_eq([[6, 8, 8], [11, 12, 13]], &mut bottom);
1172    *top.at_mut(0, 0) -= 1;
1173    *top.at_mut(0, 2) += 3;
1174    *bottom.at_mut(0, 2) -= 1;
1175    *bottom.at_mut(1, 0) += 3;
1176    assert_submatrix_eq([[0, 2, 6]], &mut top);
1177    assert_submatrix_eq([[6, 8, 7], [14, 12, 13]], &mut bottom);
1178}
1179
1180#[test]
1181fn test_submatrix_mutate_wrapper() {
1182    with_testmatrix_vec(test_submatrix_mutate);
1183    with_testmatrix_array(test_submatrix_mutate);
1184    with_testmatrix_linmem(test_submatrix_mutate);
1185    with_testmatrix_ndarray(test_submatrix_mutate);
1186}
1187
1188#[cfg(test)]
1189fn test_submatrix_col_iter<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1190    assert_submatrix_eq([
1191        [1, 2, 3, 4, 5],
1192        [6, 7, 8, 9, 10],
1193        [11, 12, 13, 14, 15]
1194    ], &mut matrix);
1195    {
1196        let mut it = matrix.reborrow().col_iter();
1197        assert_eq!(vec![2, 7, 12], it.by_ref().skip(1).next().unwrap().into_iter().map(|x| *x).collect::<Vec<_>>());
1198        assert_eq!(vec![4, 9, 14], it.by_ref().skip(1).next().unwrap().into_iter().map(|x| *x).collect::<Vec<_>>());
1199        let mut last_col = it.next().unwrap();
1200        for x in last_col.reborrow() {
1201            *x *= 2;
1202        }
1203        assert_eq!(vec![10, 20, 30], last_col.into_iter().map(|x| *x).collect::<Vec<_>>());
1204    }
1205    assert_submatrix_eq([
1206        [1, 2, 3, 4, 10],
1207        [6, 7, 8, 9, 20],
1208        [11, 12, 13, 14, 30]], 
1209        &mut matrix
1210    );
1211    
1212    let (left, _right) = matrix.reborrow().split_cols(0..2, 3..4);
1213    {
1214        let mut it = left.col_iter();
1215        let mut col1 = it.next().unwrap();
1216        let mut col2 = it.next().unwrap();
1217        assert!(it.next().is_none());
1218        assert_eq!(vec![1, 6, 11], col1.as_iter().map(|x| *x).collect::<Vec<_>>());
1219        assert_eq!(vec![2, 7, 12], col2.as_iter().map(|x| *x).collect::<Vec<_>>());
1220        assert_eq!(vec![1, 6, 11], col1.reborrow().into_iter().map(|x| *x).collect::<Vec<_>>());
1221        assert_eq!(vec![2, 7, 12], col2.reborrow().into_iter().map(|x| *x).collect::<Vec<_>>());
1222        *col1.into_iter().skip(1).next().unwrap() += 5;
1223    }
1224    assert_submatrix_eq([
1225        [1, 2, 3, 4, 10],
1226        [11, 7, 8, 9, 20],
1227        [11, 12, 13, 14, 30]], 
1228        &mut matrix
1229    );
1230
1231    let (_left, right) = matrix.reborrow().split_cols(0..2, 3..4);
1232    {
1233        let mut it = right.col_iter();
1234        let mut col = it.next().unwrap();
1235        assert!(it.next().is_none());
1236        assert_eq!(vec![4, 9, 14], col.reborrow().as_iter().map(|x| *x).collect::<Vec<_>>());
1237        *col.into_iter().next().unwrap() += 3;
1238    }
1239    assert_submatrix_eq([
1240        [1, 2, 3, 7, 10],
1241        [11, 7, 8, 9, 20],
1242        [11, 12, 13, 14, 30]], 
1243        &mut matrix
1244    );
1245}
1246
1247#[test]
1248fn test_submatrix_col_iter_wrapper() {
1249    with_testmatrix_vec(test_submatrix_col_iter);
1250    with_testmatrix_array(test_submatrix_col_iter);
1251    with_testmatrix_linmem(test_submatrix_col_iter);
1252    with_testmatrix_ndarray(test_submatrix_col_iter);
1253}
1254
1255#[cfg(test)]
1256fn test_submatrix_row_iter<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1257    assert_submatrix_eq([
1258        [1, 2, 3, 4, 5],
1259        [6, 7, 8, 9, 10],
1260        [11, 12, 13, 14, 15]
1261    ], &mut matrix);
1262    {
1263        let mut it = matrix.reborrow().row_iter();
1264        assert_eq!(&[6, 7, 8, 9, 10], it.by_ref().skip(1).next().unwrap());
1265        let row = it.next().unwrap();
1266        assert!(it.next().is_none());
1267        row[1] += 6;
1268        row[4] *= 2;
1269    }
1270    assert_submatrix_eq([
1271        [1, 2, 3, 4, 5],
1272        [6, 7, 8, 9, 10],
1273        [11, 18, 13, 14, 30]], 
1274        &mut matrix
1275    );
1276    let (mut left, mut right) = matrix.reborrow().split_cols(0..2, 3..4);
1277    {
1278        let mut it = left.reborrow().row_iter();
1279        let row1 = it.next().unwrap();
1280        let row2 = it.next().unwrap();
1281        assert!(it.next().is_some());
1282        assert!(it.next().is_none());
1283        assert_eq!(&[1, 2], row1);
1284        assert_eq!(&[6, 7], row2);
1285    }
1286    {
1287        let mut it = left.reborrow().row_iter();
1288        let row1 = it.next().unwrap();
1289        let row2 = it.next().unwrap();
1290        assert!(it.next().is_some());
1291        assert!(it.next().is_none());
1292        assert_eq!(&[1, 2], row1);
1293        assert_eq!(&[6, 7], row2);
1294        row2[1] += 1;
1295    }
1296    assert_submatrix_eq([[1, 2], [6, 8], [11, 18]], &mut left);
1297    {
1298        right = right.submatrix(1..3, 0..1);
1299        let mut it = right.reborrow().row_iter();
1300        let row1 = it.next().unwrap();
1301        let row2 = it.next().unwrap();
1302        assert_eq!(&[9], row1);
1303        assert_eq!(&[14], row2);
1304        row1[0] += 1;
1305    }
1306    assert_submatrix_eq([[10], [14]], &mut right);
1307}
1308
1309#[test]
1310fn test_submatrix_row_iter_wrapper() {
1311    with_testmatrix_vec(test_submatrix_row_iter);
1312    with_testmatrix_array(test_submatrix_row_iter);
1313    with_testmatrix_linmem(test_submatrix_row_iter);
1314    with_testmatrix_ndarray(test_submatrix_row_iter);
1315}
1316
1317#[cfg(test)]
1318fn test_submatrix_col_at<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1319    assert_submatrix_eq([
1320        [1, 2, 3, 4, 5],
1321        [6, 7, 8, 9, 10],
1322        [11, 12, 13, 14, 15]
1323    ], &mut matrix);
1324    assert_eq!(&[2, 7, 12], &matrix.col_at(1).as_iter().copied().collect::<Vec<_>>()[..]);
1325    assert_eq!(&[2, 7, 12], &matrix.as_const().col_at(1).as_iter().copied().collect::<Vec<_>>()[..]);
1326    assert_eq!(&[5, 10, 15], &matrix.col_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1327    assert_eq!(&[5, 10, 15], &matrix.as_const().col_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1328
1329    {
1330        let (mut top, mut bottom) = matrix.reborrow().restrict_rows(0..2).split_rows(0..1, 1..2);
1331        assert_eq!(&[1], &top.col_mut_at(0).as_iter().copied().collect::<Vec<_>>()[..]);
1332        assert_eq!(&[1], &top.as_const().col_at(0).as_iter().copied().collect::<Vec<_>>()[..]);
1333        assert_eq!(&[1], &top.col_at(0).as_iter().copied().collect::<Vec<_>>()[..]);
1334        assert_eq!(&[5], &top.col_mut_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1335        assert_eq!(&[5], &top.as_const().col_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1336        assert_eq!(&[5], &top.col_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1337
1338        assert_eq!(&[6], &bottom.col_mut_at(0).as_iter().copied().collect::<Vec<_>>()[..]);
1339        assert_eq!(&[6], &bottom.as_const().col_at(0).as_iter().copied().collect::<Vec<_>>()[..]);
1340        assert_eq!(&[6], &bottom.col_at(0).as_iter().copied().collect::<Vec<_>>()[..]);
1341        assert_eq!(&[10], &bottom.col_mut_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1342        assert_eq!(&[10], &bottom.as_const().col_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1343        assert_eq!(&[10], &bottom.col_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1344    }
1345}
1346
1347#[test]
1348fn test_submatrix_col_at_wrapper() {
1349    with_testmatrix_vec(test_submatrix_col_at);
1350    with_testmatrix_array(test_submatrix_col_at);
1351    with_testmatrix_linmem(test_submatrix_col_at);
1352    with_testmatrix_ndarray(test_submatrix_col_at);
1353}
1354
1355#[cfg(test)]
1356fn test_submatrix_row_at<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1357    assert_submatrix_eq([
1358        [1, 2, 3, 4, 5],
1359        [6, 7, 8, 9, 10],
1360        [11, 12, 13, 14, 15]
1361    ], &mut matrix);
1362    assert_eq!(&[2, 7, 12], &matrix.col_at(1).as_iter().copied().collect::<Vec<_>>()[..]);
1363    assert_eq!(&[2, 7, 12], &matrix.as_const().col_at(1).as_iter().copied().collect::<Vec<_>>()[..]);
1364    assert_eq!(&[5, 10, 15], &matrix.col_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1365    assert_eq!(&[5, 10, 15], &matrix.as_const().col_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1366
1367    {
1368        let (mut left, mut right) = matrix.reborrow().restrict_cols(1..5).split_cols(0..2, 2..4);
1369        assert_eq!(&[2, 3], left.row_mut_at(0));
1370        assert_eq!(&[4, 5], right.row_mut_at(0));
1371        assert_eq!(&[2, 3], left.as_const().row_at(0));
1372        assert_eq!(&[4, 5], right.as_const().row_at(0));
1373        assert_eq!(&[2, 3], left.row_at(0));
1374        assert_eq!(&[4, 5], right.row_at(0));
1375
1376        assert_eq!(&[7, 8], left.row_mut_at(1));
1377        assert_eq!(&[9, 10], right.row_mut_at(1));
1378        assert_eq!(&[7, 8], left.as_const().row_at(1));
1379        assert_eq!(&[9, 10], right.as_const().row_at(1));
1380        assert_eq!(&[7, 8], left.row_at(1));
1381        assert_eq!(&[9, 10], right.row_at(1));
1382    }
1383}
1384
1385#[test]
1386fn test_submatrix_row_at_wrapper() {
1387    with_testmatrix_vec(test_submatrix_row_at);
1388    with_testmatrix_array(test_submatrix_row_at);
1389    with_testmatrix_linmem(test_submatrix_row_at);
1390    with_testmatrix_ndarray(test_submatrix_row_at);
1391}