1use std::fmt::{Debug, Formatter};
2use std::marker::PhantomData;
3use std::mem::MaybeUninit;
4#[cfg(test)]
5use std::num::NonZeroI64;
6use std::ops::{Deref, Range};
7use std::ptr::{NonNull, addr_of_mut};
8
9#[cfg(feature = "ndarray")]
10use ndarray::{ArrayBase, DataMut, Ix2};
11
12use crate::seq::{SwappableVectorViewMut, VectorView, VectorViewMut};
13
14pub unsafe trait AsPointerToSlice<T> {
32 unsafe fn get_pointer(self_: NonNull<Self>) -> NonNull<T>;
47}
48
49unsafe impl<T> AsPointerToSlice<T> for Vec<MaybeUninit<T>> {
50 unsafe fn get_pointer(self_: NonNull<Self>) -> NonNull<T> {
51 unsafe { NonNull::new((*self_.as_ptr()).as_mut_ptr() as *mut T).unwrap() }
55 }
56}
57
58unsafe impl<T> AsPointerToSlice<T> for Vec<T> {
59 unsafe fn get_pointer(self_: NonNull<Self>) -> NonNull<T> {
60 unsafe { NonNull::new((*self_.as_ptr()).as_mut_ptr() as *mut T).unwrap() }
64 }
65}
66
67#[repr(transparent)]
72#[deprecated]
73#[derive(Clone, Copy, PartialEq, Eq)]
74pub struct DerefArray<T, const SIZE: usize> {
75 pub data: [T; SIZE],
77}
78
79#[allow(deprecated)]
80impl<T: std::fmt::Debug, const SIZE: usize> std::fmt::Debug for DerefArray<T, SIZE> {
81 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.data.fmt(f) }
82}
83
84#[allow(deprecated)]
85impl<T, const SIZE: usize> From<[T; SIZE]> for DerefArray<T, SIZE> {
86 fn from(value: [T; SIZE]) -> Self { Self { data: value } }
87}
88
89#[allow(deprecated)]
90impl<'a, T, const SIZE: usize> From<&'a [T; SIZE]> for &'a DerefArray<T, SIZE> {
91 fn from(value: &'a [T; SIZE]) -> Self { unsafe { std::mem::transmute(value) } }
92}
93
94#[allow(deprecated)]
95impl<'a, T, const SIZE: usize> From<&'a mut [T; SIZE]> for &'a mut DerefArray<T, SIZE> {
96 fn from(value: &'a mut [T; SIZE]) -> Self { unsafe { std::mem::transmute(value) } }
97}
98
99#[allow(deprecated)]
100impl<T, const SIZE: usize> Deref for DerefArray<T, SIZE> {
101 type Target = [T];
102
103 fn deref(&self) -> &Self::Target { &self.data[..] }
104}
105
106#[allow(deprecated)]
107unsafe impl<T, const SIZE: usize> AsPointerToSlice<T> for DerefArray<T, SIZE> {
108 unsafe fn get_pointer(self_: NonNull<Self>) -> NonNull<T> {
109 unsafe {
110 let self_ptr = self_.as_ptr();
111 let data_ptr = addr_of_mut!((*self_ptr).data);
112 NonNull::new((*data_ptr).as_mut_ptr()).unwrap()
113 }
114 }
115}
116
117#[repr(transparent)]
121pub struct AsFirstElement<T>(T);
122
123unsafe impl<'a, T> AsPointerToSlice<T> for AsFirstElement<T> {
124 unsafe fn get_pointer(self_: NonNull<Self>) -> NonNull<T> { unsafe { std::mem::transmute(self_) } }
125}
126
127unsafe impl<'a, T> AsPointerToSlice<T> for AsFirstElement<MaybeUninit<T>> {
128 unsafe fn get_pointer(self_: NonNull<Self>) -> NonNull<T> { unsafe { std::mem::transmute(self_) } }
129}
130
131#[stability::unstable(feature = "enable")]
169pub struct SubmatrixRaw<V, T>
170where
171 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>
186where
187 V: AsPointerToSlice<T> + Sync,
188 T: Sync,
189{
190}
191
192unsafe impl<V, T> Sync for SubmatrixRaw<V, T>
193where
194 V: AsPointerToSlice<T> + Sync,
195 T: Sync,
196{
197}
198
199impl<V, T> Clone for SubmatrixRaw<V, T>
200where
201 V: AsPointerToSlice<T>,
202{
203 fn clone(&self) -> Self { *self }
204}
205
206impl<V, T> Copy for SubmatrixRaw<V, T> where V: AsPointerToSlice<T> {}
207
208impl<V, T> SubmatrixRaw<V, T>
209where
210 V: AsPointerToSlice<T>,
211{
212 #[stability::unstable(feature = "enable")]
226 pub unsafe fn new(
227 rows: NonNull<V>,
228 row_count: usize,
229 row_step: isize,
230 cols_start: usize,
231 col_count: usize,
232 ) -> Self {
233 Self {
234 entry: PhantomData,
235 row_count,
236 row_step,
237 rows,
238 col_start: cols_start,
239 col_count,
240 }
241 }
242
243 #[stability::unstable(feature = "enable")]
244 pub fn restrict_rows(mut self, rows: Range<usize>) -> Self {
245 assert!(rows.start <= rows.end);
246 assert!(rows.end <= self.row_count);
247 unsafe {
255 self.row_count = rows.end - rows.start;
256 self.rows = self.rows.offset(rows.start as isize * self.row_step);
257 }
258 self
259 }
260
261 #[stability::unstable(feature = "enable")]
262 pub fn restrict_cols(mut self, cols: Range<usize>) -> Self {
263 assert!(cols.start <= cols.end);
264 assert!(cols.end <= self.col_count);
265 self.col_count = cols.end - cols.start;
266 self.col_start += cols.start;
267 self
268 }
269
270 #[stability::unstable(feature = "enable")]
273 pub fn row_at(&self, row: usize) -> NonNull<[T]> {
274 assert!(row < self.row_count);
275 let row_ref = unsafe { V::get_pointer(self.rows.offset(row as isize * self.row_step)) };
278 unsafe { NonNull::slice_from_raw_parts(row_ref.offset(self.col_start as isize), self.col_count) }
280 }
281
282 #[stability::unstable(feature = "enable")]
285 pub fn entry_at(&self, row: usize, col: usize) -> NonNull<T> {
286 assert!(
287 row < self.row_count,
288 "Row index {} out of range 0..{}",
289 row,
290 self.row_count
291 );
292 assert!(
293 col < self.col_count,
294 "Col index {} out of range 0..{}",
295 col,
296 self.col_count
297 );
298 let row_ref = unsafe { V::get_pointer(self.rows.offset(row as isize * self.row_step)) };
301 unsafe { row_ref.offset(self.col_start as isize + col as isize) }
303 }
304}
305
306impl<V, T> SubmatrixRaw<V, MaybeUninit<T>>
307where
308 V: AsPointerToSlice<T> + AsPointerToSlice<MaybeUninit<T>>,
309{
310 #[stability::unstable(feature = "enable")]
314 pub unsafe fn assume_init(self) -> SubmatrixRaw<V, T> {
315 SubmatrixRaw {
316 entry: PhantomData,
317 rows: self.rows,
318 row_count: self.row_count,
319 row_step: self.row_step,
320 col_start: self.col_start,
321 col_count: self.col_count,
322 }
323 }
324}
325
326impl<V, T> SubmatrixRaw<V, T>
327where
328 V: AsPointerToSlice<T> + AsPointerToSlice<MaybeUninit<T>>,
329{
330 #[stability::unstable(feature = "enable")]
333 pub fn assume_uninit(self) -> SubmatrixRaw<V, MaybeUninit<T>> {
334 SubmatrixRaw {
335 entry: PhantomData,
336 rows: self.rows,
337 row_count: self.row_count,
338 row_step: self.row_step,
339 col_start: self.col_start,
340 col_count: self.col_count,
341 }
342 }
343}
344
345pub struct Column<'a, V, T>
347where
348 V: AsPointerToSlice<T>,
349{
350 entry: PhantomData<&'a T>,
351 raw_data: SubmatrixRaw<V, T>,
352}
353
354impl<'a, V, T> Column<'a, V, T>
355where
356 V: AsPointerToSlice<T>,
357{
358 unsafe fn new(raw_data: SubmatrixRaw<V, T>) -> Self {
368 assert!(raw_data.col_count == 1);
369 Self {
370 entry: PhantomData,
371 raw_data,
372 }
373 }
374}
375
376impl<'a, V, T: Debug> Debug for Column<'a, V, T>
377where
378 V: AsPointerToSlice<T>,
379{
380 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
381 let mut output = f.debug_list();
382 for x in self.as_iter() {
383 _ = output.entry(x);
384 }
385 output.finish()
386 }
387}
388
389impl<'a, V, T> Clone for Column<'a, V, T>
390where
391 V: AsPointerToSlice<T>,
392{
393 fn clone(&self) -> Self { *self }
394}
395
396impl<'a, V, T> Copy for Column<'a, V, T> where V: AsPointerToSlice<T> {}
397
398impl<'a, V, T> VectorView<T> for Column<'a, V, T>
399where
400 V: AsPointerToSlice<T>,
401{
402 fn len(&self) -> usize { self.raw_data.row_count }
403
404 fn at(&self, i: usize) -> &T {
405 unsafe { self.raw_data.entry_at(i, 0).as_ref() }
407 }
408}
409
410pub struct ColumnMut<'a, V, T>
414where
415 V: AsPointerToSlice<T>,
416{
417 entry: PhantomData<&'a mut T>,
418 raw_data: SubmatrixRaw<V, T>,
419}
420
421impl<'a, V, T: Debug> Debug for ColumnMut<'a, V, T>
422where
423 V: AsPointerToSlice<T>,
424{
425 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { self.as_const().fmt(f) }
426}
427
428impl<'a, V, T> ColumnMut<'a, V, T>
429where
430 V: AsPointerToSlice<T>,
431{
432 unsafe fn new(raw_data: SubmatrixRaw<V, T>) -> Self {
443 assert!(raw_data.col_count == 1);
444 Self {
445 entry: PhantomData,
446 raw_data,
447 }
448 }
449
450 pub fn reborrow<'b>(&'b mut self) -> ColumnMut<'b, V, T> {
454 ColumnMut {
455 entry: PhantomData,
456 raw_data: self.raw_data,
457 }
458 }
459
460 pub fn two_entries(&mut self, i: usize, j: usize) -> (&mut T, &mut T) {
466 assert!(i != j);
467 unsafe {
469 (
470 self.raw_data.entry_at(i, 0).as_mut(),
471 self.raw_data.entry_at(j, 0).as_mut(),
472 )
473 }
474 }
475
476 pub fn as_const<'b>(&'b self) -> Column<'b, V, T> {
478 Column {
479 entry: PhantomData,
480 raw_data: self.raw_data,
481 }
482 }
483}
484
485unsafe impl<'a, V, T> Send for ColumnMut<'a, V, T>
486where
487 V: AsPointerToSlice<T> + Sync,
488 T: Send,
489{
490}
491
492impl<'a, V, T> VectorView<T> for ColumnMut<'a, V, T>
493where
494 V: AsPointerToSlice<T>,
495{
496 fn len(&self) -> usize { self.raw_data.row_count }
497
498 fn at(&self, i: usize) -> &T {
499 unsafe { self.raw_data.entry_at(i, 0).as_ref() }
501 }
502}
503
504pub struct ColumnMutIter<'a, V, T>
507where
508 V: AsPointerToSlice<T>,
509{
510 column_mut: ColumnMut<'a, V, T>,
511}
512
513impl<'a, V, T> Iterator for ColumnMutIter<'a, V, T>
514where
515 V: AsPointerToSlice<T>,
516{
517 type Item = &'a mut T;
518
519 fn next(&mut self) -> Option<Self::Item> {
520 if self.column_mut.raw_data.row_count > 0 {
521 let mut result = self.column_mut.raw_data.entry_at(0, 0);
522 self.column_mut.raw_data = self
523 .column_mut
524 .raw_data
525 .restrict_rows(1..self.column_mut.raw_data.row_count);
526 unsafe { Some(result.as_mut()) }
529 } else {
530 None
531 }
532 }
533}
534
535impl<'a, V, T> IntoIterator for ColumnMut<'a, V, T>
536where
537 V: AsPointerToSlice<T>,
538{
539 type Item = &'a mut T;
540 type IntoIter = ColumnMutIter<'a, V, T>;
541
542 fn into_iter(self) -> ColumnMutIter<'a, V, T> { ColumnMutIter { column_mut: self } }
543}
544
545impl<'a, V, T> VectorViewMut<T> for ColumnMut<'a, V, T>
546where
547 V: AsPointerToSlice<T>,
548{
549 fn at_mut(&mut self, i: usize) -> &mut T {
550 unsafe { self.raw_data.entry_at(i, 0).as_mut() }
552 }
553}
554
555impl<'a, V, T> SwappableVectorViewMut<T> for ColumnMut<'a, V, T>
556where
557 V: AsPointerToSlice<T>,
558{
559 fn swap(&mut self, i: usize, j: usize) {
560 if i != j {
561 unsafe {
565 std::mem::swap(
566 self.raw_data.entry_at(i, 0).as_mut(),
567 self.raw_data.entry_at(j, 0).as_mut(),
568 );
569 }
570 }
571 }
572}
573
574pub struct Submatrix<'a, V, T>
584where
585 V: 'a + AsPointerToSlice<T>,
586{
587 entry: PhantomData<&'a T>,
588 raw_data: SubmatrixRaw<V, T>,
589}
590
591impl<'a, V, T> Submatrix<'a, V, T>
592where
593 V: 'a + AsPointerToSlice<T>,
594{
595 pub fn submatrix(self, rows: Range<usize>, cols: Range<usize>) -> Self {
598 self.restrict_rows(rows).restrict_cols(cols)
599 }
600
601 pub fn restrict_rows(self, rows: Range<usize>) -> Self {
604 Self {
605 entry: PhantomData,
606 raw_data: self.raw_data.restrict_rows(rows),
607 }
608 }
609
610 pub fn into_at(self, i: usize, j: usize) -> &'a T { &self.into_row_at(i)[j] }
616
617 pub fn at(&self, i: usize, j: usize) -> &T { &self.row_at(i)[j] }
619
620 pub fn restrict_cols(self, cols: Range<usize>) -> Self {
623 Self {
624 entry: PhantomData,
625 raw_data: self.raw_data.restrict_cols(cols),
626 }
627 }
628
629 pub fn row_iter(self) -> impl 'a + Clone + ExactSizeIterator<Item = &'a [T]> {
631 (0..self.raw_data.row_count).map(move |i|
632 unsafe {
634 self.raw_data.row_at(i).as_ref()
635 })
636 }
637
638 pub fn col_iter(self) -> impl 'a + Clone + ExactSizeIterator<Item = Column<'a, V, T>> {
640 (0..self.raw_data.col_count).map(move |j| {
641 debug_assert!(j < self.raw_data.col_count);
642 let mut result_raw = self.raw_data;
643 result_raw.col_start += j;
644 result_raw.col_count = 1;
645 unsafe {
647 return Column::new(result_raw);
648 }
649 })
650 }
651
652 pub fn into_row_at(self, i: usize) -> &'a [T] {
658 unsafe { self.raw_data.row_at(i).as_ref() }
660 }
661
662 pub fn row_at(&self, i: usize) -> &[T] {
664 unsafe { self.raw_data.row_at(i).as_ref() }
666 }
667
668 pub fn into_col_at(self, j: usize) -> Column<'a, V, T> {
674 assert!(j < self.raw_data.col_count);
675 let mut result_raw = self.raw_data;
676 result_raw.col_start += j;
677 result_raw.col_count = 1;
678 unsafe {
680 return Column::new(result_raw);
681 }
682 }
683
684 pub fn col_at<'b>(&'b self, j: usize) -> Column<'b, V, T> {
686 assert!(j < self.raw_data.col_count);
687 let mut result_raw = self.raw_data;
688 result_raw.col_start += j;
689 result_raw.col_count = 1;
690 unsafe {
692 return Column::new(result_raw);
693 }
694 }
695
696 pub fn col_count(&self) -> usize { self.raw_data.col_count }
698
699 pub fn row_count(&self) -> usize { self.raw_data.row_count }
701}
702
703impl<'a, V, T> Submatrix<'a, V, MaybeUninit<T>>
704where
705 V: 'a + AsPointerToSlice<T> + AsPointerToSlice<MaybeUninit<T>>,
706{
707 pub unsafe fn assume_init(self) -> Submatrix<'a, V, T> {
710 let data_new = unsafe { self.raw_data.assume_init() };
712 Submatrix {
713 entry: PhantomData,
714 raw_data: data_new,
715 }
716 }
717}
718
719impl<'a, V, T> Submatrix<'a, V, T>
720where
721 V: 'a + AsPointerToSlice<T> + AsPointerToSlice<MaybeUninit<T>>,
722{
723 #[stability::unstable(feature = "enable")]
726 pub fn assume_uninit(self) -> Submatrix<'a, V, MaybeUninit<T>> {
727 Submatrix {
728 entry: PhantomData,
729 raw_data: self.raw_data.assume_uninit(),
730 }
731 }
732}
733
734impl<'a, V, T: Debug> Debug for Submatrix<'a, V, T>
735where
736 V: 'a + AsPointerToSlice<T>,
737{
738 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
739 let mut output = f.debug_list();
740 for row in self.row_iter() {
741 _ = output.entry(&row);
742 }
743 output.finish()
744 }
745}
746
747impl<'a, V, T> Clone for Submatrix<'a, V, T>
748where
749 V: 'a + AsPointerToSlice<T>,
750{
751 fn clone(&self) -> Self { *self }
752}
753
754impl<'a, V, T> Copy for Submatrix<'a, V, T> where V: 'a + AsPointerToSlice<T> {}
755
756pub struct SubmatrixMut<'a, V, T>
764where
765 V: 'a + AsPointerToSlice<T>,
766{
767 entry: PhantomData<&'a mut T>,
768 raw_data: SubmatrixRaw<V, T>,
769}
770
771impl<'a, V, T> SubmatrixMut<'a, V, T>
772where
773 V: 'a + AsPointerToSlice<T>,
774{
775 pub fn submatrix(self, rows: Range<usize>, cols: Range<usize>) -> Self {
778 self.restrict_rows(rows).restrict_cols(cols)
779 }
780
781 pub fn restrict_rows(self, rows: Range<usize>) -> Self {
784 Self {
785 entry: PhantomData,
786 raw_data: self.raw_data.restrict_rows(rows),
787 }
788 }
789
790 pub fn restrict_cols(self, cols: Range<usize>) -> Self {
793 Self {
794 entry: PhantomData,
795 raw_data: self.raw_data.restrict_cols(cols),
796 }
797 }
798
799 pub fn split_rows(self, fst_rows: Range<usize>, snd_rows: Range<usize>) -> (Self, Self) {
804 assert!(fst_rows.end <= snd_rows.start || snd_rows.end <= fst_rows.start);
805 (
806 Self {
807 entry: PhantomData,
808 raw_data: self.raw_data.restrict_rows(fst_rows),
809 },
810 Self {
811 entry: PhantomData,
812 raw_data: self.raw_data.restrict_rows(snd_rows),
813 },
814 )
815 }
816
817 pub fn split_cols(self, fst_cols: Range<usize>, snd_cols: Range<usize>) -> (Self, Self) {
822 assert!(fst_cols.end <= snd_cols.start || snd_cols.end <= fst_cols.start);
823 (
824 Self {
825 entry: PhantomData,
826 raw_data: self.raw_data.restrict_cols(fst_cols),
827 },
828 Self {
829 entry: PhantomData,
830 raw_data: self.raw_data.restrict_cols(snd_cols),
831 },
832 )
833 }
834
835 pub fn row_iter(self) -> impl 'a + ExactSizeIterator<Item = &'a mut [T]> {
837 (0..self.raw_data.row_count).map(move |i|
838 unsafe {
840 self.raw_data.row_at(i).as_mut()
841 })
842 }
843
844 pub fn col_iter(self) -> impl 'a + ExactSizeIterator<Item = ColumnMut<'a, V, T>> {
846 (0..self.raw_data.col_count).map(move |j| {
847 let mut result_raw = self.raw_data;
848 result_raw.col_start += j;
849 result_raw.col_count = 1;
850 unsafe {
852 return ColumnMut::new(result_raw);
853 }
854 })
855 }
856
857 pub fn into_at_mut(self, i: usize, j: usize) -> &'a mut T { &mut self.into_row_mut_at(i)[j] }
863
864 pub fn at_mut(&mut self, i: usize, j: usize) -> &mut T { &mut self.row_mut_at(i)[j] }
866
867 pub fn at(&self, i: usize, j: usize) -> &T { self.as_const().into_at(i, j) }
869
870 pub fn row_at(&self, i: usize) -> &[T] { self.as_const().into_row_at(i) }
872
873 pub fn into_row_mut_at(self, i: usize) -> &'a mut [T] {
879 unsafe { self.raw_data.row_at(i).as_mut() }
881 }
882
883 pub fn row_mut_at(&mut self, i: usize) -> &mut [T] { self.reborrow().into_row_mut_at(i) }
885
886 pub fn col_at<'b>(&'b self, j: usize) -> Column<'b, V, T> { self.as_const().into_col_at(j) }
888
889 pub fn col_mut_at<'b>(&'b mut self, j: usize) -> ColumnMut<'b, V, T> {
891 assert!(j < self.raw_data.col_count);
892 let mut result_raw = self.raw_data;
893 result_raw.col_start += j;
894 result_raw.col_count = 1;
895 unsafe {
897 return ColumnMut::new(result_raw);
898 }
899 }
900
901 pub fn reborrow<'b>(&'b mut self) -> SubmatrixMut<'b, V, T> {
905 SubmatrixMut {
906 entry: PhantomData,
907 raw_data: self.raw_data,
908 }
909 }
910
911 pub fn as_const<'b>(&'b self) -> Submatrix<'b, V, T> {
913 Submatrix {
914 entry: PhantomData,
915 raw_data: self.raw_data,
916 }
917 }
918
919 pub fn col_count(&self) -> usize { self.raw_data.col_count }
921
922 pub fn row_count(&self) -> usize { self.raw_data.row_count }
924}
925
926impl<'a, V, T> SubmatrixMut<'a, V, MaybeUninit<T>>
927where
928 V: 'a + AsPointerToSlice<T> + AsPointerToSlice<MaybeUninit<T>>,
929{
930 pub unsafe fn assume_init(self) -> SubmatrixMut<'a, V, T> {
933 let data_new = unsafe { self.raw_data.assume_init() };
935 SubmatrixMut {
936 entry: PhantomData,
937 raw_data: data_new,
938 }
939 }
940}
941
942impl<'a, V, T> SubmatrixMut<'a, V, T>
943where
944 V: 'a + AsPointerToSlice<T> + AsPointerToSlice<MaybeUninit<T>>,
945{
946 #[stability::unstable(feature = "enable")]
949 pub fn assume_uninit(self) -> SubmatrixMut<'a, V, MaybeUninit<T>> {
950 SubmatrixMut {
951 entry: PhantomData,
952 raw_data: self.raw_data.assume_uninit(),
953 }
954 }
955}
956
957impl<'a, V, T: Debug> Debug for SubmatrixMut<'a, V, T>
958where
959 V: 'a + AsPointerToSlice<T>,
960{
961 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { self.as_const().fmt(f) }
962}
963
964impl<'a, T> SubmatrixMut<'a, AsFirstElement<T>, T> {
965 pub fn from_1d(data: &'a mut [T], row_count: usize, col_count: usize) -> Self {
969 assert_eq!(row_count * col_count, data.len());
970 unsafe {
971 Self {
972 entry: PhantomData,
973 raw_data: SubmatrixRaw::new(
974 std::mem::transmute(NonNull::new(data.as_mut_ptr()).unwrap_unchecked()),
975 row_count,
976 col_count as isize,
977 0,
978 col_count,
979 ),
980 }
981 }
982 }
983
984 #[doc(cfg(feature = "ndarray"))]
985 #[cfg(feature = "ndarray")]
986 pub fn from_ndarray<S>(data: &'a mut ArrayBase<S, Ix2>) -> Self
987 where
988 S: DataMut<Elem = T>,
989 {
990 assert!(data.is_standard_layout());
991 let (nrows, ncols) = (data.nrows(), data.ncols());
992 return Self::new(data.as_slice_mut().unwrap(), nrows, ncols);
993 }
994}
995
996impl<'a, V: AsPointerToSlice<T> + Deref<Target = [T]>, T> SubmatrixMut<'a, V, T> {
997 pub fn from_2d(data: &'a mut [V]) -> Self {
1000 assert!(!data.is_empty());
1001 let row_count = data.len();
1002 let col_count = data[0].len();
1003 for row in data.iter() {
1004 assert_eq!(col_count, row.len());
1005 }
1006 unsafe {
1007 Self {
1008 entry: PhantomData,
1009 raw_data: SubmatrixRaw::new(
1010 NonNull::new(data.as_mut_ptr() as *mut _).unwrap_unchecked(),
1011 row_count,
1012 1,
1013 0,
1014 col_count,
1015 ),
1016 }
1017 }
1018 }
1019}
1020
1021impl<'a, T> Submatrix<'a, AsFirstElement<T>, T> {
1022 pub fn from_1d(data: &'a [T], row_count: usize, col_count: usize) -> Self {
1026 assert_eq!(row_count * col_count, data.len());
1027 unsafe {
1028 Self {
1029 entry: PhantomData,
1030 raw_data: SubmatrixRaw::new(
1031 std::mem::transmute(NonNull::new(data.as_ptr() as *mut T).unwrap_unchecked()),
1032 row_count,
1033 col_count as isize,
1034 0,
1035 col_count,
1036 ),
1037 }
1038 }
1039 }
1040
1041 #[doc(cfg(feature = "ndarray"))]
1042 #[cfg(feature = "ndarray")]
1043 pub fn from_ndarray<S>(data: &'a ArrayBase<S, Ix2>) -> Self
1044 where
1045 S: DataMut<Elem = T>,
1046 {
1047 let (nrows, ncols) = (data.nrows(), data.ncols());
1048 return Self::new(data.as_slice().unwrap(), nrows, ncols);
1049 }
1050}
1051
1052impl<'a, V: AsPointerToSlice<T> + Deref<Target = [T]>, T> Submatrix<'a, V, T> {
1053 pub fn from_2d(data: &'a [V]) -> Self {
1056 assert!(!data.is_empty());
1057 let row_count = data.len();
1058 let col_count = data[0].len();
1059 for row in data.iter() {
1060 assert_eq!(col_count, row.len());
1061 }
1062 unsafe {
1063 Self {
1064 entry: PhantomData,
1065 raw_data: SubmatrixRaw::new(
1066 NonNull::new(data.as_ptr() as *mut _).unwrap_unchecked(),
1067 row_count,
1068 1,
1069 0,
1070 col_count,
1071 ),
1072 }
1073 }
1074 }
1075}
1076
1077impl<'a, V: AsPointerToSlice<T> + AsPointerToSlice<MaybeUninit<T>> + Deref<Target = [T]>, T>
1078 Submatrix<'a, V, MaybeUninit<T>>
1079{
1080 pub fn from_2d_maybe_uninit(data: &'a [V]) -> Self {
1083 assert!(data.len() > 0);
1084 let row_count = data.len();
1085 let col_count = data[0].len();
1086 for row in data.iter() {
1087 assert_eq!(col_count, row.len());
1088 }
1089 unsafe {
1090 Self {
1091 entry: PhantomData,
1092 raw_data: SubmatrixRaw::new(
1093 NonNull::new(data.as_ptr() as *mut _).unwrap_unchecked(),
1094 row_count,
1095 1,
1096 0,
1097 col_count,
1098 ),
1099 }
1100 }
1101 }
1102}
1103
1104#[cfg(test)]
1105fn assert_submatrix_eq<V: AsPointerToSlice<T>, T: PartialEq + Debug, const N: usize, const M: usize>(
1106 expected: [[T; M]; N],
1107 actual: &mut SubmatrixMut<V, T>,
1108) {
1109 assert_eq!(N, actual.row_count());
1110 assert_eq!(M, actual.col_count());
1111 for i in 0..N {
1112 for j in 0..M {
1113 assert_eq!(&expected[i][j], actual.at(i, j));
1114 assert_eq!(&expected[i][j], actual.as_const().at(i, j));
1115 }
1116 }
1117}
1118
1119#[cfg(test)]
1120fn with_testmatrix_vec_maybe_uninit<F>(f: F)
1121where
1122 F: FnOnce(SubmatrixMut<Vec<MaybeUninit<NonZeroI64>>, NonZeroI64>),
1123{
1124 let mut data = vec![vec![1, 2, 3, 4, 5], vec![6, 7, 8, 9, 10], vec![11, 12, 13, 14, 15]]
1125 .into_iter()
1126 .map(|x| {
1127 x.into_iter()
1128 .map(|x| MaybeUninit::new(NonZeroI64::new(x).unwrap()))
1129 .collect::<Vec<_>>()
1130 })
1131 .collect::<Vec<_>>();
1132 let matrix = SubmatrixMut::<Vec<MaybeUninit<NonZeroI64>>, MaybeUninit<NonZeroI64>>::from_2d(&mut data[..]);
1133 let matrix = unsafe { matrix.assume_init() };
1134 f(matrix)
1135}
1136
1137#[cfg(test)]
1138fn with_testmatrix_linmem_maybe_uninit<F>(f: F)
1139where
1140 F: FnOnce(SubmatrixMut<AsFirstElement<MaybeUninit<NonZeroI64>>, NonZeroI64>),
1141{
1142 let mut data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
1143 .into_iter()
1144 .map(|x| MaybeUninit::new(NonZeroI64::new(x).unwrap()))
1145 .collect::<Vec<_>>();
1146 let matrix = SubmatrixMut::<AsFirstElement<_>, _>::from_1d(&mut data[..], 3, 5);
1147 let matrix = unsafe { matrix.assume_init() };
1148 f(matrix)
1149}
1150
1151#[cfg(test)]
1152fn with_testmatrix_vec<F>(f: F)
1153where
1154 F: FnOnce(SubmatrixMut<Vec<i64>, i64>),
1155{
1156 let mut data = vec![vec![1, 2, 3, 4, 5], vec![6, 7, 8, 9, 10], vec![11, 12, 13, 14, 15]];
1157 let matrix = SubmatrixMut::<Vec<_>, _>::from_2d(&mut data[..]);
1158 f(matrix)
1159}
1160
1161#[cfg(test)]
1162#[allow(deprecated)]
1163fn with_testmatrix_array<F>(f: F)
1164where
1165 F: FnOnce(SubmatrixMut<DerefArray<i64, 5>, i64>),
1166{
1167 let mut data = vec![
1168 DerefArray::from([1, 2, 3, 4, 5]),
1169 DerefArray::from([6, 7, 8, 9, 10]),
1170 DerefArray::from([11, 12, 13, 14, 15]),
1171 ];
1172 let matrix = SubmatrixMut::<DerefArray<_, 5>, _>::from_2d(&mut data[..]);
1173 f(matrix)
1174}
1175
1176#[cfg(test)]
1177fn with_testmatrix_linmem<F>(f: F)
1178where
1179 F: FnOnce(SubmatrixMut<AsFirstElement<i64>, i64>),
1180{
1181 let mut data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1182 let matrix = SubmatrixMut::<AsFirstElement<_>, _>::from_1d(&mut data[..], 3, 5);
1183 f(matrix)
1184}
1185
1186#[cfg(feature = "ndarray")]
1187#[cfg(test)]
1188fn with_testmatrix_ndarray<F>(f: F)
1189where
1190 F: FnOnce(SubmatrixMut<AsFirstElement<i64>, i64>),
1191{
1192 use ndarray::array;
1193
1194 let mut data = array![[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]];
1195 let matrix = SubmatrixMut::<AsFirstElement<_>, _>::from_ndarray(&mut data);
1196 f(matrix)
1197}
1198
1199#[cfg(not(feature = "ndarray"))]
1200#[cfg(test)]
1201fn with_testmatrix_ndarray<F>(_: F)
1202where
1203 F: FnOnce(SubmatrixMut<AsFirstElement<i64>, i64>),
1204{
1205 }
1207
1208#[cfg(test)]
1209fn test_submatrix<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1210 assert_submatrix_eq([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], &mut matrix);
1211 assert_submatrix_eq([[2, 3], [7, 8]], &mut matrix.reborrow().submatrix(0..2, 1..3));
1212 assert_submatrix_eq([[8, 9, 10]], &mut matrix.reborrow().submatrix(1..2, 2..5));
1213 assert_submatrix_eq([[8, 9, 10], [13, 14, 15]], &mut matrix.reborrow().submatrix(1..3, 2..5));
1214
1215 let (mut left, mut right) = matrix.split_cols(0..3, 3..5);
1216 assert_submatrix_eq([[1, 2, 3], [6, 7, 8], [11, 12, 13]], &mut left);
1217 assert_submatrix_eq([[4, 5], [9, 10], [14, 15]], &mut right);
1218}
1219
1220#[test]
1221fn test_submatrix_wrapper() {
1222 with_testmatrix_vec(test_submatrix);
1223 with_testmatrix_array(test_submatrix);
1224 with_testmatrix_linmem(test_submatrix);
1225 with_testmatrix_ndarray(test_submatrix);
1226}
1227
1228#[cfg(test)]
1229fn test_submatrix_mutate<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1230 assert_submatrix_eq([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], &mut matrix);
1231 let (mut left, mut right) = matrix.split_cols(0..3, 3..5);
1232 assert_submatrix_eq([[1, 2, 3], [6, 7, 8], [11, 12, 13]], &mut left);
1233 assert_submatrix_eq([[4, 5], [9, 10], [14, 15]], &mut right);
1234 *left.at_mut(1, 1) += 1;
1235 *right.at_mut(0, 0) += 1;
1236 *right.at_mut(2, 1) += 1;
1237 assert_submatrix_eq([[1, 2, 3], [6, 8, 8], [11, 12, 13]], &mut left);
1238 assert_submatrix_eq([[5, 5], [9, 10], [14, 16]], &mut right);
1239
1240 let (mut top, mut bottom) = left.split_rows(0..1, 1..3);
1241 assert_submatrix_eq([[1, 2, 3]], &mut top);
1242 assert_submatrix_eq([[6, 8, 8], [11, 12, 13]], &mut bottom);
1243 *top.at_mut(0, 0) -= 1;
1244 *top.at_mut(0, 2) += 3;
1245 *bottom.at_mut(0, 2) -= 1;
1246 *bottom.at_mut(1, 0) += 3;
1247 assert_submatrix_eq([[0, 2, 6]], &mut top);
1248 assert_submatrix_eq([[6, 8, 7], [14, 12, 13]], &mut bottom);
1249}
1250
1251#[test]
1252fn test_submatrix_mutate_wrapper() {
1253 with_testmatrix_vec(test_submatrix_mutate);
1254 with_testmatrix_array(test_submatrix_mutate);
1255 with_testmatrix_linmem(test_submatrix_mutate);
1256 with_testmatrix_ndarray(test_submatrix_mutate);
1257}
1258
1259#[cfg(test)]
1260fn test_submatrix_col_iter<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1261 assert_submatrix_eq([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], &mut matrix);
1262 {
1263 let mut it = matrix.reborrow().col_iter();
1264 assert_eq!(
1265 vec![2, 7, 12],
1266 it.by_ref()
1267 .skip(1)
1268 .next()
1269 .unwrap()
1270 .into_iter()
1271 .map(|x| *x)
1272 .collect::<Vec<_>>()
1273 );
1274 assert_eq!(
1275 vec![4, 9, 14],
1276 it.by_ref()
1277 .skip(1)
1278 .next()
1279 .unwrap()
1280 .into_iter()
1281 .map(|x| *x)
1282 .collect::<Vec<_>>()
1283 );
1284 let mut last_col = it.next().unwrap();
1285 for x in last_col.reborrow() {
1286 *x *= 2;
1287 }
1288 assert_eq!(vec![10, 20, 30], last_col.into_iter().map(|x| *x).collect::<Vec<_>>());
1289 }
1290 assert_submatrix_eq([[1, 2, 3, 4, 10], [6, 7, 8, 9, 20], [11, 12, 13, 14, 30]], &mut matrix);
1291
1292 let (left, _right) = matrix.reborrow().split_cols(0..2, 3..4);
1293 {
1294 let mut it = left.col_iter();
1295 let mut col1 = it.next().unwrap();
1296 let mut col2 = it.next().unwrap();
1297 assert!(it.next().is_none());
1298 assert_eq!(vec![1, 6, 11], col1.as_iter().map(|x| *x).collect::<Vec<_>>());
1299 assert_eq!(vec![2, 7, 12], col2.as_iter().map(|x| *x).collect::<Vec<_>>());
1300 assert_eq!(
1301 vec![1, 6, 11],
1302 col1.reborrow().into_iter().map(|x| *x).collect::<Vec<_>>()
1303 );
1304 assert_eq!(
1305 vec![2, 7, 12],
1306 col2.reborrow().into_iter().map(|x| *x).collect::<Vec<_>>()
1307 );
1308 *col1.into_iter().skip(1).next().unwrap() += 5;
1309 }
1310 assert_submatrix_eq([[1, 2, 3, 4, 10], [11, 7, 8, 9, 20], [11, 12, 13, 14, 30]], &mut matrix);
1311
1312 let (_left, right) = matrix.reborrow().split_cols(0..2, 3..4);
1313 {
1314 let mut it = right.col_iter();
1315 let mut col = it.next().unwrap();
1316 assert!(it.next().is_none());
1317 assert_eq!(vec![4, 9, 14], col.reborrow().as_iter().map(|x| *x).collect::<Vec<_>>());
1318 *col.into_iter().next().unwrap() += 3;
1319 }
1320 assert_submatrix_eq([[1, 2, 3, 7, 10], [11, 7, 8, 9, 20], [11, 12, 13, 14, 30]], &mut matrix);
1321}
1322
1323#[test]
1324fn test_submatrix_col_iter_wrapper() {
1325 with_testmatrix_vec(test_submatrix_col_iter);
1326 with_testmatrix_array(test_submatrix_col_iter);
1327 with_testmatrix_linmem(test_submatrix_col_iter);
1328 with_testmatrix_ndarray(test_submatrix_col_iter);
1329}
1330
1331#[cfg(test)]
1332fn test_submatrix_row_iter<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1333 assert_submatrix_eq([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], &mut matrix);
1334 {
1335 let mut it = matrix.reborrow().row_iter();
1336 assert_eq!(&[6, 7, 8, 9, 10], it.by_ref().skip(1).next().unwrap());
1337 let row = it.next().unwrap();
1338 assert!(it.next().is_none());
1339 row[1] += 6;
1340 row[4] *= 2;
1341 }
1342 assert_submatrix_eq([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 18, 13, 14, 30]], &mut matrix);
1343 let (mut left, mut right) = matrix.reborrow().split_cols(0..2, 3..4);
1344 {
1345 let mut it = left.reborrow().row_iter();
1346 let row1 = it.next().unwrap();
1347 let row2 = it.next().unwrap();
1348 assert!(it.next().is_some());
1349 assert!(it.next().is_none());
1350 assert_eq!(&[1, 2], row1);
1351 assert_eq!(&[6, 7], row2);
1352 }
1353 {
1354 let mut it = left.reborrow().row_iter();
1355 let row1 = it.next().unwrap();
1356 let row2 = it.next().unwrap();
1357 assert!(it.next().is_some());
1358 assert!(it.next().is_none());
1359 assert_eq!(&[1, 2], row1);
1360 assert_eq!(&[6, 7], row2);
1361 row2[1] += 1;
1362 }
1363 assert_submatrix_eq([[1, 2], [6, 8], [11, 18]], &mut left);
1364 {
1365 right = right.submatrix(1..3, 0..1);
1366 let mut it = right.reborrow().row_iter();
1367 let row1 = it.next().unwrap();
1368 let row2 = it.next().unwrap();
1369 assert_eq!(&[9], row1);
1370 assert_eq!(&[14], row2);
1371 row1[0] += 1;
1372 }
1373 assert_submatrix_eq([[10], [14]], &mut right);
1374}
1375
1376#[test]
1377fn test_submatrix_row_iter_wrapper() {
1378 with_testmatrix_vec(test_submatrix_row_iter);
1379 with_testmatrix_array(test_submatrix_row_iter);
1380 with_testmatrix_linmem(test_submatrix_row_iter);
1381 with_testmatrix_ndarray(test_submatrix_row_iter);
1382}
1383
1384#[cfg(test)]
1385fn test_submatrix_col_at<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1386 assert_submatrix_eq([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], &mut matrix);
1387 assert_eq!(
1388 &[2, 7, 12],
1389 &matrix.col_at(1).as_iter().copied().collect::<Vec<_>>()[..]
1390 );
1391 assert_eq!(
1392 &[2, 7, 12],
1393 &matrix.as_const().col_at(1).as_iter().copied().collect::<Vec<_>>()[..]
1394 );
1395 assert_eq!(
1396 &[5, 10, 15],
1397 &matrix.col_at(4).as_iter().copied().collect::<Vec<_>>()[..]
1398 );
1399 assert_eq!(
1400 &[5, 10, 15],
1401 &matrix.as_const().col_at(4).as_iter().copied().collect::<Vec<_>>()[..]
1402 );
1403
1404 {
1405 let (mut top, mut bottom) = matrix.reborrow().restrict_rows(0..2).split_rows(0..1, 1..2);
1406 assert_eq!(&[1], &top.col_mut_at(0).as_iter().copied().collect::<Vec<_>>()[..]);
1407 assert_eq!(
1408 &[1],
1409 &top.as_const().col_at(0).as_iter().copied().collect::<Vec<_>>()[..]
1410 );
1411 assert_eq!(&[1], &top.col_at(0).as_iter().copied().collect::<Vec<_>>()[..]);
1412 assert_eq!(&[5], &top.col_mut_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1413 assert_eq!(
1414 &[5],
1415 &top.as_const().col_at(4).as_iter().copied().collect::<Vec<_>>()[..]
1416 );
1417 assert_eq!(&[5], &top.col_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1418
1419 assert_eq!(&[6], &bottom.col_mut_at(0).as_iter().copied().collect::<Vec<_>>()[..]);
1420 assert_eq!(
1421 &[6],
1422 &bottom.as_const().col_at(0).as_iter().copied().collect::<Vec<_>>()[..]
1423 );
1424 assert_eq!(&[6], &bottom.col_at(0).as_iter().copied().collect::<Vec<_>>()[..]);
1425 assert_eq!(&[10], &bottom.col_mut_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1426 assert_eq!(
1427 &[10],
1428 &bottom.as_const().col_at(4).as_iter().copied().collect::<Vec<_>>()[..]
1429 );
1430 assert_eq!(&[10], &bottom.col_at(4).as_iter().copied().collect::<Vec<_>>()[..]);
1431 }
1432}
1433
1434#[test]
1435fn test_submatrix_col_at_wrapper() {
1436 with_testmatrix_vec(test_submatrix_col_at);
1437 with_testmatrix_array(test_submatrix_col_at);
1438 with_testmatrix_linmem(test_submatrix_col_at);
1439 with_testmatrix_ndarray(test_submatrix_col_at);
1440}
1441
1442#[cfg(test)]
1443fn test_submatrix_maybe_uninit<V: AsPointerToSlice<NonZeroI64> + AsPointerToSlice<MaybeUninit<NonZeroI64>>>(
1444 matrix: SubmatrixMut<V, NonZeroI64>,
1445) {
1446 assert_eq!(3, matrix.row_count());
1447 assert_eq!(5, matrix.col_count());
1448
1449 let mut matrix = matrix.assume_uninit();
1450 for i in 0..matrix.row_count() {
1451 for j in 0..matrix.col_count() {
1452 *matrix.at_mut(i, j) = MaybeUninit::zeroed();
1453 }
1454 }
1455
1456 let mut submatrix = matrix.reborrow().submatrix(1..2, 1..2);
1457 *submatrix.at_mut(0, 0) = MaybeUninit::new(NonZeroI64::new(1).unwrap());
1458 let mut submatrix = unsafe { submatrix.assume_init() };
1460 assert_submatrix_eq([[NonZeroI64::new(1).unwrap()]], &mut submatrix);
1461
1462 let mut submatrix = matrix.reborrow().submatrix(1..3, 0..4);
1463 for i in 0..submatrix.row_count() {
1464 for j in 0..submatrix.col_count() {
1465 *submatrix.at_mut(i, j) = MaybeUninit::new(NonZeroI64::new((i + j + 1) as i64).unwrap());
1466 }
1467 }
1468 let mut submatrix = unsafe { submatrix.assume_init() };
1470 assert_submatrix_eq(
1471 [
1472 [
1473 NonZeroI64::new(1).unwrap(),
1474 NonZeroI64::new(2).unwrap(),
1475 NonZeroI64::new(3).unwrap(),
1476 NonZeroI64::new(4).unwrap(),
1477 ],
1478 [
1479 NonZeroI64::new(2).unwrap(),
1480 NonZeroI64::new(3).unwrap(),
1481 NonZeroI64::new(4).unwrap(),
1482 NonZeroI64::new(5).unwrap(),
1483 ],
1484 ],
1485 &mut submatrix,
1486 );
1487
1488 for j in 0..matrix.col_count() {
1489 *matrix.at_mut(0, j) = MaybeUninit::new(NonZeroI64::new(1).unwrap());
1490 }
1491 for i in 0..matrix.row_count() {
1492 *matrix.at_mut(i, 4) = MaybeUninit::new(NonZeroI64::new(1).unwrap());
1493 }
1494 let mut matrix = unsafe { matrix.assume_init() };
1495 assert_submatrix_eq(
1496 [
1497 [
1498 NonZeroI64::new(1).unwrap(),
1499 NonZeroI64::new(1).unwrap(),
1500 NonZeroI64::new(1).unwrap(),
1501 NonZeroI64::new(1).unwrap(),
1502 NonZeroI64::new(1).unwrap(),
1503 ],
1504 [
1505 NonZeroI64::new(1).unwrap(),
1506 NonZeroI64::new(2).unwrap(),
1507 NonZeroI64::new(3).unwrap(),
1508 NonZeroI64::new(4).unwrap(),
1509 NonZeroI64::new(1).unwrap(),
1510 ],
1511 [
1512 NonZeroI64::new(2).unwrap(),
1513 NonZeroI64::new(3).unwrap(),
1514 NonZeroI64::new(4).unwrap(),
1515 NonZeroI64::new(5).unwrap(),
1516 NonZeroI64::new(1).unwrap(),
1517 ],
1518 ],
1519 &mut matrix,
1520 );
1521}
1522
1523#[test]
1524fn test_submatrix_maybe_uninit_wrapper() {
1525 with_testmatrix_vec_maybe_uninit(test_submatrix_maybe_uninit);
1526 with_testmatrix_linmem_maybe_uninit(test_submatrix_maybe_uninit);
1527}
1528
1529#[cfg(test)]
1530fn test_submatrix_row_at<V: AsPointerToSlice<i64>>(mut matrix: SubmatrixMut<V, i64>) {
1531 assert_submatrix_eq([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]], &mut matrix);
1532 assert_eq!(
1533 &[2, 7, 12],
1534 &matrix.col_at(1).as_iter().copied().collect::<Vec<_>>()[..]
1535 );
1536 assert_eq!(
1537 &[2, 7, 12],
1538 &matrix.as_const().col_at(1).as_iter().copied().collect::<Vec<_>>()[..]
1539 );
1540 assert_eq!(
1541 &[5, 10, 15],
1542 &matrix.col_at(4).as_iter().copied().collect::<Vec<_>>()[..]
1543 );
1544 assert_eq!(
1545 &[5, 10, 15],
1546 &matrix.as_const().col_at(4).as_iter().copied().collect::<Vec<_>>()[..]
1547 );
1548
1549 {
1550 let (mut left, mut right) = matrix.reborrow().restrict_cols(1..5).split_cols(0..2, 2..4);
1551 assert_eq!(&[2, 3], left.row_mut_at(0));
1552 assert_eq!(&[4, 5], right.row_mut_at(0));
1553 assert_eq!(&[2, 3], left.as_const().row_at(0));
1554 assert_eq!(&[4, 5], right.as_const().row_at(0));
1555 assert_eq!(&[2, 3], left.row_at(0));
1556 assert_eq!(&[4, 5], right.row_at(0));
1557
1558 assert_eq!(&[7, 8], left.row_mut_at(1));
1559 assert_eq!(&[9, 10], right.row_mut_at(1));
1560 assert_eq!(&[7, 8], left.as_const().row_at(1));
1561 assert_eq!(&[9, 10], right.as_const().row_at(1));
1562 assert_eq!(&[7, 8], left.row_at(1));
1563 assert_eq!(&[9, 10], right.row_at(1));
1564 }
1565}
1566
1567#[test]
1568fn test_submatrix_row_at_wrapper() {
1569 with_testmatrix_vec(test_submatrix_row_at);
1570 with_testmatrix_array(test_submatrix_row_at);
1571 with_testmatrix_linmem(test_submatrix_row_at);
1572 with_testmatrix_ndarray(test_submatrix_row_at);
1573}