From b32502ea01d5a13de699d63c7ee16c68ca6a1b94 Mon Sep 17 00:00:00 2001
From: Martin Larralde <martin.larralde@embl.de>
Date: Mon, 15 May 2023 14:36:14 +0200
Subject: [PATCH] Add an unsafe constructor to create an uninitialized
 `DenseMatrix`

---
 lightmotif/src/dense.rs | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/lightmotif/src/dense.rs b/lightmotif/src/dense.rs
index 7486f64..82ca168 100644
--- a/lightmotif/src/dense.rs
+++ b/lightmotif/src/dense.rs
@@ -30,6 +30,34 @@ impl<T: Default + Copy, C: Unsigned> DenseMatrix<T, C> {
         matrix
     }
 
+    /// Create a new *uninitialized* matrix with the given number of rows.
+    pub unsafe fn uninitialized(rows: usize) -> Self {
+        // alway over-allocate columns to avoid alignment issues.
+        let c = C::USIZE.next_power_of_two();
+
+        // NOTE: this is unsafe but given that we require `T` to be
+        //       copy, this should be fine, as `Copy` prevents the
+        //       type to be `Dorp` as well.
+        // reserve the vector without initializing the data
+        let mut data = Vec::with_capacity((rows + 1) * c);
+        data.set_len((rows + 1) * c);
+
+        // compute offset to aligned memory
+        let mut offset = 0;
+        while data[offset..].as_ptr() as usize % c > 0 {
+            offset += 1
+        }
+
+        // record indices to each rows
+        let indices = (0..rows).into_iter().map(|i| offset + i * c).collect();
+
+        Self {
+            data,
+            indices,
+            _columns: std::marker::PhantomData,
+        }
+    }
+
     /// The number of columns of the matrix.
     #[inline]
     pub const fn columns(&self) -> usize {
-- 
GitLab