#[cfg(all(feature = "alloc", not(feature = "std")))] use alloc::vec::Vec; use crate::base::allocator::Allocator; use crate::base::constraint::{SameNumberOfRows, ShapeConstraint}; use crate::base::default_allocator::DefaultAllocator; use crate::base::dimension::{Dim, DimName, Dynamic, U1}; use crate::base::storage::{IsContiguous, Owned, RawStorage, RawStorageMut, ReshapableStorage}; use crate::base::{Scalar, Vector}; #[cfg(feature = "serde-serialize-no-std")] use serde::{ de::{Deserialize, Deserializer, Error}, ser::{Serialize, Serializer}, }; use crate::Storage; use std::mem::MaybeUninit; /* * * RawStorage. * */ /// A Vec-based matrix data storage. It may be dynamically-sized. #[repr(C)] #[derive(Eq, Debug, Clone, PartialEq)] pub struct VecStorage { data: Vec, nrows: R, ncols: C, } #[cfg(feature = "serde-serialize")] impl Serialize for VecStorage where T: Serialize, R: Serialize, C: Serialize, { fn serialize(&self, serializer: Ser) -> Result where Ser: Serializer, { (&self.data, &self.nrows, &self.ncols).serialize(serializer) } } #[cfg(feature = "serde-serialize")] impl<'a, T, R: Dim, C: Dim> Deserialize<'a> for VecStorage where T: Deserialize<'a>, R: Deserialize<'a>, C: Deserialize<'a>, { fn deserialize(deserializer: Des) -> Result where Des: Deserializer<'a>, { let (data, nrows, ncols): (Vec, R, C) = Deserialize::deserialize(deserializer)?; // SAFETY: make sure the data we deserialize have the // correct number of elements. if nrows.value() * ncols.value() != data.len() { return Err(Des::Error::custom(format!( "Expected {} components, found {}", nrows.value() * ncols.value(), data.len() ))); } Ok(Self { data, nrows, ncols }) } } #[deprecated(note = "renamed to `VecStorage`")] /// Renamed to [`VecStorage`]. pub type MatrixVec = VecStorage; impl VecStorage { /// Creates a new dynamic matrix data storage from the given vector and shape. #[inline] pub fn new(nrows: R, ncols: C, data: Vec) -> Self { assert!( nrows.value() * ncols.value() == data.len(), "Data storage buffer dimension mismatch." ); Self { data, nrows, ncols } } /// The underlying data storage. #[inline] #[must_use] pub fn as_vec(&self) -> &Vec { &self.data } /// The underlying mutable data storage. /// /// # Safety /// This is unsafe because this may cause UB if the size of the vector is changed /// by the user. #[inline] pub unsafe fn as_vec_mut(&mut self) -> &mut Vec { &mut self.data } /// Resizes the underlying mutable data storage and unwraps it. /// /// # Safety /// - If `sz` is larger than the current size, additional elements are uninitialized. /// - If `sz` is smaller than the current size, additional elements are truncated but **not** dropped. /// It is the responsibility of the caller of this method to drop these elements. #[inline] pub unsafe fn resize(mut self, sz: usize) -> Vec> { let len = self.len(); let new_data = if sz < len { // Use `set_len` instead of `truncate` because we don’t want to // drop the removed elements (it’s the caller’s responsibility). self.data.set_len(sz); self.data.shrink_to_fit(); // Safety: // - MaybeUninit has the same alignment and layout as T. // - The length and capacity come from a valid vector. Vec::from_raw_parts( self.data.as_mut_ptr() as *mut MaybeUninit, self.data.len(), self.data.capacity(), ) } else { self.data.reserve_exact(sz - len); // Safety: // - MaybeUninit has the same alignment and layout as T. // - The length and capacity come from a valid vector. let mut new_data = Vec::from_raw_parts( self.data.as_mut_ptr() as *mut MaybeUninit, self.data.len(), self.data.capacity(), ); // Safety: we can set the length here because MaybeUninit is always assumed // to be initialized. new_data.set_len(sz); new_data }; // Avoid double-free by forgetting `self` because its data buffer has // been transfered to `new_data`. std::mem::forget(self); new_data } /// The number of elements on the underlying vector. #[inline] #[must_use] pub fn len(&self) -> usize { self.data.len() } /// Returns true if the underlying vector contains no elements. #[inline] #[must_use] pub fn is_empty(&self) -> bool { self.len() == 0 } /// A slice containing all the components stored in this storage in column-major order. #[inline] pub fn as_slice(&self) -> &[T] { &self.data[..] } /// A mutable slice containing all the components stored in this storage in column-major order. #[inline] pub fn as_mut_slice(&mut self) -> &mut [T] { &mut self.data[..] } } impl From> for Vec { fn from(vec: VecStorage) -> Self { vec.data } } /* * * Dynamic − Static * Dynamic − Dynamic * */ unsafe impl RawStorage for VecStorage { type RStride = U1; type CStride = Dynamic; #[inline] fn ptr(&self) -> *const T { self.data.as_ptr() } #[inline] fn shape(&self) -> (Dynamic, C) { (self.nrows, self.ncols) } #[inline] fn strides(&self) -> (Self::RStride, Self::CStride) { (Self::RStride::name(), self.nrows) } #[inline] fn is_contiguous(&self) -> bool { true } #[inline] unsafe fn as_slice_unchecked(&self) -> &[T] { &self.data } } unsafe impl Storage for VecStorage where DefaultAllocator: Allocator, { #[inline] fn into_owned(self) -> Owned where DefaultAllocator: Allocator, { self } #[inline] fn clone_owned(&self) -> Owned where DefaultAllocator: Allocator, { self.clone() } } unsafe impl RawStorage for VecStorage { type RStride = U1; type CStride = R; #[inline] fn ptr(&self) -> *const T { self.data.as_ptr() } #[inline] fn shape(&self) -> (R, Dynamic) { (self.nrows, self.ncols) } #[inline] fn strides(&self) -> (Self::RStride, Self::CStride) { (Self::RStride::name(), self.nrows) } #[inline] fn is_contiguous(&self) -> bool { true } #[inline] unsafe fn as_slice_unchecked(&self) -> &[T] { &self.data } } unsafe impl Storage for VecStorage where DefaultAllocator: Allocator, { #[inline] fn into_owned(self) -> Owned where DefaultAllocator: Allocator, { self } #[inline] fn clone_owned(&self) -> Owned where DefaultAllocator: Allocator, { self.clone() } } /* * * RawStorageMut, ContiguousStorage. * */ unsafe impl RawStorageMut for VecStorage { #[inline] fn ptr_mut(&mut self) -> *mut T { self.data.as_mut_ptr() } #[inline] unsafe fn as_mut_slice_unchecked(&mut self) -> &mut [T] { &mut self.data[..] } } unsafe impl IsContiguous for VecStorage {} impl ReshapableStorage for VecStorage where T: Scalar, C1: Dim, C2: Dim, { type Output = VecStorage; fn reshape_generic(self, nrows: Dynamic, ncols: C2) -> Self::Output { assert_eq!(nrows.value() * ncols.value(), self.data.len()); VecStorage { data: self.data, nrows, ncols, } } } impl ReshapableStorage for VecStorage where T: Scalar, C1: Dim, R2: DimName, { type Output = VecStorage; fn reshape_generic(self, nrows: R2, ncols: Dynamic) -> Self::Output { assert_eq!(nrows.value() * ncols.value(), self.data.len()); VecStorage { data: self.data, nrows, ncols, } } } unsafe impl RawStorageMut for VecStorage { #[inline] fn ptr_mut(&mut self) -> *mut T { self.data.as_mut_ptr() } #[inline] unsafe fn as_mut_slice_unchecked(&mut self) -> &mut [T] { &mut self.data[..] } } impl ReshapableStorage for VecStorage where T: Scalar, R1: DimName, C2: Dim, { type Output = VecStorage; fn reshape_generic(self, nrows: Dynamic, ncols: C2) -> Self::Output { assert_eq!(nrows.value() * ncols.value(), self.data.len()); VecStorage { data: self.data, nrows, ncols, } } } impl ReshapableStorage for VecStorage where T: Scalar, R1: DimName, R2: DimName, { type Output = VecStorage; fn reshape_generic(self, nrows: R2, ncols: Dynamic) -> Self::Output { assert_eq!(nrows.value() * ncols.value(), self.data.len()); VecStorage { data: self.data, nrows, ncols, } } } impl Extend for VecStorage { /// Extends the number of columns of the `VecStorage` with elements /// from the given iterator. /// /// # Panics /// This function panics if the number of elements yielded by the /// given iterator is not a multiple of the number of rows of the /// `VecStorage`. fn extend>(&mut self, iter: I) { self.data.extend(iter); self.ncols = Dynamic::new(self.data.len() / self.nrows.value()); assert!(self.data.len() % self.nrows.value() == 0, "The number of elements produced by the given iterator was not a multiple of the number of rows."); } } impl<'a, T: 'a + Copy, R: Dim> Extend<&'a T> for VecStorage { /// Extends the number of columns of the `VecStorage` with elements /// from the given iterator. /// /// # Panics /// This function panics if the number of elements yielded by the /// given iterator is not a multiple of the number of rows of the /// `VecStorage`. fn extend>(&mut self, iter: I) { self.extend(iter.into_iter().copied()) } } impl Extend> for VecStorage where T: Scalar, R: Dim, RV: Dim, SV: RawStorage, ShapeConstraint: SameNumberOfRows, { /// Extends the number of columns of the `VecStorage` with vectors /// from the given iterator. /// /// # Panics /// This function panics if the number of rows of each `Vector` /// yielded by the iterator is not equal to the number of rows /// of this `VecStorage`. fn extend>>(&mut self, iter: I) { let nrows = self.nrows.value(); let iter = iter.into_iter(); let (lower, _upper) = iter.size_hint(); self.data.reserve(nrows * lower); for vector in iter { assert_eq!(nrows, vector.shape().0); self.data.extend(vector.iter().cloned()); } self.ncols = Dynamic::new(self.data.len() / nrows); } } impl Extend for VecStorage { /// Extends the number of rows of the `VecStorage` with elements /// from the given iterator. fn extend>(&mut self, iter: I) { self.data.extend(iter); self.nrows = Dynamic::new(self.data.len()); } }