1use std::fmt::{Debug, Formatter};
2use std::marker::PhantomData;
3use std::ops::{Deref, Range};
4use std::ptr::{NonNull, addr_of_mut};
5
6#[cfg(feature = "ndarray")]
7use ndarray::{ArrayBase, DataMut, Ix2};
8
9use crate::seq::{SwappableVectorViewMut, VectorView, VectorViewMut};
10
11pub unsafe trait AsPointerToSlice<T> {
27 unsafe fn get_pointer(self_: NonNull<Self>) -> NonNull<T>;
42}
43
44unsafe impl<T> AsPointerToSlice<T> for Vec<T> {
45 unsafe fn get_pointer(self_: NonNull<Self>) -> NonNull<T> {
46 unsafe { NonNull::new((*self_.as_ptr()).as_mut_ptr()).unwrap() }
50 }
51}
52
53#[repr(transparent)]
58#[derive(Clone, Copy, PartialEq, Eq)]
59pub struct DerefArray<T, const SIZE: usize> {
60 pub data: [T; SIZE],
62}
63
64impl<T: std::fmt::Debug, const SIZE: usize> std::fmt::Debug for DerefArray<T, SIZE> {
65 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.data.fmt(f) }
66}
67
68impl<T, const SIZE: usize> From<[T; SIZE]> for DerefArray<T, SIZE> {
69 fn from(value: [T; SIZE]) -> Self { Self { data: value } }
70}
71
72impl<'a, T, const SIZE: usize> From<&'a [T; SIZE]> for &'a DerefArray<T, SIZE> {
73 fn from(value: &'a [T; SIZE]) -> Self { unsafe { std::mem::transmute(value) } }
74}
75
76impl<'a, T, const SIZE: usize> From<&'a mut [T; SIZE]> for &'a mut DerefArray<T, SIZE> {
77 fn from(value: &'a mut [T; SIZE]) -> Self { unsafe { std::mem::transmute(value) } }
78}
79
80impl<T, const SIZE: usize> Deref for DerefArray<T, SIZE> {
81 type Target = [T];
82
83 fn deref(&self) -> &Self::Target { &self.data[..] }
84}
85
86unsafe impl<T, const SIZE: usize> AsPointerToSlice<T> for DerefArray<T, SIZE> {
87 unsafe fn get_pointer(self_: NonNull<Self>) -> NonNull<T> {
88 unsafe {
89 let self_ptr = self_.as_ptr();
90 let data_ptr = addr_of_mut!((*self_ptr).data);
91 NonNull::new((*data_ptr).as_mut_ptr()).unwrap()
92 }
93 }
94}
95
96#[repr(transparent)]
100pub struct AsFirstElement<T>(T);
101
102unsafe impl<'a, T> AsPointerToSlice<T> for AsFirstElement<T> {
103 unsafe fn get_pointer(self_: NonNull<Self>) -> NonNull<T> { unsafe { std::mem::transmute(self_) } }
104}
105
106#[stability::unstable(feature = "enable")]
144pub struct SubmatrixRaw<V, T>
145where
146 V: AsPointerToSlice<T>,
147{
148 entry: PhantomData<*mut T>,
149 rows: NonNull<V>,
150 row_count: usize,
151 row_step: isize,
152 col_start: usize,
153 col_count: usize,
154}
155
156unsafe impl<V, T> Send for SubmatrixRaw<V, T>
161where
162 V: AsPointerToSlice<T> + Sync,
163 T: Sync,
164{
165}
166
167unsafe impl<V, T> Sync for SubmatrixRaw<V, T>
168where
169 V: AsPointerToSlice<T> + Sync,
170 T: Sync,
171{
172}
173
174impl<V, T> Clone for SubmatrixRaw<V, T>
175where
176 V: AsPointerToSlice<T>,
177{
178 fn clone(&self) -> Self { *self }
179}
180
181impl<V, T> Copy for SubmatrixRaw<V, T> where V: AsPointerToSlice<T> {}
182
183impl<V, T> SubmatrixRaw<V, T>
184where
185 V: AsPointerToSlice<T>,
186{
187 #[stability::unstable(feature = "enable")]
201 pub unsafe fn new(
202 rows: NonNull<V>,
203 row_count: usize,
204 row_step: isize,
205 cols_start: usize,
206 col_count: usize,
207 ) -> Self {
208 Self {
209 entry: PhantomData,
210 row_count,
211 row_step,
212 rows,
213 col_start: cols_start,
214 col_count,
215 }
216 }
217
218 #[stability::unstable(feature = "enable")]
219 pub fn restrict_rows(mut self, rows: Range<usize>) -> Self {
220 assert!(rows.start <= rows.end);
221 assert!(rows.end <= self.row_count);
222 unsafe {
230 self.row_count = rows.end - rows.start;
231 self.rows = self.rows.offset(rows.start as isize * self.row_step);
232 }
233 self
234 }
235
236 #[stability::unstable(feature = "enable")]
237 pub fn restrict_cols(mut self, cols: Range<usize>) -> Self {
238 assert!(cols.end <= self.col_count);
239 self.col_count = cols.end - cols.start;
240 self.col_start += cols.start;
241 self
242 }
243
244 #[stability::unstable(feature = "enable")]
247 pub fn row_at(&self, row: usize) -> NonNull<[T]> {
248 assert!(row < self.row_count);
249 let row_ref = unsafe { V::get_pointer(self.rows.offset(row as isize * self.row_step)) };
252 unsafe { NonNull::slice_from_raw_parts(row_ref.offset(self.col_start as isize), self.col_count) }
254 }
255
256 #[stability::unstable(feature = "enable")]
259 pub fn entry_at(&self, row: usize, col: usize) -> NonNull<T> {
260 assert!(
261 row < self.row_count,
262 "Row index {} out of range 0..{}",
263 row,
264 self.row_count
265 );
266 assert!(
267 col < self.col_count,
268 "Col index {} out of range 0..{}",
269 col,
270 self.col_count
271 );
272 let row_ref = unsafe { V::get_pointer(self.rows.offset(row as isize * self.row_step)) };
275 unsafe { row_ref.offset(self.col_start as isize + col as isize) }
277 }
278}
279
280pub struct Column<'a, V, T>
282where
283 V: AsPointerToSlice<T>,
284{
285 entry: PhantomData<&'a T>,
286 raw_data: SubmatrixRaw<V, T>,
287}
288
289impl<'a, V, T> Column<'a, V, T>
290where
291 V: AsPointerToSlice<T>,
292{
293 unsafe fn new(raw_data: SubmatrixRaw<V, T>) -> Self {
303 assert!(raw_data.col_count == 1);
304 Self {
305 entry: PhantomData,
306 raw_data,
307 }
308 }
309}
310
311impl<'a, V, T: Debug> Debug for Column<'a, V, T>
312where
313 V: AsPointerToSlice<T>,
314{
315 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
316 let mut output = f.debug_list();
317 for x in self.as_iter() {
318 _ = output.entry(x);
319 }
320 output.finish()
321 }
322}
323
324impl<'a, V, T> Clone for Column<'a, V, T>
325where
326 V: AsPointerToSlice<T>,
327{
328 fn clone(&self) -> Self { *self }
329}
330
331impl<'a, V, T> Copy for Column<'a, V, T> where V: AsPointerToSlice<T> {}
332
333impl<'a, V, T> VectorView<T> for Column<'a, V, T>
334where
335 V: AsPointerToSlice<T>,
336{
337 fn len(&self) -> usize { self.raw_data.row_count }
338
339 fn at(&self, i: usize) -> &T {
340 unsafe { self.raw_data.entry_at(i, 0).as_ref() }
342 }
343}
344
345pub struct ColumnMut<'a, V, T>
349where
350 V: AsPointerToSlice<T>,
351{
352 entry: PhantomData<&'a mut T>,
353 raw_data: SubmatrixRaw<V, T>,
354}
355
356impl<'a, V, T: Debug> Debug for ColumnMut<'a, V, T>
357where
358 V: AsPointerToSlice<T>,
359{
360 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { self.as_const().fmt(f) }
361}
362
363impl<'a, V, T> ColumnMut<'a, V, T>
364where
365 V: AsPointerToSlice<T>,
366{
367 unsafe fn new(raw_data: SubmatrixRaw<V, T>) -> Self {
378 assert!(raw_data.col_count == 1);
379 Self {
380 entry: PhantomData,
381 raw_data,
382 }
383 }
384
385 pub fn reborrow<'b>(&'b mut self) -> ColumnMut<'b, V, T> {
389 ColumnMut {
390 entry: PhantomData,
391 raw_data: self.raw_data,
392 }
393 }
394
395 pub fn two_entries(&mut self, i: usize, j: usize) -> (&mut T, &mut T) {
401 assert!(i != j);
402 unsafe {
404 (
405 self.raw_data.entry_at(i, 0).as_mut(),
406 self.raw_data.entry_at(j, 0).as_mut(),
407 )
408 }
409 }
410
411 pub fn as_const<'b>(&'b self) -> Column<'b, V, T> {
413 Column {
414 entry: PhantomData,
415 raw_data: self.raw_data,
416 }
417 }
418}
419
420unsafe impl<'a, V, T> Send for ColumnMut<'a, V, T>
421where
422 V: AsPointerToSlice<T> + Sync,
423 T: Send,
424{
425}
426
427impl<'a, V, T> VectorView<T> for ColumnMut<'a, V, T>
428where
429 V: AsPointerToSlice<T>,
430{
431 fn len(&self) -> usize { self.raw_data.row_count }
432
433 fn at(&self, i: usize) -> &T {
434 unsafe { self.raw_data.entry_at(i, 0).as_ref() }
436 }
437}
438
439pub struct ColumnMutIter<'a, V, T>
442where
443 V: AsPointerToSlice<T>,
444{
445 column_mut: ColumnMut<'a, V, T>,
446}
447
448impl<'a, V, T> Iterator for ColumnMutIter<'a, V, T>
449where
450 V: AsPointerToSlice<T>,
451{
452 type Item = &'a mut T;
453
454 fn next(&mut self) -> Option<Self::Item> {
455 if self.column_mut.raw_data.row_count > 0 {
456 let mut result = self.column_mut.raw_data.entry_at(0, 0);
457 self.column_mut.raw_data = self
458 .column_mut
459 .raw_data
460 .restrict_rows(1..self.column_mut.raw_data.row_count);
461 unsafe { Some(result.as_mut()) }
464 } else {
465 None
466 }
467 }
468}
469
470impl<'a, V, T> IntoIterator for ColumnMut<'a, V, T>
471where
472 V: AsPointerToSlice<T>,
473{
474 type Item = &'a mut T;
475 type IntoIter = ColumnMutIter<'a, V, T>;
476
477 fn into_iter(self) -> ColumnMutIter<'a, V, T> { ColumnMutIter { column_mut: self } }
478}
479
480impl<'a, V, T> VectorViewMut<T> for ColumnMut<'a, V, T>
481where
482 V: AsPointerToSlice<T>,
483{
484 fn at_mut(&mut self, i: usize) -> &mut T {
485 unsafe { self.raw_data.entry_at(i, 0).as_mut() }
487 }
488}
489
490impl<'a, V, T> SwappableVectorViewMut<T> for ColumnMut<'a, V, T>
491where
492 V: AsPointerToSlice<T>,
493{
494 fn swap(&mut self, i: usize, j: usize) {
495 if i != j {
496 unsafe {
500 std::mem::swap(
501 self.raw_data.entry_at(i, 0).as_mut(),
502 self.raw_data.entry_at(j, 0).as_mut(),
503 );
504 }
505 }
506 }
507}
508
509pub struct Submatrix<'a, V, T>
519where
520 V: 'a + AsPointerToSlice<T>,
521{
522 entry: PhantomData<&'a T>,
523 raw_data: SubmatrixRaw<V, T>,
524}
525
526impl<'a, V, T> Submatrix<'a, V, T>
527where
528 V: 'a + AsPointerToSlice<T>,
529{
530 pub fn submatrix(self, rows: Range<usize>, cols: Range<usize>) -> Self {
533 self.restrict_rows(rows).restrict_cols(cols)
534 }
535
536 pub fn restrict_rows(self, rows: Range<usize>) -> Self {
539 Self {
540 entry: PhantomData,
541 raw_data: self.raw_data.restrict_rows(rows),
542 }
543 }
544
545 pub fn into_at(self, i: usize, j: usize) -> &'a T { &self.into_row_at(i)[j] }
551
552 pub fn at(&self, i: usize, j: usize) -> &T { &self.row_at(i)[j] }
554
555 pub fn restrict_cols(self, cols: Range<usize>) -> Self {
558 Self {
559 entry: PhantomData,
560 raw_data: self.raw_data.restrict_cols(cols),
561 }
562 }
563
564 pub fn row_iter(self) -> impl 'a + Clone + ExactSizeIterator<Item = &'a [T]> {
566 (0..self.raw_data.row_count).map(move |i|
567 unsafe {
569 self.raw_data.row_at(i).as_ref()
570 })
571 }
572
573 pub fn col_iter(self) -> impl 'a + Clone + ExactSizeIterator<Item = Column<'a, V, T>> {
575 (0..self.raw_data.col_count).map(move |j| {
576 debug_assert!(j < self.raw_data.col_count);
577 let mut result_raw = self.raw_data;
578 result_raw.col_start += j;
579 result_raw.col_count = 1;
580 unsafe {
582 return Column::new(result_raw);
583 }
584 })
585 }
586
587 pub fn into_row_at(self, i: usize) -> &'a [T] {
593 unsafe { self.raw_data.row_at(i).as_ref() }
595 }
596
597 pub fn row_at(&self, i: usize) -> &[T] {
599 unsafe { self.raw_data.row_at(i).as_ref() }
601 }
602
603 pub fn into_col_at(self, j: usize) -> Column<'a, V, T> {
609 assert!(j < self.raw_data.col_count);
610 let mut result_raw = self.raw_data;
611 result_raw.col_start += j;
612 result_raw.col_count = 1;
613 unsafe {
615 return Column::new(result_raw);
616 }
617 }
618
619 pub fn col_at<'b>(&'b self, j: usize) -> Column<'b, V, T> {
621 assert!(j < self.raw_data.col_count);
622 let mut result_raw = self.raw_data;
623 result_raw.col_start += j;
624 result_raw.col_count = 1;
625 unsafe {
627 return Column::new(result_raw);
628 }
629 }
630
631 pub fn col_count(&self) -> usize { self.raw_data.col_count }
633
634 pub fn row_count(&self) -> usize { self.raw_data.row_count }
636}
637
638impl<'a, V, T: Debug> Debug for Submatrix<'a, V, T>
639where
640 V: 'a + AsPointerToSlice<T>,
641{
642 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
643 let mut output = f.debug_list();
644 for row in self.row_iter() {
645 _ = output.entry(&row);
646 }
647 output.finish()
648 }
649}
650
651impl<'a, V, T> Clone for Submatrix<'a, V, T>
652where
653 V: 'a + AsPointerToSlice<T>,
654{
655 fn clone(&self) -> Self { *self }
656}
657
658impl<'a, V, T> Copy for Submatrix<'a, V, T> where V: 'a + AsPointerToSlice<T> {}
659
660pub struct SubmatrixMut<'a, V, T>
668where
669 V: 'a + AsPointerToSlice<T>,
670{
671 entry: PhantomData<&'a mut T>,
672 raw_data: SubmatrixRaw<V, T>,
673}
674
675impl<'a, V, T> SubmatrixMut<'a, V, T>
676where
677 V: 'a + AsPointerToSlice<T>,
678{
679 pub fn submatrix(self, rows: Range<usize>, cols: Range<usize>) -> Self {
682 self.restrict_rows(rows).restrict_cols(cols)
683 }
684
685 pub fn restrict_rows(self, rows: Range<usize>) -> Self {
688 Self {
689 entry: PhantomData,
690 raw_data: self.raw_data.restrict_rows(rows),
691 }
692 }
693
694 pub fn restrict_cols(self, cols: Range<usize>) -> Self {
697 Self {
698 entry: PhantomData,
699 raw_data: self.raw_data.restrict_cols(cols),
700 }
701 }
702
703 pub fn split_rows(self, fst_rows: Range<usize>, snd_rows: Range<usize>) -> (Self, Self) {
708 assert!(fst_rows.end <= snd_rows.start || snd_rows.end <= fst_rows.start);
709 (
710 Self {
711 entry: PhantomData,
712 raw_data: self.raw_data.restrict_rows(fst_rows),
713 },
714 Self {
715 entry: PhantomData,
716 raw_data: self.raw_data.restrict_rows(snd_rows),
717 },
718 )
719 }
720
721 pub fn split_cols(self, fst_cols: Range<usize>, snd_cols: Range<usize>) -> (Self, Self) {
726 assert!(fst_cols.end <= snd_cols.start || snd_cols.end <= fst_cols.start);
727 (
728 Self {
729 entry: PhantomData,
730 raw_data: self.raw_data.restrict_cols(fst_cols),
731 },
732 Self {
733 entry: PhantomData,
734 raw_data: self.raw_data.restrict_cols(snd_cols),
735 },
736 )
737 }
738
739 pub fn row_iter(self) -> impl 'a + ExactSizeIterator<Item = &'a mut [T]> {
741 (0..self.raw_data.row_count).map(move |i|
742 unsafe {
744 self.raw_data.row_at(i).as_mut()
745 })
746 }
747
748 pub fn col_iter(self) -> impl 'a + ExactSizeIterator<Item = ColumnMut<'a, V, T>> {
750 (0..self.raw_data.col_count).map(move |j| {
751 let mut result_raw = self.raw_data;
752 result_raw.col_start += j;
753 result_raw.col_count = 1;
754 unsafe {
756 return ColumnMut::new(result_raw);
757 }
758 })
759 }
760
761 pub fn into_at_mut(self, i: usize, j: usize) -> &'a mut T { &mut self.into_row_mut_at(i)[j] }
767
768 pub fn at_mut(&mut self, i: usize, j: usize) -> &mut T { &mut self.row_mut_at(i)[j] }
770
771 pub fn at(&self, i: usize, j: usize) -> &T { self.as_const().into_at(i, j) }
773
774 pub fn row_at(&self, i: usize) -> &[T] { self.as_const().into_row_at(i) }
776
777 pub fn into_row_mut_at(self, i: usize) -> &'a mut [T] {
783 unsafe { self.raw_data.row_at(i).as_mut() }
785 }
786
787 pub fn row_mut_at(&mut self, i: usize) -> &mut [T] { self.reborrow().into_row_mut_at(i) }
789
790 pub fn col_at<'b>(&'b self, j: usize) -> Column<'b, V, T> { self.as_const().into_col_at(j) }
792
793 pub fn col_mut_at<'b>(&'b mut self, j: usize) -> ColumnMut<'b, V, T> {
795 assert!(j < self.raw_data.col_count);
796 let mut result_raw = self.raw_data;
797 result_raw.col_start += j;
798 result_raw.col_count = 1;
799 unsafe {
801 return ColumnMut::new(result_raw);
802 }
803 }
804
805 pub fn reborrow<'b>(&'b mut self) -> SubmatrixMut<'b, V, T> {
809 SubmatrixMut {
810 entry: PhantomData,
811 raw_data: self.raw_data,
812 }
813 }
814
815 pub fn as_const<'b>(&'b self) -> Submatrix<'b, V, T> {
817 Submatrix {
818 entry: PhantomData,
819 raw_data: self.raw_data,
820 }
821 }
822
823 pub fn col_count(&self) -> usize { self.raw_data.col_count }
825
826 pub fn row_count(&self) -> usize { self.raw_data.row_count }
828}
829
830impl<'a, V, T: Debug> Debug for SubmatrixMut<'a, V, T>
831where
832 V: 'a + AsPointerToSlice<T>,
833{
834 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { self.as_const().fmt(f) }
835}
836
837impl<'a, T> SubmatrixMut<'a, AsFirstElement<T>, T> {
838 pub fn from_1d(data: &'a mut [T], row_count: usize, col_count: usize) -> Self {
842 assert_eq!(row_count * col_count, data.len());
843 unsafe {
844 Self {
845 entry: PhantomData,
846 raw_data: SubmatrixRaw::new(
847 std::mem::transmute(NonNull::new(data.as_mut_ptr()).unwrap_unchecked()),
848 row_count,
849 col_count as isize,
850 0,
851 col_count,
852 ),
853 }
854 }
855 }
856
857 #[doc(cfg(feature = "ndarray"))]
858 #[cfg(feature = "ndarray")]
859 pub fn from_ndarray<S>(data: &'a mut ArrayBase<S, Ix2>) -> Self
860 where
861 S: DataMut<Elem = T>,
862 {
863 assert!(data.is_standard_layout());
864 let (nrows, ncols) = (data.nrows(), data.ncols());
865 return Self::new(data.as_slice_mut().unwrap(), nrows, ncols);
866 }
867}
868
869impl<'a, V: AsPointerToSlice<T> + Deref<Target = [T]>, T> SubmatrixMut<'a, V, T> {
870 pub fn from_2d(data: &'a mut [V]) -> Self {
873 assert!(!data.is_empty());
874 let row_count = data.len();
875 let col_count = data[0].len();
876 for row in data.iter() {
877 assert_eq!(col_count, row.len());
878 }
879 unsafe {
880 Self {
881 entry: PhantomData,
882 raw_data: SubmatrixRaw::new(
883 NonNull::new(data.as_mut_ptr() as *mut _).unwrap_unchecked(),
884 row_count,
885 1,
886 0,
887 col_count,
888 ),
889 }
890 }
891 }
892}
893
894impl<'a, T> Submatrix<'a, AsFirstElement<T>, T> {
895 pub fn from_1d(data: &'a [T], row_count: usize, col_count: usize) -> Self {
899 assert_eq!(row_count * col_count, data.len());
900 unsafe {
901 Self {
902 entry: PhantomData,
903 raw_data: SubmatrixRaw::new(
904 std::mem::transmute(NonNull::new(data.as_ptr() as *mut T).unwrap_unchecked()),
905 row_count,
906 col_count as isize,
907 0,
908 col_count,
909 ),
910 }
911 }
912 }
913
914 #[doc(cfg(feature = "ndarray"))]
915 #[cfg(feature = "ndarray")]
916 pub fn from_ndarray<S>(data: &'a ArrayBase<S, Ix2>) -> Self
917 where
918 S: DataMut<Elem = T>,
919 {
920 let (nrows, ncols) = (data.nrows(), data.ncols());
921 return Self::new(data.as_slice().unwrap(), nrows, ncols);
922 }
923}
924
925impl<'a, V: AsPointerToSlice<T> + Deref<Target = [T]>, T> Submatrix<'a, V, T> {
926 pub fn from_2d(data: &'a [V]) -> Self {
929 assert!(!data.is_empty());
930 let row_count = data.len();
931 let col_count = data[0].len();
932 for row in data.iter() {
933 assert_eq!(col_count, row.len());
934 }
935 unsafe {
936 Self {
937 entry: PhantomData,
938 raw_data: SubmatrixRaw::new(
939 NonNull::new(data.as_ptr() as *mut _).unwrap_unchecked(),
940 row_count,
941 1,
942 0,
943 col_count,
944 ),
945 }
946 }
947 }
948}
949
950#[cfg(test)]
951fn assert_submatrix_eq<V: AsPointerToSlice<T>, T: PartialEq + Debug, const N: usize, const M: usize>(
952 expected: [[T; M]; N],
953 actual: &mut SubmatrixMut<V, T>,
954) {
955 assert_eq!(N, actual.row_count());
956 assert_eq!(M, actual.col_count());
957 for i in 0..N {
958 for j in 0..M {
959 assert_eq!(&expected[i][j], actual.at(i, j));
960 assert_eq!(&expected[i][j], actual.as_const().at(i, j));
961 }
962 }
963}
964
965#[cfg(test)]
966fn with_testmatrix_vec<F>(f: F)
967where
968 F: FnOnce(SubmatrixMut<Vec<i64>, i64>),
969{
970 let mut data = vec![vec![1, 2, 3, 4, 5], vec![6, 7, 8, 9, 10], vec![11, 12, 13, 14, 15]];
971 let matrix = SubmatrixMut::<Vec<_>, _>::from_2d(&mut data[..]);
972 f(matrix)
973}
974
975#[cfg(test)]
976fn with_testmatrix_array<F>(f: F)
977where
978 F: FnOnce(SubmatrixMut<DerefArray<i64, 5>, i64>),
979{
980 let mut data = vec![
981 DerefArray::from([1, 2, 3, 4, 5]),
982 DerefArray::from([6, 7, 8, 9, 10]),
983 DerefArray::from([11, 12, 13, 14, 15]),
984 ];
985 let matrix = SubmatrixMut::<DerefArray<_, 5>, _>::from_2d(&mut data[..]);
986 f(matrix)
987}
988
989#[cfg(test)]
990fn with_testmatrix_linmem<F>(f: F)
991where
992 F: FnOnce(SubmatrixMut<AsFirstElement<i64>, i64>),
993{
994 let mut data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
995 let matrix = SubmatrixMut::<AsFirstElement<_>, _>::from_1d(&mut data[..], 3, 5);
996 f(matrix)
997}
998
999#[cfg(feature = "ndarray")]
1000#[cfg(test)]
1001fn with_testmatrix_ndarray<F>(f: F)
1002where
1003 F: FnOnce(SubmatrixMut<AsFirstElement<i64>, i64>),
1004{
1005 use ndarray::array;
1006
1007 let mut data = array![[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]];
1008 let matrix = SubmatrixMut::<AsFirstElement<_>, _>::from_ndarray(&mut data);
1009 f(matrix)
1010}
1011
1012#[cfg(not(feature = "ndarray"))]
1013#[cfg(test)]
1014fn with_testmatrix_ndarray<F>(_: F)
1015where
1016 F: FnOnce(SubmatrixMut<AsFirstElement<i64>, i64>),
1017{
1018 }
1020
1021#[cfg(test)]
1022fn test_submatrix<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1023 assert_submatrix_eq([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], &mut matrix);
1024 assert_submatrix_eq([[2, 3], [7, 8]], &mut matrix.reborrow().submatrix(0..2, 1..3));
1025 assert_submatrix_eq([[8, 9, 10]], &mut matrix.reborrow().submatrix(1..2, 2..5));
1026 assert_submatrix_eq([[8, 9, 10], [13, 14, 15]], &mut matrix.reborrow().submatrix(1..3, 2..5));
1027
1028 let (mut left, mut right) = matrix.split_cols(0..3, 3..5);
1029 assert_submatrix_eq([[1, 2, 3], [6, 7, 8], [11, 12, 13]], &mut left);
1030 assert_submatrix_eq([[4, 5], [9, 10], [14, 15]], &mut right);
1031}
1032
1033#[test]
1034fn test_submatrix_wrapper() {
1035 with_testmatrix_vec(test_submatrix);
1036 with_testmatrix_array(test_submatrix);
1037 with_testmatrix_linmem(test_submatrix);
1038 with_testmatrix_ndarray(test_submatrix);
1039}
1040
1041#[cfg(test)]
1042fn test_submatrix_mutate<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1043 assert_submatrix_eq([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], &mut matrix);
1044 let (mut left, mut right) = matrix.split_cols(0..3, 3..5);
1045 assert_submatrix_eq([[1, 2, 3], [6, 7, 8], [11, 12, 13]], &mut left);
1046 assert_submatrix_eq([[4, 5], [9, 10], [14, 15]], &mut right);
1047 *left.at_mut(1, 1) += 1;
1048 *right.at_mut(0, 0) += 1;
1049 *right.at_mut(2, 1) += 1;
1050 assert_submatrix_eq([[1, 2, 3], [6, 8, 8], [11, 12, 13]], &mut left);
1051 assert_submatrix_eq([[5, 5], [9, 10], [14, 16]], &mut right);
1052
1053 let (mut top, mut bottom) = left.split_rows(0..1, 1..3);
1054 assert_submatrix_eq([[1, 2, 3]], &mut top);
1055 assert_submatrix_eq([[6, 8, 8], [11, 12, 13]], &mut bottom);
1056 *top.at_mut(0, 0) -= 1;
1057 *top.at_mut(0, 2) += 3;
1058 *bottom.at_mut(0, 2) -= 1;
1059 *bottom.at_mut(1, 0) += 3;
1060 assert_submatrix_eq([[0, 2, 6]], &mut top);
1061 assert_submatrix_eq([[6, 8, 7], [14, 12, 13]], &mut bottom);
1062}
1063
1064#[test]
1065fn test_submatrix_mutate_wrapper() {
1066 with_testmatrix_vec(test_submatrix_mutate);
1067 with_testmatrix_array(test_submatrix_mutate);
1068 with_testmatrix_linmem(test_submatrix_mutate);
1069 with_testmatrix_ndarray(test_submatrix_mutate);
1070}
1071
1072#[cfg(test)]
1073fn test_submatrix_col_iter<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1074 assert_submatrix_eq([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], &mut matrix);
1075 {
1076 let mut it = matrix.reborrow().col_iter();
1077 assert_eq!(
1078 vec![2, 7, 12],
1079 it.by_ref()
1080 .skip(1)
1081 .next()
1082 .unwrap()
1083 .into_iter()
1084 .map(|x| *x)
1085 .collect::<Vec<_>>()
1086 );
1087 assert_eq!(
1088 vec![4, 9, 14],
1089 it.by_ref()
1090 .skip(1)
1091 .next()
1092 .unwrap()
1093 .into_iter()
1094 .map(|x| *x)
1095 .collect::<Vec<_>>()
1096 );
1097 let mut last_col = it.next().unwrap();
1098 for x in last_col.reborrow() {
1099 *x *= 2;
1100 }
1101 assert_eq!(vec![10, 20, 30], last_col.into_iter().map(|x| *x).collect::<Vec<_>>());
1102 }
1103 assert_submatrix_eq([[1, 2, 3, 4, 10], [6, 7, 8, 9, 20], [11, 12, 13, 14, 30]], &mut matrix);
1104
1105 let (left, _right) = matrix.reborrow().split_cols(0..2, 3..4);
1106 {
1107 let mut it = left.col_iter();
1108 let mut col1 = it.next().unwrap();
1109 let mut col2 = it.next().unwrap();
1110 assert!(it.next().is_none());
1111 assert_eq!(vec![1, 6, 11], col1.as_iter().map(|x| *x).collect::<Vec<_>>());
1112 assert_eq!(vec![2, 7, 12], col2.as_iter().map(|x| *x).collect::<Vec<_>>());
1113 assert_eq!(
1114 vec![1, 6, 11],
1115 col1.reborrow().into_iter().map(|x| *x).collect::<Vec<_>>()
1116 );
1117 assert_eq!(
1118 vec![2, 7, 12],
1119 col2.reborrow().into_iter().map(|x| *x).collect::<Vec<_>>()
1120 );
1121 *col1.into_iter().skip(1).next().unwrap() += 5;
1122 }
1123 assert_submatrix_eq([[1, 2, 3, 4, 10], [11, 7, 8, 9, 20], [11, 12, 13, 14, 30]], &mut matrix);
1124
1125 let (_left, right) = matrix.reborrow().split_cols(0..2, 3..4);
1126 {
1127 let mut it = right.col_iter();
1128 let mut col = it.next().unwrap();
1129 assert!(it.next().is_none());
1130 assert_eq!(vec![4, 9, 14], col.reborrow().as_iter().map(|x| *x).collect::<Vec<_>>());
1131 *col.into_iter().next().unwrap() += 3;
1132 }
1133 assert_submatrix_eq([[1, 2, 3, 7, 10], [11, 7, 8, 9, 20], [11, 12, 13, 14, 30]], &mut matrix);
1134}
1135
1136#[test]
1137fn test_submatrix_col_iter_wrapper() {
1138 with_testmatrix_vec(test_submatrix_col_iter);
1139 with_testmatrix_array(test_submatrix_col_iter);
1140 with_testmatrix_linmem(test_submatrix_col_iter);
1141 with_testmatrix_ndarray(test_submatrix_col_iter);
1142}
1143
1144#[cfg(test)]
1145fn test_submatrix_row_iter<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1146 assert_submatrix_eq([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], &mut matrix);
1147 {
1148 let mut it = matrix.reborrow().row_iter();
1149 assert_eq!(&[6, 7, 8, 9, 10], it.by_ref().skip(1).next().unwrap());
1150 let row = it.next().unwrap();
1151 assert!(it.next().is_none());
1152 row[1] += 6;
1153 row[4] *= 2;
1154 }
1155 assert_submatrix_eq([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 18, 13, 14, 30]], &mut matrix);
1156 let (mut left, mut right) = matrix.reborrow().split_cols(0..2, 3..4);
1157 {
1158 let mut it = left.reborrow().row_iter();
1159 let row1 = it.next().unwrap();
1160 let row2 = it.next().unwrap();
1161 assert!(it.next().is_some());
1162 assert!(it.next().is_none());
1163 assert_eq!(&[1, 2], row1);
1164 assert_eq!(&[6, 7], row2);
1165 }
1166 {
1167 let mut it = left.reborrow().row_iter();
1168 let row1 = it.next().unwrap();
1169 let row2 = it.next().unwrap();
1170 assert!(it.next().is_some());
1171 assert!(it.next().is_none());
1172 assert_eq!(&[1, 2], row1);
1173 assert_eq!(&[6, 7], row2);
1174 row2[1] += 1;
1175 }
1176 assert_submatrix_eq([[1, 2], [6, 8], [11, 18]], &mut left);
1177 {
1178 right = right.submatrix(1..3, 0..1);
1179 let mut it = right.reborrow().row_iter();
1180 let row1 = it.next().unwrap();
1181 let row2 = it.next().unwrap();
1182 assert_eq!(&[9], row1);
1183 assert_eq!(&[14], row2);
1184 row1[0] += 1;
1185 }
1186 assert_submatrix_eq([[10], [14]], &mut right);
1187}
1188
1189#[test]
1190fn test_submatrix_row_iter_wrapper() {
1191 with_testmatrix_vec(test_submatrix_row_iter);
1192 with_testmatrix_array(test_submatrix_row_iter);
1193 with_testmatrix_linmem(test_submatrix_row_iter);
1194 with_testmatrix_ndarray(test_submatrix_row_iter);
1195}
1196
1197#[cfg(test)]
1198fn test_submatrix_col_at<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1199 assert_submatrix_eq([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], &mut matrix);
1200 assert_eq!(
1201 &[2, 7, 12],
1202 &matrix.col_at(1).as_iter().copied().collect::<Vec<_>>()[..]
1203 );
1204 assert_eq!(
1205 &[2, 7, 12],
1206 &matrix.as_const().col_at(1).as_iter().copied().collect::<Vec<_>>()[..]
1207 );
1208 assert_eq!(
1209 &[5, 10, 15],
1210 &matrix.col_at(4).as_iter().copied().collect::<Vec<_>>()[..]
1211 );
1212 assert_eq!(
1213 &[5, 10, 15],
1214 &matrix.as_const().col_at(4).as_iter().copied().collect::<Vec<_>>()[..]
1215 );
1216
1217 {
1218 let (mut top, mut bottom) = matrix.reborrow().restrict_rows(0..2).split_rows(0..1, 1..2);
1219 assert_eq!(&[1], &top.col_mut_at(0).as_iter().copied().collect::<Vec<_>>()[..]);
1220 assert_eq!(
1221 &[1],
1222 &top.as_const().col_at(0).as_iter().copied().collect::<Vec<_>>()[..]
1223 );
1224 assert_eq!(&[1], &top.col_at(0).as_iter().copied().collect::<Vec<_>>()[..]);
1225 assert_eq!(&[5], &top.col_mut_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1226 assert_eq!(
1227 &[5],
1228 &top.as_const().col_at(4).as_iter().copied().collect::<Vec<_>>()[..]
1229 );
1230 assert_eq!(&[5], &top.col_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1231
1232 assert_eq!(&[6], &bottom.col_mut_at(0).as_iter().copied().collect::<Vec<_>>()[..]);
1233 assert_eq!(
1234 &[6],
1235 &bottom.as_const().col_at(0).as_iter().copied().collect::<Vec<_>>()[..]
1236 );
1237 assert_eq!(&[6], &bottom.col_at(0).as_iter().copied().collect::<Vec<_>>()[..]);
1238 assert_eq!(&[10], &bottom.col_mut_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1239 assert_eq!(
1240 &[10],
1241 &bottom.as_const().col_at(4).as_iter().copied().collect::<Vec<_>>()[..]
1242 );
1243 assert_eq!(&[10], &bottom.col_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1244 }
1245}
1246
1247#[test]
1248fn test_submatrix_col_at_wrapper() {
1249 with_testmatrix_vec(test_submatrix_col_at);
1250 with_testmatrix_array(test_submatrix_col_at);
1251 with_testmatrix_linmem(test_submatrix_col_at);
1252 with_testmatrix_ndarray(test_submatrix_col_at);
1253}
1254
1255#[cfg(test)]
1256fn test_submatrix_row_at<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1257 assert_submatrix_eq([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], &mut matrix);
1258 assert_eq!(
1259 &[2, 7, 12],
1260 &matrix.col_at(1).as_iter().copied().collect::<Vec<_>>()[..]
1261 );
1262 assert_eq!(
1263 &[2, 7, 12],
1264 &matrix.as_const().col_at(1).as_iter().copied().collect::<Vec<_>>()[..]
1265 );
1266 assert_eq!(
1267 &[5, 10, 15],
1268 &matrix.col_at(4).as_iter().copied().collect::<Vec<_>>()[..]
1269 );
1270 assert_eq!(
1271 &[5, 10, 15],
1272 &matrix.as_const().col_at(4).as_iter().copied().collect::<Vec<_>>()[..]
1273 );
1274
1275 {
1276 let (mut left, mut right) = matrix.reborrow().restrict_cols(1..5).split_cols(0..2, 2..4);
1277 assert_eq!(&[2, 3], left.row_mut_at(0));
1278 assert_eq!(&[4, 5], right.row_mut_at(0));
1279 assert_eq!(&[2, 3], left.as_const().row_at(0));
1280 assert_eq!(&[4, 5], right.as_const().row_at(0));
1281 assert_eq!(&[2, 3], left.row_at(0));
1282 assert_eq!(&[4, 5], right.row_at(0));
1283
1284 assert_eq!(&[7, 8], left.row_mut_at(1));
1285 assert_eq!(&[9, 10], right.row_mut_at(1));
1286 assert_eq!(&[7, 8], left.as_const().row_at(1));
1287 assert_eq!(&[9, 10], right.as_const().row_at(1));
1288 assert_eq!(&[7, 8], left.row_at(1));
1289 assert_eq!(&[9, 10], right.row_at(1));
1290 }
1291}
1292
1293#[test]
1294fn test_submatrix_row_at_wrapper() {
1295 with_testmatrix_vec(test_submatrix_row_at);
1296 with_testmatrix_array(test_submatrix_row_at);
1297 with_testmatrix_linmem(test_submatrix_row_at);
1298 with_testmatrix_ndarray(test_submatrix_row_at);
1299}