Repository: sarah-quinones/faer-rs (language: rust)

Issue:
clone_from for Mat
I noticed while messing around with object pools that the current implementation of Clone for Mat leaves the clone_from method to the default implementation. A custom implementation of this function that avoids an extra memory allocation in some generic cases (such as a smart pointer with a handle to an object pool implementing clone by drawing an object from the pool and then using clone_from) should be relatively simple.


Discussion / hints:

Fix patch:
diff --git a/src/col/colown.rs b/src/col/colown.rs
index 88d2f15e..50565610 100644
--- a/src/col/colown.rs
+++ b/src/col/colown.rs
@@ -611,13 +611,12 @@ impl<E: Entity> Col<E> {
             this: &mut Col<E>,
             other: ColRef<'_, ViewE>,
         ) {
-            let mut mat = Col::<E>::new();
-            mat.resize_with(
+            this.resize_with(0, |_| E::zeroed());
+            this.resize_with(
                 other.nrows(),
                 #[inline(always)]
                 |row| unsafe { other.read_unchecked(row).canonicalize() },
             );
-            *this = mat;
         }
         implementation(self, other.as_col_ref());
     }
@@ -1070,6 +1069,13 @@ impl<E: Entity> Clone for Col<E> {
                 E::faer_from_units(E::faer_deref(this.get_unchecked(i)))
             })
         }
+    }fn clone_from(&mut self,other:&Self){
+        self.resize_with(0, |_| E::zeroed());
+        self.resize_with(
+            other.nrows(),
+            #[inline(always)]
+            |row| unsafe { other.read_unchecked(row) },
+        );
     }
 }
 
diff --git a/src/mat/matown.rs b/src/mat/matown.rs
index 3b3a4433..3f7fc3be 100644
--- a/src/mat/matown.rs
+++ b/src/mat/matown.rs
@@ -1044,14 +1044,14 @@ impl<E: Entity> Mat<E> {
             this: &mut Mat<E>,
             other: MatRef<'_, ViewE>,
         ) {
-            let mut mat = Mat::<E>::new();
-            mat.resize_with(
-                other.nrows(),
-                other.ncols(),
+            let (rows, cols)=other.shape();
+            this.resize_with(0, 0, |_, _| E::zeroed());
+            this.resize_with(
+                rows,
+                cols,
                 #[inline(always)]
                 |row, col| unsafe { other.read_unchecked(row, col).canonicalize() },
             );
-            *this = mat;
         }
         implementation(self, other.as_mat_ref());
     }
@@ -2070,6 +2070,17 @@ impl<E: Entity> Clone for Mat<E> {
             })
         }
     }
+    
+    fn clone_from(&mut self, other: &Self) {
+        let (rows, cols)=other.shape();
+        self.resize_with(0, 0, |_, _| E::zeroed());
+        self.resize_with(
+            rows,
+            cols,
+            #[inline(always)]
+            |row, col| unsafe { other.read_unchecked(row, col) },
+        );
+    }
 }
 
 impl<E: Entity> AsMatRef<E> for Mat<E> {
diff --git a/src/row/rowown.rs b/src/row/rowown.rs
index 37f4f671..5b5f9d57 100644
--- a/src/row/rowown.rs
+++ b/src/row/rowown.rs
@@ -682,13 +682,12 @@ impl<E: Entity> Row<E> {
             this: &mut Row<E>,
             other: RowRef<'_, ViewE>,
         ) {
-            let mut mat = Row::<E>::new();
-            mat.resize_with(
+            this.resize_with(0, |_| E::zeroed());
+            this.resize_with(
                 other.nrows(),
                 #[inline(always)]
                 |row| unsafe { other.read_unchecked(row).canonicalize() },
             );
-            *this = mat;
         }
         implementation(self, other.as_row_ref());
     }
@@ -1031,6 +1030,15 @@ impl<E: Entity> Clone for Row<E> {
             })
         }
     }
+    
+    fn clone_from(&mut self, other: &Self){
+        self.resize_with(0, |_| E::zeroed());
+        self.resize_with(
+            other.nrows(),
+            #[inline(always)]
+            |row| unsafe { other.read_unchecked(row) },
+        );
+    }
 }
 
 impl<E: Entity> As2D<E> for Row<E> {


Test patch: