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}