use std::any::Any;
use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
use crate::base::dimension::{Dim, U1};
use crate::base::storage::ContiguousStorageMut;
use crate::base::{DefaultAllocator, Scalar};
pub trait Allocator<N: Scalar, R: Dim, C: Dim = U1>: Any + Sized {
type Buffer: ContiguousStorageMut<N, R, C> + Clone;
unsafe fn allocate_uninitialized(nrows: R, ncols: C) -> Self::Buffer;
fn allocate_from_iterator<I: IntoIterator<Item = N>>(
nrows: R,
ncols: C,
iter: I,
) -> Self::Buffer;
}
pub trait Reallocator<N: Scalar, RFrom: Dim, CFrom: Dim, RTo: Dim, CTo: Dim>:
Allocator<N, RFrom, CFrom> + Allocator<N, RTo, CTo>
{
unsafe fn reallocate_copy(
nrows: RTo,
ncols: CTo,
buf: <Self as Allocator<N, RFrom, CFrom>>::Buffer,
) -> <Self as Allocator<N, RTo, CTo>>::Buffer;
}
pub type SameShapeR<R1, R2> = <ShapeConstraint as SameNumberOfRows<R1, R2>>::Representative;
pub type SameShapeC<C1, C2> = <ShapeConstraint as SameNumberOfColumns<C1, C2>>::Representative;
pub trait SameShapeAllocator<N, R1, C1, R2, C2>:
Allocator<N, R1, C1> + Allocator<N, SameShapeR<R1, R2>, SameShapeC<C1, C2>>
where
R1: Dim,
R2: Dim,
C1: Dim,
C2: Dim,
N: Scalar,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
{
}
impl<N, R1, R2, C1, C2> SameShapeAllocator<N, R1, C1, R2, C2> for DefaultAllocator
where
R1: Dim,
R2: Dim,
C1: Dim,
C2: Dim,
N: Scalar,
DefaultAllocator: Allocator<N, R1, C1> + Allocator<N, SameShapeR<R1, R2>, SameShapeC<C1, C2>>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
{
}
pub trait SameShapeVectorAllocator<N, R1, R2>:
Allocator<N, R1> + Allocator<N, SameShapeR<R1, R2>> + SameShapeAllocator<N, R1, U1, R2, U1>
where
R1: Dim,
R2: Dim,
N: Scalar,
ShapeConstraint: SameNumberOfRows<R1, R2>,
{
}
impl<N, R1, R2> SameShapeVectorAllocator<N, R1, R2> for DefaultAllocator
where
R1: Dim,
R2: Dim,
N: Scalar,
DefaultAllocator: Allocator<N, R1, U1> + Allocator<N, SameShapeR<R1, R2>>,
ShapeConstraint: SameNumberOfRows<R1, R2>,
{
}