1use std::{alloc::Layout, iter::FusedIterator, marker::PhantomData, ptr::NonNull};
31
32use diskann_utils::{Reborrow, ReborrowMut, views::MatrixView};
33use thiserror::Error;
34
35use crate::utils;
36
37pub unsafe trait Repr: Copy {
60 type Row<'a>
62 where
63 Self: 'a;
64
65 fn nrows(&self) -> usize;
72
73 fn layout(&self) -> Result<Layout, LayoutError>;
80
81 unsafe fn get_row<'a>(self, ptr: NonNull<u8>, i: usize) -> Self::Row<'a>;
93}
94
95pub unsafe trait ReprMut: Repr {
113 type RowMut<'a>
115 where
116 Self: 'a;
117
118 unsafe fn get_row_mut<'a>(self, ptr: NonNull<u8>, i: usize) -> Self::RowMut<'a>;
129}
130
131pub unsafe trait ReprOwned: ReprMut {
141 unsafe fn drop(self, ptr: NonNull<u8>);
149}
150
151#[derive(Debug, Clone, Copy)]
157#[non_exhaustive]
158pub struct LayoutError;
159
160impl LayoutError {
161 pub fn new() -> Self {
163 Self
164 }
165}
166
167impl Default for LayoutError {
168 fn default() -> Self {
169 Self::new()
170 }
171}
172
173impl std::fmt::Display for LayoutError {
174 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
175 write!(f, "LayoutError")
176 }
177}
178
179impl std::error::Error for LayoutError {}
180
181impl From<std::alloc::LayoutError> for LayoutError {
182 fn from(_: std::alloc::LayoutError) -> Self {
183 LayoutError
184 }
185}
186
187pub unsafe trait NewRef<T>: Repr {
198 type Error;
200
201 fn new_ref(self, slice: &[T]) -> Result<MatRef<'_, Self>, Self::Error>;
203}
204
205pub unsafe trait NewMut<T>: ReprMut {
212 type Error;
214
215 fn new_mut(self, slice: &mut [T]) -> Result<MatMut<'_, Self>, Self::Error>;
217}
218
219pub unsafe trait NewOwned<T>: ReprOwned {
226 type Error;
228
229 fn new_owned(self, init: T) -> Result<Mat<Self>, Self::Error>;
231}
232
233#[derive(Debug, Clone, Copy)]
244pub struct Defaulted;
245
246pub trait NewCloned: ReprOwned {
248 fn new_cloned(v: MatRef<'_, Self>) -> Mat<Self>;
252}
253
254#[derive(Debug)]
268pub struct Standard<T> {
269 nrows: usize,
270 ncols: usize,
271 _elem: PhantomData<T>,
272}
273
274impl<T> Copy for Standard<T> {}
278
279impl<T> Clone for Standard<T> {
280 fn clone(&self) -> Self {
281 *self
282 }
283}
284
285impl<T> PartialEq for Standard<T> {
286 fn eq(&self, other: &Self) -> bool {
287 self.nrows == other.nrows && self.ncols == other.ncols
288 }
289}
290
291impl<T> Eq for Standard<T> {}
292
293impl<T> Standard<T> {
294 pub fn new(nrows: usize, ncols: usize) -> Result<Self, Overflow> {
303 Overflow::check::<T>(nrows, ncols)?;
304 Ok(Self {
305 nrows,
306 ncols,
307 _elem: PhantomData,
308 })
309 }
310
311 pub fn num_elements(&self) -> usize {
313 self.nrows() * self.ncols()
315 }
316
317 fn nrows(&self) -> usize {
319 self.nrows
320 }
321
322 fn ncols(&self) -> usize {
324 self.ncols
325 }
326
327 fn check_slice(&self, slice: &[T]) -> Result<(), SliceError> {
332 let len = self.num_elements();
333
334 if slice.len() != len {
335 Err(SliceError::LengthMismatch {
336 expected: len,
337 found: slice.len(),
338 })
339 } else {
340 Ok(())
341 }
342 }
343
344 unsafe fn box_to_mat(self, b: Box<[T]>) -> Mat<Self> {
350 debug_assert_eq!(b.len(), self.num_elements(), "safety contract violated");
351
352 let ptr = utils::box_into_nonnull(b).cast::<u8>();
353
354 unsafe { Mat::from_raw_parts(self, ptr) }
358 }
359}
360
361#[derive(Debug, Clone, Copy)]
363pub struct Overflow {
364 nrows: usize,
365 ncols: usize,
366 elsize: usize,
367}
368
369impl Overflow {
370 pub(crate) fn for_type<T>(nrows: usize, ncols: usize) -> Self {
372 Self {
373 nrows,
374 ncols,
375 elsize: std::mem::size_of::<T>(),
376 }
377 }
378
379 pub(crate) fn check_byte_budget<T>(
385 capacity: usize,
386 nrows: usize,
387 ncols: usize,
388 ) -> Result<(), Self> {
389 let bytes = std::mem::size_of::<T>().saturating_mul(capacity);
390 if bytes <= isize::MAX as usize {
391 Ok(())
392 } else {
393 Err(Self::for_type::<T>(nrows, ncols))
394 }
395 }
396
397 pub(crate) fn check<T>(nrows: usize, ncols: usize) -> Result<(), Self> {
398 let capacity = nrows
400 .checked_mul(ncols)
401 .ok_or_else(|| Self::for_type::<T>(nrows, ncols))?;
402
403 Self::check_byte_budget::<T>(capacity, nrows, ncols)
404 }
405}
406
407impl std::fmt::Display for Overflow {
408 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
409 if self.elsize == 0 {
410 write!(
411 f,
412 "ZST matrix with dimensions {} x {} has more than `usize::MAX` elements",
413 self.nrows, self.ncols,
414 )
415 } else {
416 write!(
417 f,
418 "a matrix of size {} x {} with element size {} would exceed isize::MAX bytes",
419 self.nrows, self.ncols, self.elsize,
420 )
421 }
422 }
423}
424
425impl std::error::Error for Overflow {}
426
427#[derive(Debug, Clone, Copy, Error)]
429#[non_exhaustive]
430pub enum SliceError {
431 #[error("Length mismatch: expected {expected}, found {found}")]
432 LengthMismatch { expected: usize, found: usize },
433}
434
435unsafe impl<T> Repr for Standard<T> {
439 type Row<'a>
440 = &'a [T]
441 where
442 T: 'a;
443
444 fn nrows(&self) -> usize {
445 self.nrows
446 }
447
448 fn layout(&self) -> Result<Layout, LayoutError> {
449 Ok(Layout::array::<T>(self.num_elements())?)
450 }
451
452 unsafe fn get_row<'a>(self, ptr: NonNull<u8>, i: usize) -> Self::Row<'a> {
453 debug_assert!(ptr.cast::<T>().is_aligned());
454 debug_assert!(i < self.nrows);
455
456 let row_ptr = unsafe { ptr.as_ptr().cast::<T>().add(i * self.ncols) };
460
461 unsafe { std::slice::from_raw_parts(row_ptr, self.ncols) }
463 }
464}
465
466unsafe impl<T> ReprMut for Standard<T> {
469 type RowMut<'a>
470 = &'a mut [T]
471 where
472 T: 'a;
473
474 unsafe fn get_row_mut<'a>(self, ptr: NonNull<u8>, i: usize) -> Self::RowMut<'a> {
475 debug_assert!(ptr.cast::<T>().is_aligned());
476 debug_assert!(i < self.nrows);
477
478 let row_ptr = unsafe { ptr.as_ptr().cast::<T>().add(i * self.ncols) };
482
483 unsafe { std::slice::from_raw_parts_mut(row_ptr, self.ncols) }
486 }
487}
488
489unsafe impl<T> ReprOwned for Standard<T> {
493 unsafe fn drop(self, ptr: NonNull<u8>) {
494 unsafe {
500 let slice_ptr = std::ptr::slice_from_raw_parts_mut(
501 ptr.cast::<T>().as_ptr(),
502 self.nrows * self.ncols,
503 );
504 let _ = Box::from_raw(slice_ptr);
505 }
506 }
507}
508
509unsafe impl<T> NewOwned<T> for Standard<T>
512where
513 T: Clone,
514{
515 type Error = crate::error::Infallible;
516 fn new_owned(self, value: T) -> Result<Mat<Self>, Self::Error> {
517 let b: Box<[T]> = std::iter::repeat_n(value, self.num_elements()).collect();
518
519 Ok(unsafe { self.box_to_mat(b) })
521 }
522}
523
524unsafe impl<T> NewOwned<Defaulted> for Standard<T>
527where
528 T: Default,
529{
530 type Error = crate::error::Infallible;
531 fn new_owned(self, _: Defaulted) -> Result<Mat<Self>, Self::Error> {
532 let b: Box<[T]> = std::iter::repeat_with(T::default)
533 .take(self.num_elements())
534 .collect();
535
536 Ok(unsafe { self.box_to_mat(b) })
538 }
539}
540
541unsafe impl<T> NewRef<T> for Standard<T> {
544 type Error = SliceError;
545 fn new_ref(self, data: &[T]) -> Result<MatRef<'_, Self>, Self::Error> {
546 self.check_slice(data)?;
547
548 Ok(unsafe { MatRef::from_raw_parts(self, utils::as_nonnull(data).cast::<u8>()) })
553 }
554}
555
556unsafe impl<T> NewMut<T> for Standard<T> {
559 type Error = SliceError;
560 fn new_mut(self, data: &mut [T]) -> Result<MatMut<'_, Self>, Self::Error> {
561 self.check_slice(data)?;
562
563 Ok(unsafe { MatMut::from_raw_parts(self, utils::as_nonnull_mut(data).cast::<u8>()) })
568 }
569}
570
571impl<T> NewCloned for Standard<T>
572where
573 T: Clone,
574{
575 fn new_cloned(v: MatRef<'_, Self>) -> Mat<Self> {
576 let b: Box<[T]> = v.as_slice().iter().cloned().collect();
577
578 unsafe { v.repr().box_to_mat(b) }
580 }
581}
582
583#[derive(Debug)]
592pub struct Mat<T: ReprOwned> {
593 ptr: NonNull<u8>,
594 repr: T,
595 _invariant: PhantomData<fn(T) -> T>,
596}
597
598unsafe impl<T> Send for Mat<T> where T: ReprOwned + Send {}
600
601unsafe impl<T> Sync for Mat<T> where T: ReprOwned + Sync {}
603
604impl<T: ReprOwned> Mat<T> {
605 pub fn new<U>(repr: T, init: U) -> Result<Self, <T as NewOwned<U>>::Error>
607 where
608 T: NewOwned<U>,
609 {
610 repr.new_owned(init)
611 }
612
613 #[inline]
615 pub fn num_vectors(&self) -> usize {
616 self.repr.nrows()
617 }
618
619 pub fn repr(&self) -> &T {
621 &self.repr
622 }
623
624 #[must_use]
626 pub fn get_row(&self, i: usize) -> Option<T::Row<'_>> {
627 if i < self.num_vectors() {
628 let row = unsafe { self.get_row_unchecked(i) };
631 Some(row)
632 } else {
633 None
634 }
635 }
636
637 pub(crate) unsafe fn get_row_unchecked(&self, i: usize) -> T::Row<'_> {
638 unsafe { self.repr.get_row(self.ptr, i) }
641 }
642
643 #[must_use]
645 pub fn get_row_mut(&mut self, i: usize) -> Option<T::RowMut<'_>> {
646 if i < self.num_vectors() {
647 Some(unsafe { self.get_row_mut_unchecked(i) })
649 } else {
650 None
651 }
652 }
653
654 pub(crate) unsafe fn get_row_mut_unchecked(&mut self, i: usize) -> T::RowMut<'_> {
655 unsafe { self.repr.get_row_mut(self.ptr, i) }
658 }
659
660 #[inline]
662 pub fn as_view(&self) -> MatRef<'_, T> {
663 MatRef {
664 ptr: self.ptr,
665 repr: self.repr,
666 _lifetime: PhantomData,
667 }
668 }
669
670 #[inline]
672 pub fn as_view_mut(&mut self) -> MatMut<'_, T> {
673 MatMut {
674 ptr: self.ptr,
675 repr: self.repr,
676 _lifetime: PhantomData,
677 }
678 }
679
680 pub fn rows(&self) -> Rows<'_, T> {
682 Rows::new(self.reborrow())
683 }
684
685 pub fn rows_mut(&mut self) -> RowsMut<'_, T> {
687 RowsMut::new(self.reborrow_mut())
688 }
689
690 pub(crate) unsafe fn from_raw_parts(repr: T, ptr: NonNull<u8>) -> Self {
700 Self {
701 ptr,
702 repr,
703 _invariant: PhantomData,
704 }
705 }
706
707 pub fn as_raw_ptr(&self) -> *const u8 {
709 self.ptr.as_ptr()
710 }
711
712 pub(crate) fn as_raw_mut_ptr(&mut self) -> *mut u8 {
714 self.ptr.as_ptr()
715 }
716}
717
718impl<T: ReprOwned> Drop for Mat<T> {
719 fn drop(&mut self) {
720 unsafe { self.repr.drop(self.ptr) };
723 }
724}
725
726impl<T: NewCloned> Clone for Mat<T> {
727 fn clone(&self) -> Self {
728 T::new_cloned(self.as_view())
729 }
730}
731
732impl<T> Mat<Standard<T>> {
733 pub fn from_fn<F: FnMut() -> T>(repr: Standard<T>, mut f: F) -> Self {
735 let b: Box<[T]> = (0..repr.num_elements()).map(|_| f()).collect();
736 unsafe { repr.box_to_mat(b) }
738 }
739
740 #[inline]
742 pub fn vector_dim(&self) -> usize {
743 self.repr.ncols()
744 }
745
746 #[inline]
750 pub fn as_slice(&self) -> &[T] {
751 self.as_view().as_slice()
752 }
753
754 #[inline]
756 pub fn as_matrix_view(&self) -> MatrixView<'_, T> {
757 self.as_view().as_matrix_view()
758 }
759}
760
761#[derive(Debug, Clone, Copy)]
777pub struct MatRef<'a, T: Repr> {
778 ptr: NonNull<u8>,
779 repr: T,
780 _lifetime: PhantomData<&'a T>,
782}
783
784unsafe impl<T> Send for MatRef<'_, T> where T: Repr + Send {}
786
787unsafe impl<T> Sync for MatRef<'_, T> where T: Repr + Sync {}
789
790impl<'a, T: Repr> MatRef<'a, T> {
791 pub fn new<U>(repr: T, data: &'a [U]) -> Result<Self, T::Error>
793 where
794 T: NewRef<U>,
795 {
796 repr.new_ref(data)
797 }
798
799 #[inline]
801 pub fn num_vectors(&self) -> usize {
802 self.repr.nrows()
803 }
804
805 pub fn repr(&self) -> &T {
807 &self.repr
808 }
809
810 #[must_use]
812 pub fn get_row(&self, i: usize) -> Option<T::Row<'_>> {
813 if i < self.num_vectors() {
814 let row = unsafe { self.get_row_unchecked(i) };
817 Some(row)
818 } else {
819 None
820 }
821 }
822
823 #[inline]
829 pub(crate) unsafe fn get_row_unchecked(&self, i: usize) -> T::Row<'_> {
830 unsafe { self.repr.get_row(self.ptr, i) }
832 }
833
834 pub fn rows(&self) -> Rows<'_, T> {
836 Rows::new(*self)
837 }
838
839 pub fn to_owned(&self) -> Mat<T>
841 where
842 T: NewCloned,
843 {
844 T::new_cloned(*self)
845 }
846
847 pub unsafe fn from_raw_parts(repr: T, ptr: NonNull<u8>) -> Self {
855 Self {
856 ptr,
857 repr,
858 _lifetime: PhantomData,
859 }
860 }
861
862 pub fn as_raw_ptr(&self) -> *const u8 {
864 self.ptr.as_ptr()
865 }
866}
867
868impl<'a, T> MatRef<'a, Standard<T>> {
869 #[inline]
871 pub fn vector_dim(&self) -> usize {
872 self.repr.ncols()
873 }
874
875 #[inline]
879 pub fn as_slice(&self) -> &'a [T] {
880 let len = self.repr.num_elements();
881 unsafe { std::slice::from_raw_parts(self.ptr.as_ptr().cast::<T>(), len) }
884 }
885
886 #[allow(clippy::expect_used)]
888 #[inline]
889 pub fn as_matrix_view(&self) -> MatrixView<'a, T> {
890 MatrixView::try_from(self.as_slice(), self.num_vectors(), self.vector_dim())
893 .expect("Standard<T> has valid dimensions")
894 }
895}
896
897impl<'this, T: ReprOwned> Reborrow<'this> for Mat<T> {
899 type Target = MatRef<'this, T>;
900
901 fn reborrow(&'this self) -> Self::Target {
902 self.as_view()
903 }
904}
905
906impl<'this, T: ReprOwned> ReborrowMut<'this> for Mat<T> {
908 type Target = MatMut<'this, T>;
909
910 fn reborrow_mut(&'this mut self) -> Self::Target {
911 self.as_view_mut()
912 }
913}
914
915impl<'this, 'a, T: Repr> Reborrow<'this> for MatRef<'a, T> {
917 type Target = MatRef<'this, T>;
918
919 fn reborrow(&'this self) -> Self::Target {
920 MatRef {
921 ptr: self.ptr,
922 repr: self.repr,
923 _lifetime: PhantomData,
924 }
925 }
926}
927
928#[derive(Debug)]
945pub struct MatMut<'a, T: ReprMut> {
946 ptr: NonNull<u8>,
947 repr: T,
948 _lifetime: PhantomData<&'a mut T>,
950}
951
952unsafe impl<T> Send for MatMut<'_, T> where T: ReprMut + Send {}
954
955unsafe impl<T> Sync for MatMut<'_, T> where T: ReprMut + Sync {}
957
958impl<'a, T: ReprMut> MatMut<'a, T> {
959 pub fn new<U>(repr: T, data: &'a mut [U]) -> Result<Self, T::Error>
961 where
962 T: NewMut<U>,
963 {
964 repr.new_mut(data)
965 }
966
967 #[inline]
969 pub fn num_vectors(&self) -> usize {
970 self.repr.nrows()
971 }
972
973 pub fn repr(&self) -> &T {
975 &self.repr
976 }
977
978 #[inline]
980 #[must_use]
981 pub fn get_row(&self, i: usize) -> Option<T::Row<'_>> {
982 if i < self.num_vectors() {
983 Some(unsafe { self.get_row_unchecked(i) })
985 } else {
986 None
987 }
988 }
989
990 #[inline]
996 pub(crate) unsafe fn get_row_unchecked(&self, i: usize) -> T::Row<'_> {
997 unsafe { self.repr.get_row(self.ptr, i) }
999 }
1000
1001 #[inline]
1003 #[must_use]
1004 pub fn get_row_mut(&mut self, i: usize) -> Option<T::RowMut<'_>> {
1005 if i < self.num_vectors() {
1006 Some(unsafe { self.get_row_mut_unchecked(i) })
1008 } else {
1009 None
1010 }
1011 }
1012
1013 #[inline]
1019 pub(crate) unsafe fn get_row_mut_unchecked(&mut self, i: usize) -> T::RowMut<'_> {
1020 unsafe { self.repr.get_row_mut(self.ptr, i) }
1023 }
1024
1025 pub fn as_view(&self) -> MatRef<'_, T> {
1027 MatRef {
1028 ptr: self.ptr,
1029 repr: self.repr,
1030 _lifetime: PhantomData,
1031 }
1032 }
1033
1034 pub fn rows(&self) -> Rows<'_, T> {
1036 Rows::new(self.reborrow())
1037 }
1038
1039 pub fn rows_mut(&mut self) -> RowsMut<'_, T> {
1041 RowsMut::new(self.reborrow_mut())
1042 }
1043
1044 pub fn to_owned(&self) -> Mat<T>
1046 where
1047 T: NewCloned,
1048 {
1049 T::new_cloned(self.as_view())
1050 }
1051
1052 pub unsafe fn from_raw_parts(repr: T, ptr: NonNull<u8>) -> Self {
1059 Self {
1060 ptr,
1061 repr,
1062 _lifetime: PhantomData,
1063 }
1064 }
1065
1066 pub fn as_raw_ptr(&self) -> *const u8 {
1068 self.ptr.as_ptr()
1069 }
1070
1071 pub(crate) fn as_raw_mut_ptr(&mut self) -> *mut u8 {
1073 self.ptr.as_ptr()
1074 }
1075}
1076
1077impl<'this, 'a, T: ReprMut> Reborrow<'this> for MatMut<'a, T> {
1079 type Target = MatRef<'this, T>;
1080
1081 fn reborrow(&'this self) -> Self::Target {
1082 self.as_view()
1083 }
1084}
1085
1086impl<'this, 'a, T: ReprMut> ReborrowMut<'this> for MatMut<'a, T> {
1088 type Target = MatMut<'this, T>;
1089
1090 fn reborrow_mut(&'this mut self) -> Self::Target {
1091 MatMut {
1092 ptr: self.ptr,
1093 repr: self.repr,
1094 _lifetime: PhantomData,
1095 }
1096 }
1097}
1098
1099impl<'a, T> MatMut<'a, Standard<T>> {
1100 #[inline]
1102 pub fn vector_dim(&self) -> usize {
1103 self.repr.ncols()
1104 }
1105
1106 #[inline]
1110 pub fn as_slice(&self) -> &[T] {
1111 self.as_view().as_slice()
1112 }
1113
1114 #[inline]
1116 pub fn as_matrix_view(&self) -> MatrixView<'_, T> {
1117 self.as_view().as_matrix_view()
1118 }
1119}
1120
1121#[derive(Debug)]
1129pub struct Rows<'a, T: Repr> {
1130 matrix: MatRef<'a, T>,
1131 current: usize,
1132}
1133
1134impl<'a, T> Rows<'a, T>
1135where
1136 T: Repr,
1137{
1138 fn new(matrix: MatRef<'a, T>) -> Self {
1139 Self { matrix, current: 0 }
1140 }
1141}
1142
1143impl<'a, T> Iterator for Rows<'a, T>
1144where
1145 T: Repr + 'a,
1146{
1147 type Item = T::Row<'a>;
1148
1149 fn next(&mut self) -> Option<Self::Item> {
1150 let current = self.current;
1151 if current >= self.matrix.num_vectors() {
1152 None
1153 } else {
1154 self.current += 1;
1155 Some(unsafe { self.matrix.repr.get_row(self.matrix.ptr, current) })
1161 }
1162 }
1163
1164 fn size_hint(&self) -> (usize, Option<usize>) {
1165 let remaining = self.matrix.num_vectors() - self.current;
1166 (remaining, Some(remaining))
1167 }
1168}
1169
1170impl<'a, T> ExactSizeIterator for Rows<'a, T> where T: Repr + 'a {}
1171impl<'a, T> FusedIterator for Rows<'a, T> where T: Repr + 'a {}
1172
1173#[derive(Debug)]
1181pub struct RowsMut<'a, T: ReprMut> {
1182 matrix: MatMut<'a, T>,
1183 current: usize,
1184}
1185
1186impl<'a, T> RowsMut<'a, T>
1187where
1188 T: ReprMut,
1189{
1190 fn new(matrix: MatMut<'a, T>) -> Self {
1191 Self { matrix, current: 0 }
1192 }
1193}
1194
1195impl<'a, T> Iterator for RowsMut<'a, T>
1196where
1197 T: ReprMut + 'a,
1198{
1199 type Item = T::RowMut<'a>;
1200
1201 fn next(&mut self) -> Option<Self::Item> {
1202 let current = self.current;
1203 if current >= self.matrix.num_vectors() {
1204 None
1205 } else {
1206 self.current += 1;
1207 Some(unsafe { self.matrix.repr.get_row_mut(self.matrix.ptr, current) })
1216 }
1217 }
1218
1219 fn size_hint(&self) -> (usize, Option<usize>) {
1220 let remaining = self.matrix.num_vectors() - self.current;
1221 (remaining, Some(remaining))
1222 }
1223}
1224
1225impl<'a, T> ExactSizeIterator for RowsMut<'a, T> where T: ReprMut + 'a {}
1226impl<'a, T> FusedIterator for RowsMut<'a, T> where T: ReprMut + 'a {}
1227
1228#[cfg(test)]
1233mod tests {
1234 use super::*;
1235
1236 use std::fmt::Display;
1237
1238 use diskann_utils::lazy_format;
1239
1240 fn assert_copy<T: Copy>(_: &T) {}
1242
1243 fn _assert_matref_covariant_lifetime<'long: 'short, 'short, T: Repr>(
1253 v: MatRef<'long, T>,
1254 ) -> MatRef<'short, T> {
1255 v
1256 }
1257
1258 fn _assert_matref_covariant_repr<'long: 'short, 'short, 'a>(
1260 v: MatRef<'a, Standard<&'long u8>>,
1261 ) -> MatRef<'a, Standard<&'short u8>> {
1262 v
1263 }
1264
1265 fn _assert_matmut_covariant_lifetime<'long: 'short, 'short, T: ReprMut>(
1267 v: MatMut<'long, T>,
1268 ) -> MatMut<'short, T> {
1269 v
1270 }
1271
1272 fn edge_cases(nrows: usize) -> Vec<usize> {
1273 let max = usize::MAX;
1274
1275 vec![
1276 nrows,
1277 nrows + 1,
1278 nrows + 11,
1279 nrows + 20,
1280 max / 2,
1281 max.div_ceil(2),
1282 max - 1,
1283 max,
1284 ]
1285 }
1286
1287 fn fill_mat(x: &mut Mat<Standard<usize>>, repr: Standard<usize>) {
1288 assert_eq!(x.repr(), &repr);
1289 assert_eq!(x.num_vectors(), repr.nrows());
1290 assert_eq!(x.vector_dim(), repr.ncols());
1291
1292 for i in 0..x.num_vectors() {
1293 let row = x.get_row_mut(i).unwrap();
1294 assert_eq!(row.len(), repr.ncols());
1295 row.iter_mut()
1296 .enumerate()
1297 .for_each(|(j, r)| *r = 10 * i + j);
1298 }
1299
1300 for i in edge_cases(repr.nrows()).into_iter() {
1301 assert!(x.get_row_mut(i).is_none());
1302 }
1303 }
1304
1305 fn fill_mat_mut(mut x: MatMut<'_, Standard<usize>>, repr: Standard<usize>) {
1306 assert_eq!(x.repr(), &repr);
1307 assert_eq!(x.num_vectors(), repr.nrows());
1308 assert_eq!(x.vector_dim(), repr.ncols());
1309
1310 for i in 0..x.num_vectors() {
1311 let row = x.get_row_mut(i).unwrap();
1312 assert_eq!(row.len(), repr.ncols());
1313
1314 row.iter_mut()
1315 .enumerate()
1316 .for_each(|(j, r)| *r = 10 * i + j);
1317 }
1318
1319 for i in edge_cases(repr.nrows()).into_iter() {
1320 assert!(x.get_row_mut(i).is_none());
1321 }
1322 }
1323
1324 fn fill_rows_mut(x: RowsMut<'_, Standard<usize>>, repr: Standard<usize>) {
1325 assert_eq!(x.len(), repr.nrows());
1326 let mut all_rows: Vec<_> = x.collect();
1328 assert_eq!(all_rows.len(), repr.nrows());
1329 for (i, row) in all_rows.iter_mut().enumerate() {
1330 assert_eq!(row.len(), repr.ncols());
1331 row.iter_mut()
1332 .enumerate()
1333 .for_each(|(j, r)| *r = 10 * i + j);
1334 }
1335 }
1336
1337 fn check_mat(x: &Mat<Standard<usize>>, repr: Standard<usize>, ctx: &dyn Display) {
1338 assert_eq!(x.repr(), &repr);
1339 assert_eq!(x.num_vectors(), repr.nrows());
1340 assert_eq!(x.vector_dim(), repr.ncols());
1341
1342 for i in 0..x.num_vectors() {
1343 let row = x.get_row(i).unwrap();
1344
1345 assert_eq!(row.len(), repr.ncols(), "ctx: {ctx}");
1346 row.iter().enumerate().for_each(|(j, r)| {
1347 assert_eq!(
1348 *r,
1349 10 * i + j,
1350 "mismatched entry at row {}, col {} -- ctx: {}",
1351 i,
1352 j,
1353 ctx
1354 )
1355 });
1356 }
1357
1358 for i in edge_cases(repr.nrows()).into_iter() {
1359 assert!(x.get_row(i).is_none(), "ctx: {ctx}");
1360 }
1361 }
1362
1363 fn check_mat_ref(x: MatRef<'_, Standard<usize>>, repr: Standard<usize>, ctx: &dyn Display) {
1364 assert_eq!(x.repr(), &repr);
1365 assert_eq!(x.num_vectors(), repr.nrows());
1366 assert_eq!(x.vector_dim(), repr.ncols());
1367
1368 assert_copy(&x);
1369 for i in 0..x.num_vectors() {
1370 let row = x.get_row(i).unwrap();
1371 assert_eq!(row.len(), repr.ncols(), "ctx: {ctx}");
1372
1373 row.iter().enumerate().for_each(|(j, r)| {
1374 assert_eq!(
1375 *r,
1376 10 * i + j,
1377 "mismatched entry at row {}, col {} -- ctx: {}",
1378 i,
1379 j,
1380 ctx
1381 )
1382 });
1383 }
1384
1385 for i in edge_cases(repr.nrows()).into_iter() {
1386 assert!(x.get_row(i).is_none(), "ctx: {ctx}");
1387 }
1388 }
1389
1390 fn check_mat_mut(x: MatMut<'_, Standard<usize>>, repr: Standard<usize>, ctx: &dyn Display) {
1391 assert_eq!(x.repr(), &repr);
1392 assert_eq!(x.num_vectors(), repr.nrows());
1393 assert_eq!(x.vector_dim(), repr.ncols());
1394
1395 for i in 0..x.num_vectors() {
1396 let row = x.get_row(i).unwrap();
1397 assert_eq!(row.len(), repr.ncols(), "ctx: {ctx}");
1398
1399 row.iter().enumerate().for_each(|(j, r)| {
1400 assert_eq!(
1401 *r,
1402 10 * i + j,
1403 "mismatched entry at row {}, col {} -- ctx: {}",
1404 i,
1405 j,
1406 ctx
1407 )
1408 });
1409 }
1410
1411 for i in edge_cases(repr.nrows()).into_iter() {
1412 assert!(x.get_row(i).is_none(), "ctx: {ctx}");
1413 }
1414 }
1415
1416 fn check_rows(x: Rows<'_, Standard<usize>>, repr: Standard<usize>, ctx: &dyn Display) {
1417 assert_eq!(x.len(), repr.nrows(), "ctx: {ctx}");
1418 let all_rows: Vec<_> = x.collect();
1419 assert_eq!(all_rows.len(), repr.nrows(), "ctx: {ctx}");
1420 for (i, row) in all_rows.iter().enumerate() {
1421 assert_eq!(row.len(), repr.ncols(), "ctx: {ctx}");
1422 row.iter().enumerate().for_each(|(j, r)| {
1423 assert_eq!(
1424 *r,
1425 10 * i + j,
1426 "mismatched entry at row {}, col {} -- ctx: {}",
1427 i,
1428 j,
1429 ctx
1430 )
1431 });
1432 }
1433 }
1434
1435 #[test]
1440 fn standard_representation() {
1441 let repr = Standard::<f32>::new(4, 3).unwrap();
1442 assert_eq!(repr.nrows(), 4);
1443 assert_eq!(repr.ncols(), 3);
1444
1445 let layout = repr.layout().unwrap();
1446 assert_eq!(layout.size(), 4 * 3 * std::mem::size_of::<f32>());
1447 assert_eq!(layout.align(), std::mem::align_of::<f32>());
1448 }
1449
1450 #[test]
1451 fn standard_zero_dimensions() {
1452 for (nrows, ncols) in [(0, 0), (0, 5), (5, 0)] {
1453 let repr = Standard::<u8>::new(nrows, ncols).unwrap();
1454 assert_eq!(repr.nrows(), nrows);
1455 assert_eq!(repr.ncols(), ncols);
1456 let layout = repr.layout().unwrap();
1457 assert_eq!(layout.size(), 0);
1458 }
1459 }
1460
1461 #[test]
1462 fn standard_check_slice() {
1463 let repr = Standard::<u32>::new(3, 4).unwrap();
1464
1465 let data = vec![0u32; 12];
1467 assert!(repr.check_slice(&data).is_ok());
1468
1469 let short = vec![0u32; 11];
1471 assert!(matches!(
1472 repr.check_slice(&short),
1473 Err(SliceError::LengthMismatch {
1474 expected: 12,
1475 found: 11
1476 })
1477 ));
1478
1479 let long = vec![0u32; 13];
1481 assert!(matches!(
1482 repr.check_slice(&long),
1483 Err(SliceError::LengthMismatch {
1484 expected: 12,
1485 found: 13
1486 })
1487 ));
1488
1489 let overflow_repr = Standard::<u8>::new(usize::MAX, 2).unwrap_err();
1491 assert!(matches!(overflow_repr, Overflow { .. }));
1492 }
1493
1494 #[test]
1495 fn standard_new_rejects_element_count_overflow() {
1496 assert!(Standard::<u8>::new(usize::MAX, 2).is_err());
1498 assert!(Standard::<u8>::new(2, usize::MAX).is_err());
1499 assert!(Standard::<u8>::new(usize::MAX, usize::MAX).is_err());
1500 }
1501
1502 #[test]
1503 fn standard_new_rejects_byte_count_exceeding_isize_max() {
1504 let half = (isize::MAX as usize / std::mem::size_of::<u64>()) + 1;
1506 assert!(Standard::<u64>::new(half, 1).is_err());
1507 assert!(Standard::<u64>::new(1, half).is_err());
1508 }
1509
1510 #[test]
1511 fn standard_new_accepts_boundary_below_isize_max() {
1512 let max_elems = isize::MAX as usize / std::mem::size_of::<u64>();
1514 let repr = Standard::<u64>::new(max_elems, 1).unwrap();
1515 assert_eq!(repr.num_elements(), max_elems);
1516 }
1517
1518 #[test]
1519 fn standard_new_zst_rejects_element_count_overflow() {
1520 assert!(Standard::<()>::new(usize::MAX, 2).is_err());
1523 assert!(Standard::<()>::new(usize::MAX / 2 + 1, 3).is_err());
1524 }
1525
1526 #[test]
1527 fn standard_new_zst_accepts_large_non_overflowing() {
1528 let repr = Standard::<()>::new(usize::MAX, 1).unwrap();
1530 assert_eq!(repr.num_elements(), usize::MAX);
1531 assert_eq!(repr.layout().unwrap().size(), 0);
1532 }
1533
1534 #[test]
1535 fn standard_new_overflow_error_display() {
1536 let err = Standard::<u32>::new(usize::MAX, 2).unwrap_err();
1537 let msg = err.to_string();
1538 assert!(msg.contains("would exceed isize::MAX bytes"), "{msg}");
1539
1540 let zst_err = Standard::<()>::new(usize::MAX, 2).unwrap_err();
1541 let zst_msg = zst_err.to_string();
1542 assert!(zst_msg.contains("ZST matrix"), "{zst_msg}");
1543 assert!(zst_msg.contains("usize::MAX"), "{zst_msg}");
1544 }
1545
1546 #[test]
1551 fn mat_new_and_basic_accessors() {
1552 let mat = Mat::new(Standard::<usize>::new(3, 4).unwrap(), 42usize).unwrap();
1553 let base: *const u8 = mat.as_raw_ptr();
1554
1555 assert_eq!(mat.num_vectors(), 3);
1556 assert_eq!(mat.vector_dim(), 4);
1557
1558 let repr = mat.repr();
1559 assert_eq!(repr.nrows(), 3);
1560 assert_eq!(repr.ncols(), 4);
1561
1562 for (i, r) in mat.rows().enumerate() {
1563 assert_eq!(r, &[42, 42, 42, 42]);
1564 let ptr = r.as_ptr().cast::<u8>();
1565 assert_eq!(
1566 ptr,
1567 base.wrapping_add(std::mem::size_of::<usize>() * mat.repr().ncols() * i),
1568 );
1569 }
1570 }
1571
1572 #[test]
1573 fn mat_new_with_default() {
1574 let mat = Mat::new(Standard::<usize>::new(2, 3).unwrap(), Defaulted).unwrap();
1575 let base: *const u8 = mat.as_raw_ptr();
1576
1577 assert_eq!(mat.num_vectors(), 2);
1578 for (i, row) in mat.rows().enumerate() {
1579 assert!(row.iter().all(|&v| v == 0));
1580
1581 let ptr = row.as_ptr().cast::<u8>();
1582 assert_eq!(
1583 ptr,
1584 base.wrapping_add(std::mem::size_of::<usize>() * mat.repr().ncols() * i),
1585 );
1586 }
1587 }
1588
1589 const ROWS: &[usize] = &[0, 1, 2, 3, 5, 10];
1590 const COLS: &[usize] = &[0, 1, 2, 3, 5, 10];
1591
1592 #[test]
1593 fn test_mat() {
1594 for nrows in ROWS {
1595 for ncols in COLS {
1596 let repr = Standard::<usize>::new(*nrows, *ncols).unwrap();
1597 let ctx = &lazy_format!("nrows = {}, ncols = {}", nrows, ncols);
1598
1599 {
1601 let ctx = &lazy_format!("{ctx} - direct");
1602 let mut mat = Mat::new(repr, Defaulted).unwrap();
1603
1604 assert_eq!(mat.num_vectors(), *nrows);
1605 assert_eq!(mat.vector_dim(), *ncols);
1606
1607 fill_mat(&mut mat, repr);
1608
1609 check_mat(&mat, repr, ctx);
1610 check_mat_ref(mat.reborrow(), repr, ctx);
1611 check_mat_mut(mat.reborrow_mut(), repr, ctx);
1612 check_rows(mat.rows(), repr, ctx);
1613
1614 assert_eq!(mat.as_raw_ptr(), mat.reborrow().as_raw_ptr());
1616 assert_eq!(mat.as_raw_ptr(), mat.reborrow_mut().as_raw_ptr());
1617 }
1618
1619 {
1621 let ctx = &lazy_format!("{ctx} - matmut");
1622 let mut mat = Mat::new(repr, Defaulted).unwrap();
1623 let matmut = mat.reborrow_mut();
1624
1625 assert_eq!(matmut.num_vectors(), *nrows);
1626 assert_eq!(matmut.vector_dim(), *ncols);
1627
1628 fill_mat_mut(matmut, repr);
1629
1630 check_mat(&mat, repr, ctx);
1631 check_mat_ref(mat.reborrow(), repr, ctx);
1632 check_mat_mut(mat.reborrow_mut(), repr, ctx);
1633 check_rows(mat.rows(), repr, ctx);
1634 }
1635
1636 {
1638 let ctx = &lazy_format!("{ctx} - rows_mut");
1639 let mut mat = Mat::new(repr, Defaulted).unwrap();
1640 fill_rows_mut(mat.rows_mut(), repr);
1641
1642 check_mat(&mat, repr, ctx);
1643 check_mat_ref(mat.reborrow(), repr, ctx);
1644 check_mat_mut(mat.reborrow_mut(), repr, ctx);
1645 check_rows(mat.rows(), repr, ctx);
1646 }
1647 }
1648 }
1649 }
1650
1651 #[test]
1652 fn test_mat_clone() {
1653 for nrows in ROWS {
1654 for ncols in COLS {
1655 let repr = Standard::<usize>::new(*nrows, *ncols).unwrap();
1656 let ctx = &lazy_format!("nrows = {}, ncols = {}", nrows, ncols);
1657
1658 let mut mat = Mat::new(repr, Defaulted).unwrap();
1659 fill_mat(&mut mat, repr);
1660
1661 {
1663 let ctx = &lazy_format!("{ctx} - Mat::clone");
1664 let cloned = mat.clone();
1665
1666 assert_eq!(cloned.num_vectors(), *nrows);
1667 assert_eq!(cloned.vector_dim(), *ncols);
1668
1669 check_mat(&cloned, repr, ctx);
1670 check_mat_ref(cloned.reborrow(), repr, ctx);
1671 check_rows(cloned.rows(), repr, ctx);
1672
1673 if repr.num_elements() > 0 {
1675 assert_ne!(mat.as_raw_ptr(), cloned.as_raw_ptr());
1676 }
1677 }
1678
1679 {
1681 let ctx = &lazy_format!("{ctx} - MatRef::to_owned");
1682 let owned = mat.as_view().to_owned();
1683
1684 check_mat(&owned, repr, ctx);
1685 check_mat_ref(owned.reborrow(), repr, ctx);
1686 check_rows(owned.rows(), repr, ctx);
1687
1688 if repr.num_elements() > 0 {
1689 assert_ne!(mat.as_raw_ptr(), owned.as_raw_ptr());
1690 }
1691 }
1692
1693 {
1695 let ctx = &lazy_format!("{ctx} - MatMut::to_owned");
1696 let owned = mat.as_view_mut().to_owned();
1697
1698 check_mat(&owned, repr, ctx);
1699 check_mat_ref(owned.reborrow(), repr, ctx);
1700 check_rows(owned.rows(), repr, ctx);
1701
1702 if repr.num_elements() > 0 {
1703 assert_ne!(mat.as_raw_ptr(), owned.as_raw_ptr());
1704 }
1705 }
1706 }
1707 }
1708 }
1709
1710 #[test]
1711 fn test_mat_refmut() {
1712 for nrows in ROWS {
1713 for ncols in COLS {
1714 let repr = Standard::<usize>::new(*nrows, *ncols).unwrap();
1715 let ctx = &lazy_format!("nrows = {}, ncols = {}", nrows, ncols);
1716
1717 {
1719 let ctx = &lazy_format!("{ctx} - by matmut");
1720 let mut b: Box<[_]> = (0..repr.num_elements()).map(|_| 0usize).collect();
1721 let ptr = b.as_ptr().cast::<u8>();
1722 let mut matmut = MatMut::new(repr, &mut b).unwrap();
1723
1724 assert_eq!(
1725 ptr,
1726 matmut.as_raw_ptr(),
1727 "underlying memory should be preserved",
1728 );
1729
1730 fill_mat_mut(matmut.reborrow_mut(), repr);
1731
1732 check_mat_mut(matmut.reborrow_mut(), repr, ctx);
1733 check_mat_ref(matmut.reborrow(), repr, ctx);
1734 check_rows(matmut.rows(), repr, ctx);
1735 check_rows(matmut.reborrow().rows(), repr, ctx);
1736
1737 let matref = MatRef::new(repr, &b).unwrap();
1738 check_mat_ref(matref, repr, ctx);
1739 check_mat_ref(matref.reborrow(), repr, ctx);
1740 check_rows(matref.rows(), repr, ctx);
1741 }
1742
1743 {
1745 let ctx = &lazy_format!("{ctx} - by rows");
1746 let mut b: Box<[_]> = (0..repr.num_elements()).map(|_| 0usize).collect();
1747 let ptr = b.as_ptr().cast::<u8>();
1748 let mut matmut = MatMut::new(repr, &mut b).unwrap();
1749
1750 assert_eq!(
1751 ptr,
1752 matmut.as_raw_ptr(),
1753 "underlying memory should be preserved",
1754 );
1755
1756 fill_rows_mut(matmut.rows_mut(), repr);
1757
1758 check_mat_mut(matmut.reborrow_mut(), repr, ctx);
1759 check_mat_ref(matmut.reborrow(), repr, ctx);
1760 check_rows(matmut.rows(), repr, ctx);
1761 check_rows(matmut.reborrow().rows(), repr, ctx);
1762
1763 let matref = MatRef::new(repr, &b).unwrap();
1764 check_mat_ref(matref, repr, ctx);
1765 check_mat_ref(matref.reborrow(), repr, ctx);
1766 check_rows(matref.rows(), repr, ctx);
1767 }
1768 }
1769 }
1770 }
1771
1772 #[test]
1777 fn test_standard_new_owned() {
1778 let rows = [0, 1, 2, 3, 5, 10];
1779 let cols = [0, 1, 2, 3, 5, 10];
1780
1781 for nrows in rows {
1782 for ncols in cols {
1783 let m = Mat::new(Standard::new(nrows, ncols).unwrap(), 1usize).unwrap();
1784 let rows_iter = m.rows();
1785 let len = <_ as ExactSizeIterator>::len(&rows_iter);
1786 assert_eq!(len, nrows);
1787 for r in rows_iter {
1788 assert_eq!(r.len(), ncols);
1789 assert!(r.iter().all(|i| *i == 1usize));
1790 }
1791 }
1792 }
1793 }
1794
1795 #[test]
1796 fn test_mat_from_fn() {
1797 let rows = [0, 1, 2, 5];
1798 let cols = [0, 1, 3, 7];
1799
1800 for nrows in rows {
1801 for ncols in cols {
1802 let mut counter = 0u32;
1803 let m = Mat::from_fn(Standard::new(nrows, ncols).unwrap(), || {
1804 let v = counter;
1805 counter += 1;
1806 v
1807 });
1808
1809 assert_eq!(counter as usize, nrows * ncols);
1810 for (i, row) in m.rows().enumerate() {
1811 assert_eq!(row.len(), ncols);
1812 for (j, &v) in row.iter().enumerate() {
1813 assert_eq!(v, (i * ncols + j) as u32);
1814 }
1815 }
1816 }
1817 }
1818 }
1819
1820 #[test]
1821 fn matref_new_slice_length_error() {
1822 let repr = Standard::<u32>::new(3, 4).unwrap();
1823
1824 let data = vec![0u32; 12];
1826 assert!(MatRef::new(repr, &data).is_ok());
1827
1828 let short = vec![0u32; 11];
1830 assert!(matches!(
1831 MatRef::new(repr, &short),
1832 Err(SliceError::LengthMismatch {
1833 expected: 12,
1834 found: 11
1835 })
1836 ));
1837
1838 let long = vec![0u32; 13];
1840 assert!(matches!(
1841 MatRef::new(repr, &long),
1842 Err(SliceError::LengthMismatch {
1843 expected: 12,
1844 found: 13
1845 })
1846 ));
1847 }
1848
1849 #[test]
1850 fn matmut_new_slice_length_error() {
1851 let repr = Standard::<u32>::new(3, 4).unwrap();
1852
1853 let mut data = vec![0u32; 12];
1855 assert!(MatMut::new(repr, &mut data).is_ok());
1856
1857 let mut short = vec![0u32; 11];
1859 assert!(matches!(
1860 MatMut::new(repr, &mut short),
1861 Err(SliceError::LengthMismatch {
1862 expected: 12,
1863 found: 11
1864 })
1865 ));
1866
1867 let mut long = vec![0u32; 13];
1869 assert!(matches!(
1870 MatMut::new(repr, &mut long),
1871 Err(SliceError::LengthMismatch {
1872 expected: 12,
1873 found: 13
1874 })
1875 ));
1876 }
1877
1878 #[test]
1879 fn as_matrix_view_roundtrip() {
1880 let data = [1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0];
1881
1882 let matref = MatRef::new(Standard::new(2, 3).unwrap(), &data).unwrap();
1884 let view = matref.as_matrix_view();
1885 assert_eq!(view.nrows(), 2);
1886 assert_eq!(view.ncols(), 3);
1887 for row in 0..2 {
1888 for col in 0..3 {
1889 assert_eq!(view[(row, col)], data[row * 3 + col]);
1890 }
1891 }
1892 assert_eq!(matref.as_slice(), &data);
1893
1894 let mut mat = Mat::new(Standard::<f32>::new(2, 3).unwrap(), 0.0f32).unwrap();
1896 for i in 0..2 {
1897 let r = mat.get_row_mut(i).unwrap();
1898 for j in 0..3 {
1899 r[j] = data[i * 3 + j];
1900 }
1901 }
1902 let view = mat.as_matrix_view();
1903 assert_eq!(view.nrows(), 2);
1904 assert_eq!(view.ncols(), 3);
1905 for row in 0..2 {
1906 for col in 0..3 {
1907 assert_eq!(view[(row, col)], data[row * 3 + col]);
1908 }
1909 }
1910 assert_eq!(mat.as_slice(), &data);
1911
1912 let mut buf = [1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0];
1914 let matmut = MatMut::new(Standard::new(2, 3).unwrap(), &mut buf).unwrap();
1915 let view = matmut.as_matrix_view();
1916 assert_eq!(view.nrows(), 2);
1917 assert_eq!(view.ncols(), 3);
1918 for row in 0..2 {
1919 for col in 0..3 {
1920 assert_eq!(view[(row, col)], data[row * 3 + col]);
1921 }
1922 }
1923 assert_eq!(matmut.as_slice(), &data);
1924 }
1925
1926 #[test]
1927 fn test_standard_non_copy_element() {
1928 let repr = Standard::<String>::new(2, 3).unwrap();
1929
1930 let filled = Mat::new(repr, String::from("x")).unwrap();
1932 assert_eq!(filled.num_vectors(), 2);
1933 assert!(filled.rows().flatten().all(|s| s == "x"));
1934
1935 let defaulted = Mat::new(repr, Defaulted).unwrap();
1937 assert!(defaulted.rows().flatten().all(String::is_empty));
1938
1939 let mut counter = 0usize;
1941 let mut mat = Mat::from_fn(repr, || {
1942 let s = counter.to_string();
1943 counter += 1;
1944 s
1945 });
1946 assert_eq!(counter, 6);
1947 assert_eq!(mat.get_row(1).unwrap()[0], "3");
1948
1949 mat.get_row_mut(0).unwrap()[0] = String::from("mutated");
1951 assert_eq!(mat.get_row(0).unwrap()[0], "mutated");
1952
1953 let cloned = mat.clone();
1955 assert_ne!(mat.as_raw_ptr(), cloned.as_raw_ptr());
1956 assert_eq!(cloned.get_row(0).unwrap()[0], "mutated");
1957
1958 let data = [String::from("a"), String::from("b")];
1960 let view = MatRef::new(Standard::new(2, 1).unwrap(), &data).unwrap();
1961 assert_eq!(view.get_row(1).unwrap()[0], "b");
1962
1963 let mut data_mut = [String::from("a"), String::from("b")];
1965 let mut view_mut = MatMut::new(Standard::new(1, 2).unwrap(), &mut data_mut).unwrap();
1966 view_mut.get_row_mut(0).unwrap()[1] = String::from("z");
1967 assert_eq!(data_mut[1], "z");
1968 }
1969}