//! Abstract definition of a matrix data storage allocator. use std::mem::MaybeUninit; use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; use crate::base::dimension::{Dim, U1}; use crate::base::storage::ContiguousStorageMut; use crate::base::DefaultAllocator; /// A matrix allocator of a memory buffer that may contain `R::to_usize() * C::to_usize()` /// elements of type `T`. /// /// An allocator is said to be: /// − static: if `R` and `C` both implement `DimName`. /// − dynamic: if either one (or both) of `R` or `C` is equal to `Dynamic`. /// /// Every allocator must be both static and dynamic. Though not all implementations may share the /// same `Buffer` type. /// /// If you also want to be able to create uninitizalized memory buffers, see [`Allocator`]. pub trait InnerAllocator: 'static + Sized { /// The type of buffer this allocator can instanciate. type Buffer: ContiguousStorageMut; /// Allocates a buffer initialized with the content of the given iterator. fn allocate_from_iterator>( nrows: R, ncols: C, iter: I, ) -> Self::Buffer; } /// Same as the [`InnerAllocator`] trait, but also provides methods to build uninitialized buffers. pub trait Allocator: InnerAllocator + InnerAllocator, R, C> { /// Allocates a buffer with the given number of rows and columns without initializing its content. fn allocate_uninitialized( nrows: R, ncols: C, ) -> , R, C>>::Buffer; /// Assumes a data buffer to be initialized. This operation should be near zero-cost. unsafe fn assume_init( uninit: , R, C>>::Buffer, ) -> >::Buffer; } /// A matrix reallocator. Changes the size of the memory buffer that initially contains (RFrom × /// CFrom) elements to a smaller or larger size (RTo, CTo). pub trait Reallocator: InnerAllocator + InnerAllocator { /// Reallocates a buffer of shape `(RTo, CTo)`, possibly reusing a previously allocated buffer /// `buf`. Data stored by `buf` are linearly copied to the output: /// /// # Safety /// * The copy is performed as if both were just arrays (without a matrix structure). /// * If `buf` is larger than the output size, then extra elements of `buf` are truncated. /// * If `buf` is smaller than the output size, then extra elements of the output are left /// uninitialized. unsafe fn reallocate_copy( nrows: RTo, ncols: CTo, buf: >::Buffer, ) -> >::Buffer; } /// The number of rows of the result of a componentwise operation on two matrices. pub type SameShapeR = >::Representative; /// The number of columns of the result of a componentwise operation on two matrices. pub type SameShapeC = >::Representative; // TODO: Bad name. /// Restricts the given number of rows and columns to be respectively the same. pub trait SameShapeAllocator: InnerAllocator + InnerAllocator, SameShapeC> where ShapeConstraint: SameNumberOfRows + SameNumberOfColumns, { } impl SameShapeAllocator for DefaultAllocator where DefaultAllocator: InnerAllocator + InnerAllocator, SameShapeC>, ShapeConstraint: SameNumberOfRows + SameNumberOfColumns, { } // XXX: Bad name. /// Restricts the given number of rows to be equal. pub trait SameShapeVectorAllocator: InnerAllocator + InnerAllocator> + SameShapeAllocator where ShapeConstraint: SameNumberOfRows, { } impl SameShapeVectorAllocator for DefaultAllocator where DefaultAllocator: InnerAllocator + InnerAllocator>, ShapeConstraint: SameNumberOfRows, { }